2013-03-30 30 views
1

考慮以下腳本:如何將我的子程序的參數放到數組中?

use strict; 
use Data::Dumper; 

my @arr=('1A','2A'); 
my $arr_ref=['1','2']; 

sub routine1 
{ 
my @[email protected]_; 
print Dumper(\@arr); 
} 

routine1(@arr,'one_A'); 

sub routine2 
{ 
my $arr_ref=[@_]; 
print Dumper($arr_ref); 
} 

routine2($arr_ref,'one'); 

routine1使用@arr和routine2使用$arr_ref

routine1打印如下:

$VAR1 = [ 
     '1A', 
     '2A', 
     'one_A' 
     ]; 

routine2打印如下:

$VAR1 = [ 
     [ 
      '1', 
      '2' 
     ], 
     'one' 
     ]; 

我想繼續使用routine2@_arr_ref,但要拿出以下的輸出:

$VAR1 = [ 
     '1', 
     '2' 
     'one' 
     ]; 

有人可以提出出路嗎?

+0

您對我的問題太模糊。 – kjprice

回答

3

使用函數ref可以看到標量是否是引用(如果是,哪種類型)。在一個簡單的情況下,只有數組引用會被傳遞,你可以簡單地使用它來平滑輸入。

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Data::Dumper; 

sub test { 
    my @arr = map { ref() ? @$_ : $_ } @_; 
    print Dumper \@arr; 
} 

test(['a', 'b'], 1); 

作爲一個附帶的好處,這代碼將與消息死,如果另一種類型的引用傳遞,因爲試圖順從作爲數組。如果您需要處理更多,則需要檢查參考類型。這開始迅速複雜化。

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Data::Dumper; 

sub test { 
    my @arr = map { 
    my $type = ref; 
    if (! $type) { 
     $_; 
    } elsif ($type eq 'ARRAY') { 
     @$_; 
    } elsif ($type eq 'HASH') { 
     %$_; 
    } else { 
    () 
    } 
    } @_; 
    print Dumper \@arr; 
} 

test(['a', 'b'], { p => 'q' }, 1); 

通過返回其他引用類型的空列表我默默地忽略所有其他引用類型。或者,您可能寧願強制其他參考類型的字符串化。

... 
} else { 
    "$_"; 
} 
... 
test(['a','b'], sub{}, bless({},'MyClass'), 1); 

這些處理器的哪一個使用取決於你的使用情況。

+0

在子程序中,我們不能直接在array_reference(而不是@arr)中使用@_的值嗎?那可能嗎? –

+0

爲了扁平化引用,你將不得不遍歷整個結構。我想你可以嘗試將它打包回@_,但爲什麼你想要? –

+0

爲什麼不只是'map @ $ _,@ _'? – Zaid

0

該程序顯示一個子程序flatten,將扁平化簡單數據和數組引用的混合列表,嵌套到任何級別。

use strict; 
use warnings; 

use Data::Dump; 

my @arr = qw/ 1A 2A /; 
my $arr_ref = [1, 2]; 

sub flatten; 

routine1(@arr, 'one_A'); 
routine2($arr_ref, 'one'); 

sub routine1 { 
    my @[email protected]_; 
    dd \@arr; 
} 

sub routine2 { 
    my $arr_ref = [flatten @_]; 
    dd $arr_ref; 
} 

sub flatten { 
    my $i = 0; 
    while ($i < @_) { 
    my $item = $_[$i]; 
    if (ref $item eq 'ARRAY') { 
     splice @_, $i, 1, @$item; 
    } 
    else { 
     ++$i; 
    } 
    } 
    @_; 
} 

輸出

["1A", "2A", "one_A"] 
[1, 2, "one"] 
1

就寫了這個工作的一天。

sub flatten { 
    return map { ref($_) ? flatten(@{$_}) : ($_) } @_; 
} 
+0

我很努力地看到這會通過簡單的'map @ $ _,@ _' – Zaid

+0

@zaid來購買什麼,它可以使異構列表變平坦,並且使更深層嵌套的列表變平。換句話說,它適用於'(5,[6],[7,8],[[9,4],5])''。 – darch

+0

@darch:喬爾讓我意識到這一點 – Zaid

相關問題