有人能用Perl解释一下(我的$self=shift)吗
我很难理解OOPerl和我的$self=shift的交集代码>关于这些单独元素的文档非常棒,但我发现它们中没有一个涉及到它们是如何协同工作的 我一直在使用Moose制作具有属性的模块,当然,在所述模块中引用模块的属性是很有用的。我一次又一次地被告知要使用有人能用Perl解释一下(我的$self=shift)吗,perl,attributes,self,shift,moose,Perl,Attributes,Self,Shift,Moose,我很难理解OOPerl和我的$self=shift的交集关于这些单独元素的文档非常棒,但我发现它们中没有一个涉及到它们是如何协同工作的 我一直在使用Moose制作具有属性的模块,当然,在所述模块中引用模块的属性是很有用的。我一次又一次地被告知要使用my$self=shift以将模块的属性分配给该变量。这是有意义的,并且是有效的,但是当我也向子例程传递参数时,这个过程显然会获取@ARGV数组的第一个元素,并将其分配给$self 有人能解释一下我如何使用shift获得对模块属性的内部访问,同时在@A
my$self=shift在子例程中编写>以将模块的属性分配给该变量。这是有意义的,并且是有效的,但是当我也向子例程传递参数时,这个过程显然会获取@ARGV
数组的第一个元素,并将其分配给$self
有人能解释一下我如何使用shift获得对模块属性的内部访问,同时在@ARGV
数组中传递参数吗?首先,子例程不会在@ARGV
数组中传递。相反,传递给子例程的所有参数都被展平到子例程内部由@
表示的单个列表中。@ARGV数组位于脚本的顶层,包含传递给脚本的命令行参数
现在,在Perl中,当调用对象上的方法时,对象作为参数隐式传递给方法
如果你忽略了继承
$obj->doCoolStuff($a, $b);
相当于
doCoolStuff($obj, $a, $b);
这意味着方法docooltuff
中@
的内容将是:
@=($obj,$a,$b)代码>
现在,不带任何参数的shift
内置函数将元素从默认数组变量@
中移出。在本例中,这将是$obj
因此,当您执行$self=shift
时,实际上是在说$self=$obj
我还希望这能解释如何通过->
符号将其他参数传递给方法。继续我上面提到的例子,这将是:
sub doCoolStuff {
# Remember @_ = ($obj, $a, $b)
my $self = shift;
my ($a, $b) = @_;
此外,虽然Moose
是Perl的一个很好的对象层,但它并没有取消您需要在每个方法中自己初始化$self
的要求。永远记住这一点。虽然像C++和java这样的语言隐式地初始化对象引用<代码> < <代码>,但是在Perl中,您需要对每一个编写的方法显式地执行它。 在顶层代码中,<代码> SHIVTHER()/<代码>是<>代码> SHIFT(@ ARGV)。code>@ARGV
包含命令行参数
在sub中,shift()
是shift(@\ux)
的缩写<代码>@
包含sub的参数
所以my$self=shift
正在获取sub的第一个参数。调用方法时,invocant(->
的剩余部分)作为第一个参数传递。换句话说,
$o->method(@a)
类似于
my $sub = $o->can('method');
$sub->($o, @a);
在该示例中,my$self=shift如果您调用以下命令,代码>会将$o
分配给$self
:
$myinstance->myMethod("my_parameter");
与执行以下操作相同:
myMethod($myinstance, "my_parameter");
但如果你这样做了:
myMethod("my_parameter");
将只传递“my_参数”
然后,如果在myMethod中始终执行以下操作:
$self = shift @_;
从对象上下文调用myMethod id时,$self将成为对象引用
但当以过程方式从内部的另一个方法调用时,将是“my_参数”。
意识到这一点 shift
如果从子例程内部调用,则默认为@
;如果从顶级代码调用,则默认为@ARGV
。@cjm没错。我会在回答中提到。太棒了。那太有帮助了。我确实遇到了一个问题,$self=shift似乎将自己设置为我实际传递到子例程的第一个参数。也就是说,@u中的第一个元素不是对象,但实际上是我提供的第一个参数。发生这种情况的高层次原因是什么?(我已经解决了这个问题,没有实际的代码了)当您不确定Perl var输出中包含什么时,请使用Data::Dumper模块输出内容。@AlexHHadik我只能想象这种情况会发生的一种情况。当您没有像下面这样通过对象调用方法时:$obj->method($arg1,$arg2)
您错过了对象,直接调用了方法method($arg1,$arg2)
。这在Perl中是完全合法的,因为方法调用与普通函数调用没有什么不同。但是,由于您没有使用->
操作符通过对象调用它,$obj
参数不会传递给arg列表中的方法。