首先,子程序未通過@ARGV
陣列。而是傳遞給子例程的所有參數都被平鋪到子例程中的@_
表示的單個列表中。 @ARGV數組在您腳本的頂層可用,包含傳遞給您腳本的命令行參數。
現在,在Perl中,當您在對象上調用某個方法時,該對象將作爲參數隱式傳遞給該方法。
如果忽略繼承,
$obj->doCoolStuff($a, $b);
相當於
doCoolStuff($obj, $a, $b);
這意味着@_
的方法內容doCoolStuff
是: @_ = ($obj, $a, $b);
現在,shift
內置函數,沒有任何參數,將元素移出d默認數組變量@_
。在這種情況下,那將是$obj
。
所以,當你做$self = shift
,你有效地說$self = $obj
。
我也希望這解釋瞭如何通過->
表示法將其他參數傳遞給方法。繼續我上面所陳述的例子,這將是這樣的:
sub doCoolStuff {
# Remember @_ = ($obj, $a, $b)
my $self = shift;
my ($a, $b) = @_;
此外,雖然Moose
是Perl的一個偉大的對象層,它不會從你需要自己初始化$self
要求帶走在每種方法中。永遠記住這一點。儘管像C++和Java這樣的語言隱式地初始化了對象引用this
,但在Perl中,您需要明確地爲您編寫的每種方法執行此操作。
如果從子例程內調用'shift_',默認爲'@ _',如果從頂級代碼調用''ARGV'',則默認爲'__'。 – cjm
@cjm你是對的。將在答案中提到這一點。 – Nikhil
太棒了。這非常有幫助。我遇到了一個問題,我的$ self = shift似乎將自己設置爲實際傳遞給子例程的第一個參數。也就是說,@_中的第一個元素不是對象,但實際上是我提供的第一個參數。這會發生什麼高水平的原因? (我解決了這個問題,並且沒有實際的代碼) –