2

我注意到 Eclipse EPIC 插件中 Perl 的执行不匹配。

规格:

Perl 版本: (v5.12.4) 为 MSWin32-x86-multi-thread 构建

Eclipse 版本: Indigo Service Release 2

史诗版本: 0.6.53

考虑下面的文件和源代码:(所有源文件都在同一目录中)

样本.pl

use package1;

require "package1.pm";
require "package2.pm";

sampleFunction();

require "packagetest.pm";

packagetest::callSampleFunction();

包1.pm

package package1;

use Exporter;

our @ISA = qw(Exporter);

our @EXPORT = qw(
    sampleFunction
);

sub sampleFunction {
    print "from package1.pm \n";    
}

包2.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";    
}

包测试.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/epic/bugs/669/

看起来 (1) 是 5.12.4 版本的 Perl 调试器中的一个错误

4

1 回答 1

2

关于问题#2和#3:

您的发布模式输出是有效的:

  • 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()executes main::SampleFunction,它仍然指向原始子例程。

    来自 package1.pm

  • require "packagetest.pm"查找、加载、编译和执行packagetest.pm. 依次在这里:

    • use package1将导出package1::sampleFunction(当前是重新定义的子例程)到packagetest命名空间。

    我们还定义了packagetest::callSampleFunction子程序。

  • packagetest::callSampleFunction我们调用

    • 调用packagetest::sampleFunction,这是重新定义的子例程

      来自 package2.pm

关于#1的猜测:

如果我们正常执行脚本但保持解释器的全局状态处于活动状态,然后重新编译并重新执行,则输出可能会聚集在一起sample.pl。在这种情况下,package1.pm并且package2.pm不会被重新执行,因为它们已经被加载。然后use package1将导入package1::sampleFunction已经是重新定义版本的当前版本。

要测试此假设,请重新启动 IDE 并在调试模式下执行脚本两次。然后它应该输出

from package1.pm
from package2.pm

在第一次运行期间,并且

from package2.pm
from package2.pm

对于所有后续运行。


真正的问题是

  1. 你正在重新定义子程序(不要这样做),

  2. package1在不同的文件中使用相同的包名称(不要这样做),

  3. 您使用的文件名与内部package2.pm的包名不对应package1(也不要这样做),并且

  4. 您还有许多其他风格问题,包括:

    • 小写包名保留给“实用模块”</li>
    • 默认情况下不要导出,而是使用@EXPORT_OK并让模块的用户明确请求一些符号
    • require "filename"通常不是你想做的事情。
    • 你没有use strict; use warnings
    • 您在生产中使用警告,而不是在开发中?为什么?:(
    • 您正在使用-w有点过时的开关。
于 2014-03-03T17:07:55.803 回答