I am noticing an execution mismatch of Perl in Eclipse EPIC plugin.
Specifications:
Perl version: (v5.12.4) built for MSWin32-x86-multi-thread
Eclipse version: Indigo Service Release 2
EPIC version: 0.6.53
Consider the files & source codes below: (all source files are in same directory)
sample.pl
use package1;
require "package1.pm";
require "package2.pm";
sampleFunction();
require "packagetest.pm";
packagetest::callSampleFunction();
package1.pm
package package1;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(
sampleFunction
);
sub sampleFunction {
print "from package1.pm \n";
}
package2.pm
package package1; # declare the same package 'package1'
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(
sampleFunction
);
sub sampleFunction {
print "from package2.pm \n";
}
packagetest.pm
package packagetest;
use package1;
sub callSampleFunction {
sampleFunction();
}
1;
When I execute the sample.pl file in Eclipse EPIC, I am getting two different console outputs.
Debug mode output:
from package2.pm
from package2.pm
Run mode output:
Subroutine sampleFunction redefined at D:/My.Soft.Dev/Perl_XS/package2.pm line 11.
from package1.pm
from package2.pm
I have the below questions:
1) Why am I getting two different outputs here? Is it not a bug?
2) Which of the outputs shown is a "valid output"?
3) Can someone explain why is the particular output valid?
I tried to derive the reasons from my Perl knowledge. But I couldn't. So, I understood, I have to get to know more about Perl:))
UPDATE: I have created a bug report: https://sourceforge.net/p/e-p-i-c/bugs/669/
Looks like (1) is a bug in Perl debugger of 5.12.4 version
Your release mode output is the valid one:
use package1
finds, loads, compiles, and executes package1.pm
. This defines package1::sampleFunction
, which is exported into the main
namespace. Exporting is effectively done by reference, and not by name, so main::sampleFunction
points to the same function which package1::sampleFunction
currently refers to.
require "package1.pm
does nothing because that package has already been executed.
require "package2.pm
finds, loads, compiles and executes package2.pm
. This redefines package1::sampleFunction
, which will warn if and only if you have warnings
activated – either lexically through use warnings
(do this) or globally with the -w
switch (don't do this).
sampleFunction()
executes main::SampleFunction
, which still points to the original subroutine.
from package1.pm
require "packagetest.pm"
finds, loads, compiles and executes packagetest.pm
. Here in turn:
use package1
will export package1::sampleFunction
(which is currently the redefined subroutine) into the packagetest
namespace.We also define the packagetest::callSampleFunction
subroutine.
We call packagetest::callSampleFunction
, which in turn
calls packagetest::sampleFunction
, which is the redefined subroutine
from package2.pm
The output could come together if we executed the script normally but kept the interpreter with its global state alive, then recompile and re-execute sample.pl
. In this case, package1.pm
and package2.pm
would not be re-executed because they are already loaded. The use package1
would then import the current package1::sampleFunction
which already is the redefined version.
To test this hypothesis, restart your IDE and execute the script two times in debug mode. It should then output
from package1.pm
from package2.pm
during the first run, and
from package2.pm
from package2.pm
for all subsequent runs.
The real problem is
that you are redefining subroutines (don't do this),
that you are using the same package name package1
in different files (don't do this),
that you are using a filename package2.pm
that does not correspond to the package name package1
inside (don't do this either), and
that you have a number of other style issues, including:
@EXPORT_OK
and let the user of your module explicitly request some symbolrequire "filename"
is usually not something you want to do.use strict; use warnings
-w
switch which is a bit oudated.