Массив хэшей, не передаваемых ссылкой на подпрограмму

У меня есть сеттер sub setAssignmentStatus, который принимает массив хэшей (отсюда и далее AoH) и другой параметр (не беспокойтесь об этом, так как эта часть работает) и делает что-то, повторяя AoH, чтобы установить другая запись в каждом элементе хеша. Он ничего не возвращает, потому что я хочу использовать тот же объект AoH с добавленными записями после того, как он будет протянут через сеттер, а не создавать полностью новый AoH и повторно заполнять записи. Вот сеттер:

sub setAssignmentStatus
{
    my $fileFlatArySclr = $_[0];
    my $cfgFile = $_[1];

    #here I convert the AoH from the scalar necessary for the sub to its native form
    my @fileFlatAry = @$fileFlatArySclr;

    #this works, don't worry
    my %cfgVarHash = getConfigVars($cfgFile);

    foreach my $fileVarHashSclr(@fileFlatAry)
    {
        #convert each AoH entry from scalar necessary for iteration to native hash
        my %varHash = %$fileVarHashSclr;

        my $varName = $varHash{'VAR_NAME'};

        my $asgnLineCnt = $varHash{'ASGN_CNT'};

        my $asgnSts;
        my $fileAsgnSts; 
        my $cfgAsgnSts; 

        if($asgnLineCnt > 0) { $fileAsgnSts = 1; } else { $fileAsgnSts = 0; }

        my $cfgAsgnLine = $cfgVarHash{$varName};

        if($cfgAsgnLine ne undef) { $cfgAsgnSts = 1; } else { $cfgAsgnSts = 0; }

        $asgnSts = $fileAsgnSts.$cfgAsgnSts;

        #debug to make sure $asgnSts is not null in the first place (it is not!)
        print "\n*** setting ASGN_STUS of ".$varName." to ".$asgnSts;

        #Here we set ASGN_STUS for every iteration
        $varHash{'ASGN_STUS'} = $asgnSts;
    }
}

Он называется следующим образом:

setAssignmentStatus(\@fileFlatAry, $cfgFile);

Однако после отправки @fileFlatAry AoH через setAssignmentStatus хэш каждого элемента не содержит запись ASGN_STUS. Почему это так и как я могу это исправить?

Я подозреваю, что я делаю что-то не так с модификатором \, поэтому я получаю структуру данных для передачи в качестве скалярного параметра в подпрограмму, но я не уверен.


person amphibient    schedule 02.02.2013    source источник


Ответы (1)


Вы изменяете %varHash вместо изменения хэша, на который указывает ссылка. Прекратите копировать все в локальные переменные и модифицировать локальные переменные.

$varHash{'ASGN_STUS'} = ...;

должно быть

$fileVarHashSclr->{'ASGN_STUS'} = ...;

Я бы тоже не стал делать my @fileFlatAry = @$fileFlatArySclr;. Чистые отходы.

person ikegami    schedule 02.02.2013
comment
Нет, это не так. Это копия элемента (точнее, хэш, на который ссылается элемент). - person ikegami; 02.02.2013
comment
если бы вы не сделали my @fileFlatAry = @$fileFlatArySclr;, как бы вы еще перебирали массив? - person amphibient; 02.02.2013
comment
я делал это так раньше. причина, по которой я делаю это в отдельной строке, заключается в том, что я предпочитаю сделать каждую строку кода как можно более простой с как можно меньшим количеством вычислений в этой строке. в конечном итоге это приводит к большему количеству строк кода, однако каждая строка проста, и мне легче поддерживать ее таким образом. - person amphibient; 02.02.2013
comment
(И вы действительно обманываете себя, утверждая, что my %varHash = %$otherHash; my $x = $varHash{'ASGN_STUS'}; легче читать, чем my $x = $otherHash->{'ASGN_STUS'};.) - person ikegami; 02.02.2013