2014-08-29 3 views
0

Почему не меняется содержимое моего хэша hh? Как сохранить изменения в основной части после вызова func?Содержимое хэша не изменяется

my @RR = (1,2); 
foreach(@RR) 
{ 
    my %hh; 
    &func(\%hh); 
    print "SIZE: ".keys(%hh)."\n"; 
} 

sub func 
{ 
    my %hh = %{$_[0]}; 
    my $n="noob"; 
    my $m="moon"; 
    $hh{$n}{$m}[0]="hey"; 
    $hh{$n}{$m}[1]="bye"; 
} 

выход:

SIZE: 0 
SIZE: 0 
+2

Вы создаете новый лексический переменная '% hh' для каждой итерации цикла for. – TLP

+0

Я знаю, но даже на каждой итерации, после вызова 'func','% hh' остается пустым. – user3991583

+0

Вы создаете новый экземпляр '% hh' внутри вашего подкаталога. Он затеняет предыдущий экземпляр '% hh' из вашего цикла. Вы передаете ссылку, но разыгрываете ее и создаете копию в своем суб. – TLP

ответ

2

Вы создаете новые копии %hh для каждой итерации цикла, и каждого суб использования. Вы передаете свой аргумент по ссылке, но это не имеет значения, поскольку вы копируете значения в любом случае внутри суб. Это:

my %foo = %$bar; 

..makes копию $bar, и любые изменения в %foo не передается на $bar.

Вот прокомментировал версию вашего сценария:

foreach(@RR) 
{ 
    my %hh;      # new variable %hh created each loop iteration 
    &func(\%hh);     # hash passed by reference 
    print "SIZE: ".keys(%hh)."\n"; 
} 

sub func 
{ 
    my %hh = %{$_[0]};   # new variable %hh created, key/values copied 
    my $n="noob"; 
    my $m="moon"; 
    $hh{$n}{$m}[0]="hey";  # copy of %hh affected 
    $hh{$n}{$m}[1]="bye"; 
}        # copy of %hh goes out of scope, values lost 

Если вы хотите, чтобы это работало, как ожидалось, вам необходимо будет использовать реальные ссылки:

sub func { 
    my $ref = shift; 
    $ref->{"noob"}{"moon"}[0] = "hey"; 
    $ref->{"noob"}{"moon"}[1] = "bye"; 
} 
+0

Я хочу избежать использования 'shift', поскольку у меня много аргументов. – user3991583

+0

, тогда do 'my ($ arg1, $ arg2, $ hhref, $ arg4, $ arg5) = @ _' – ysth

+0

@ user3991583 Это не имеет значения. Использование 'shift' - это всего лишь один из способов доступа к' @ _'. Не уверен, почему вы думаете, что использование «shift» невозможно при использовании многих аргументов. – TLP