我花了两个小时来追踪这个错误.我可以解决它,但我不明白.
如果我有一个./lib/My/Foo.pm看起来像这样的perl模块:
package My::Foo;
sub import {print "importing\n"}
1;
Run Code Online (Sandbox Code Playgroud)
然后使用它import隐式调用子例程:
$ PERL5LIB=./lib perl -MMy::Foo -e 'print "ok\n"'
importing
ok
Run Code Online (Sandbox Code Playgroud)
但是如果我复制相同的模块并在没有冒号的情况下使用它,import则不会调用子例程.
$ cp lib/My/Foo.pm lib/Foo.pm
$ PERL5LIB=./lib perl -MFoo -e 'print "ok\n"'
ok
Run Code Online (Sandbox Code Playgroud)
如果我更改import为其他类似的东西do_import,则不会调用子例程.所以我可以避免这种行为.但在我的实际用例中,我有一个Import类和一个抽象方法import,然后在子类中实现该方法.因此,我不希望在父类中import自动调用此方法use.
我看着perlootut和perlobj并没有看到这个任何提及.
import()是Perl中的特殊方法名称.无论何时你use是模块,Perl都会寻找import()在该模块内部调用的子程序,如果找到它,它将被运行.
这通常用于出口商聪明.这意味着import()在模块中调用的方法,您不希望在加载模块时调用该方法是一个非常糟糕的主意.它会让你在任何时候都与Perl作战.
有关更多信息,请参阅perldoc -f import:
导入列表
没有内置
import功能.它只是希望将名称导出到另一个模块的模块定义(或继承)的普通方法(子例程).该use函数调用所import用包的方法.另请参阅use,perlmod和Exporter.
你找到的"解决方法"也不是一个好主意.您正在从名为Foo.pm的文件中有效地加载一个名为My:Foo的模块,如果文件名和包名称不匹配,Perl将会非常困惑.
在我看来,你正在寻找这头骆驼的错误结局.你的问题不是由于import"特殊" 造成的,而是由于不知道究竟use是什么做的.Per perldoc使用,use Module与"完全等效"
BEGIN { require Module; Module->import( LIST ); }
Run Code Online (Sandbox Code Playgroud)
当你使用时use,你告诉Perl调用Module的import方法. 就那么简单.
当然,Perl是Perl,你的import方法可能有一些方法可以确定它是否被作为a的一部分被调用use并且如果是这样的话立即返回,但这只会增加不必要的复杂性.重命名方法更具描述性(例如import_file,import_record等等,这取决于它是什么,你实际上是导入)将是一个更好的解决方案.