我非常难以理解Perl和我的$ self = shift的交点;关于这些单独元素的文档是非常好的,但是我没有发现任何一个这些文档能够在一起工作。
我一直在使用Moose来制作具有属性的模块,当然也可以在模块中引用模块的属性。我一直被告知使用我的$ self = shift;在子程序中将模块的属性分配给该变量。这是有意义和有效的,但是当我也将参数传递给子例程时,这个过程显然需要@ARGV数组的第一个元素,并将其分配给$ self。
解决方法
首先,一个子程序不会传递给@ARGV数组。而传递给子例程的所有参数都被平铺为子程序中由@_表示的单个列表。 @ARGV数组在脚本的顶层可用,其中包含传递给您脚本的命令行参数。
现在,在Perl中,当您调用对象上的方法时,该对象将作为参数隐式传递给该方法。
所以这:
$obj->doCoolStuff($a,$b);
相当于:
doCoolStuff($obj,$a,$b);
这意味着方法doCoolStuff中的@_的内容将是:
@_ =($ obj,$ a,$ b);
现在,没有任何参数的shift内置函数将元素从默认数组变量@_中移出。在这种情况下,这将是$ obj。
所以当你做$ self = shift时,你实际上是说$ self = $ obj。
我也希望这解释了如何通过以下方式将其他参数传递给方法:符号。继续上面我已经说过的例子,就像:
sub doCoolStuff { # Remember @_ = ($obj,$b) my $self = shift; my ($a,$b) = @_;
另外,虽然Moose是Perl的一个很好的对象层,但是它并没有从每一种方法中需要自己初始化$ self的要求。永远记住这一点。虽然C和Java这样的语言隐式地初始化对象引用,但在Perl中,您需要为每个写入的方法明确地执行此操作。