我注意到Eclipse EPIC插件中Perl的执行不匹配。
的规格: 的
为MSWin32-x86-multi-thread构建的Perl版本(v5.12.4)
Eclipse版本: Indigo Service Release 2
EPIC版本: 0.6.53
考虑文件&源代码如下:(所有源文件都在同一目录中)
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;
当我在Eclipse EPIC中执行sample.pl文件时,我得到两个不同的控制台输出。
调试模式输出:
from package2.pm
from package2.pm
运行模式输出:
Subroutine sampleFunction redefined at D:/My.Soft.Dev/Perl_XS/package2.pm line 11.
from package1.pm
from package2.pm
我有以下问题:
1)为什么我在这里得到两个不同的输出?这不是一个错误吗?
2)显示哪个输出是“有效输出”?
3)有人可以解释为什么特定输出有效吗?
我试图从我的Perl知识中推导出原因。但我不能。所以,我明白了,我必须更多地了解Perl:))
更新:我创建了一个错误报告:https://sourceforge.net/p/e-p-i-c/bugs/669/
看起来(1)是5.12.4版本的Perl调试器中的错误
答案 0 :(得分:2)
您的发布模式输出是有效的:
use package1
查找,加载,编译和执行package1.pm
。这定义了package1::sampleFunction
,它被导出到main
命名空间。导出通过引用而非名称有效地完成,因此main::sampleFunction
指向package1::sampleFunction
当前引用的相同功能。
require "package1.pm
不执行任何操作,因为该包已经执行。
require "package2.pm
查找,加载,编译和执行package2.pm
。这会重新定义package1::sampleFunction
,当且仅当您warnings
被激活时才会发出警告 - 通过use warnings
(执行此操作)或通过-w
开关全局激活(不要这样做。)
sampleFunction()
执行main::SampleFunction
,仍然指向原始子例程。
来自package1.pm 的
require "packagetest.pm"
查找,加载,编译和执行packagetest.pm
。在此反过来:
use package1
会将package1::sampleFunction
(当前是重新定义的子例程)导出到packagetest
命名空间。我们还定义了packagetest::callSampleFunction
子例程。
我们打电话给packagetest::callSampleFunction
,而
调用packagetest::sampleFunction
,这是重新定义的子例程
来自package2.pm
如果我们正常执行脚本但是将解释器的全局状态保持为活动状态,然后重新编译并重新执行sample.pl
,则输出可以组合在一起。在这种情况下,package1.pm
和package2.pm
将不会被重新执行,因为它们已经被加载。然后,use package1
将导入当前已重新定义的package1::sampleFunction
。
要测试此假设,请重新启动IDE并在调试模式下执行脚本两次。然后应该输出
from package1.pm
from package2.pm
在第一次运行期间,
from package2.pm
from package2.pm
用于所有后续运行。
真正的问题是
您正在重新定义子程序(不要这样做),
您在不同的文件中使用相同的包名package1
(不要这样做),
您使用的文件名package2.pm
与包名package1
不对应(请勿执行此操作),
您还有其他一些风格问题,包括:
@EXPORT_OK
并让模块的用户明确请求一些符号require "filename"
通常不是您想要做的事情。use strict; use warnings
-w
开关,有点oud。