从模块调用子程序时,我一直很::困惑->.我知道这::与路径以及模块/子程序->用于对象的位置有关,但我真的不明白为什么我看似可以互换它并且它没有立即出现错误.我有perl模块,它们是更大包装的一部分,例如FullProgram::Part1
我只是想要掌握模块,但是当谈到Perl对象时仍然处于不稳定状态,但我不小心这样做了:
FullProgram::Part1::subroutine1();
Run Code Online (Sandbox Code Playgroud)
代替
FullProgram::Part1->subroutine1();
Run Code Online (Sandbox Code Playgroud)
因此,当我将散列引用传递给子程序1并小心使用$class/$self处理对象引用并意外使用时,::我最后拉出我的头发,想知道为什么我的哈希引用似乎消失了.我已经吸取了教训,但我真的想解释一下这种差异.我已经阅读了perldocs和各种网站,但我没有看到两者之间的任何比较(很难谷歌...)所有帮助赞赏 - 总是很好理解我在做什么!
香草子和一种方法之间没有固有的区别.这就是你如何称呼它.
Class::foo('a');
Run Code Online (Sandbox Code Playgroud)
这会打电话Class::foo.如果Class::foo不存在,则不会检查继承树.Class::foo将仅传递提供的参数('a').
它大致相同: my $sub = \&Class::foo; $sub->('a');
Class->foo('a');
Run Code Online (Sandbox Code Playgroud)
如果不存在Class::foo,这将调用或foo在其中一个基类中调用Class::foo.调用者(左侧的内容->)将作为参数传递.
它大致相同: my $sub = Class->can('foo'); $sub->('Class', 'a');
FullProgram::Part1::subroutine1();
Run Code Online (Sandbox Code Playgroud)
使用空参数列表调用subroutine1包的子例程FullProgram::Part1
FullProgram::Part1->subroutine1();
Run Code Online (Sandbox Code Playgroud)
使用包名称作为第一个参数调用相同的子例程(请注意,当您进行子类化时,它会变得更复杂一些).这种语法由构造函数方法使用,这些方法需要类名来构建子类的对象,如
sub new {
my ($class, @args) = @_;
...
return bless $thing, $class;
}
Run Code Online (Sandbox Code Playgroud)
仅供参考:在Perl OO中,您可以看到$object->method(@args)哪些调用Class::method带有对象(一个有福的引用)作为第一个参数而不是包/类名.在这样的方法中,子例程可以这样工作:
sub method {
my ($self, $foo, $bar) = @_;
$self->do_something_with($bar);
# ...
}
Run Code Online (Sandbox Code Playgroud)
这将调用子程序do_something_with与对象作为第一个参数再其次是价值$bar这是你最初传递到第二列表元素method在@args.这样对象本身就不会丢失.
有关在调用方法时继承树如何变得重要的更多信息,请参阅ikegami的答案!
同时使用!
use Module::Two;
Module::Two::->class_method();
Run Code Online (Sandbox Code Playgroud)
请注意,这有效但也可以保护您免受歧义的影响; 简单
Module::Two->class_method();
Run Code Online (Sandbox Code Playgroud)
将被解释为:
Module::Two()->class_method();
Run Code Online (Sandbox Code Playgroud)
(在Module中调用子例程2并尝试在其返回值上调用class_method - 可能导致运行时错误或在某个完全不同的类中调用类或实例方法)如果在模块中碰巧有一个子二 - 这是你的不应该依赖于这种或那种方式,因为它不是您的代码业务中的任何模块.