如果是只有一個參數要傳,且是hash,最直接想到的辦法就是像傳其他類型參數一樣直接傳如 %relhash = count_word(%relhash); 但 :
1. too expensive. 整個 hash 是被拷貝到函數中, 因此就算你在函數中對該 hash 進行操作, 原本的 hash 並不受影響, 因此需要將修改後的 hash 回傳.
2. 如果有超過一個參數要傳,而把hash放到最前面,結果在子函數中會合併到第一個hash上面去,如 :
- %relhash = (
- 1=>"one",
- 2=>"two",
- 3=>"three"
- );
- $test = "test";
- sub printHash()
- {
- my($var1, %hash2) = @_;
- print "\t[Test] var1=$var1\n";
- for my $key (keys %hash2)
- {
- my $value = $hash2{$key};
- print "\t[Test] Hash($key) -> $value\n";
- }
- return %hash2;
- }
- &printHash($test, %relhash);
以上雖然可以運行,但是複制了整個hash,代價比較大. 而且下面用法傳遞參數會出錯,sub中$var1為空 :
- ...
- sub printHash()
- {
- my(%hash2, $var1) = @_;
- ...
- }
- &printHash(%relhash, $test);
3. 如果同時傳了兩個 hash 或 array,在子函數中也會合併到第一個中去,而第二個就會傳不進來!
使用方法二 :
一種解決方法是透過傳遞 hash 的 Reference (要傳兩個或以上hash也可以這樣做):
- %relhash = (
- 1=>"one",
- 2=>"two",
- 3=>"three"
- );
- $test = "test";
- sub printHash()
- {
- my($var1, $hash2) = @_;
- print "\t[printHash] var1=$$var1\n";
- for $key (keys %$hash2)
- {
- $value = $hash2->{$key};
- print "\t[printHash] hash2($key) -> $value\n";
- }
- $hash2->{4} = "four";
- }
- &printHash($test, \%relhash); # 傳遞 hash 的 reference
- while( my($k, $v) = each %relhash)
- {
- print "\t[Main] relhash($k) -> $v\n";
- }
可以發現在函式中修改 hash, 原本函式外的 hash (傳入的 hash) 也會改變 ! 同理如果要傳多個array :
- ...
- processarrays(\@array1, \@array2);
- $sub processarrays{
- my($a1, $a2) = @_;
- foreach(@$a1){ # dereferences $a1
- print $_;
- }
- for($i=0; $i<@$a2; $i++){
- print $a2->[$i]; #get at a particular index within array
- }
- }
如果不是有特別需要的話,呼呼,還是直接定義為全局變量,而不傳遞是最方便的啦!
參考連結 :
* 如何在perl子函數中傳遞hash
* Perl 函數傳引用 (Scalar, Array and Hash)