доброй ночи
присваиваю %tmp=%hash и работаю ТОЛЬКО с %tmp, но при этом данные в %hash также меняются.
не меняются они, только если прогнать while по всему %hash и поскалярно перекинуть данные в %tmp
т.е. $tmp{$key}=$hash{$key}
это баг или фича?
> присваиваю %tmp=%hash и работаю ТОЛЬКО с %tmp, но при этом данные в
> %hash также меняются.Вообще-то не должно быть такого. Вот минимальный пример:
$ perl -MData::Dumper -E '%hash=(key=>"foo"); %tmp=%hash; $tmp{key}="bar"; print Dumper \%hash, \%tmp'
$VAR1 = {
'key' => 'foo'
};
$VAR2 = {
'key' => 'bar'
};Приведите минимальный пример, где наблюдается поведение, которое вы описали. Не используются ли там ссылки?
>[оверквотинг удален]
> $VAR1 = {
> 'key' =>
> 'foo'
> };
> $VAR2 = {
> 'key' =>
> 'bar'
> };
строго говоря это хеш хешей, а с простым хешем всё ок:
my%hash=(
'cat'=>{
1=>['20','21'],
2=>['30','31']
}
);
my%tmp=%hash;
$tmp{cat}{1}[0]=25;
print"$hash{cat}{1}[0]\n";
> строго говоря это хеш хешей, а с простым хешем всё ок:Ага, ссылки.
> my%hash=(
> 'cat'=>{
> 1=>['20','21'],
> 2=>['30','31']
> }
> );Тут один именованный хеш (%hash), один безымянный хеш и два безымянных массива. Всё это хозяйство связанно друг с другом ссылками.
%hash содержит один элемент - скаляр $hash{cat}, который является ссылкой на безымянный хеш.
> my%tmp=%hash;
Новый хеш %tmp содержит то же, что и старый: одну ссылку на тот же самый безымянный хеш. Естественно его копия не была создана.
Теперь $hash{cat} и $tmp{cat} - один и тот же хеш. Обращаться к нему можно и так, и так.
> $tmp{cat}{1}[0]=25;
Тут мы поменяли что-то в недрах всё того же безымянного хеша.
> print"$hash{cat}{1}[0]\n";
И получили закономерный результат.
>[оверквотинг удален]
> хеш.
>> my%tmp=%hash;
> Новый хеш %tmp содержит то же, что и старый: одну ссылку на
> тот же самый безымянный хеш. Естественно его копия не была создана.
> Теперь $hash{cat} и $tmp{cat} - один и тот же хеш. Обращаться к
> нему можно и так, и так.
>> $tmp{cat}{1}[0]=25;
> Тут мы поменяли что-то в недрах всё того же безымянного хеша.
>> print"$hash{cat}{1}[0]\n";
> И получили закономерный результат.ну а как правильно?
> ну а как правильно?Трудно сказать, от задачи зависит. В общем случае для копирования сложной структуры можно сделать рекурсивную функцию.
>> ну а как правильно?
> Трудно сказать, от задачи зависит. В общем случае для копирования сложной структуры
> можно сделать рекурсивную функцию.ну у меня пока решение такое:
while(my$key1 = each %hash)
{
while(my$key2 = each %{$hash{$key1}})
{
$tmp{$key1}{$key2}[0]=$hash{$key1}{$key2}[0];
$tmp{$key1}{$key2}[1]=$hash{$key1}{$key2}[1]
}
}но если массив будет помассивней, херня получится
>[оверквотинг удален]
> ну у меня пока решение такое:
> while(my$key1 = each %hash)
> {
> while(my$key2 = each %{$hash{$key1}})
> {
> $tmp{$key1}{$key2}[0]=$hash{$key1}{$key2}[0];
> $tmp{$key1}{$key2}[1]=$hash{$key1}{$key2}[1]
> }
> }
> но если массив будет помассивней, херня получитсяну дак вы учитесь таки пользоваться перлом.
вам же правильно говорят - делайте функцию копирования для структуры,
а то ни про ссылки не знаете, ни про циклы по массиву ...
>[оверквотинг удален]
>> {
>> $tmp{$key1}{$key2}[0]=$hash{$key1}{$key2}[0];
>> $tmp{$key1}{$key2}[1]=$hash{$key1}{$key2}[1]
>> }
>> }
>> но если массив будет помассивней, херня получится
> ну дак вы учитесь таки пользоваться перлом.
> вам же правильно говорят - делайте функцию копирования для структуры,
> а то ни про ссылки не знаете, ни про циклы по массиву
> ...о блять, знаток вылез
а зачем же там функция отдельная, когда можно прям там же:
my@tmp=@{$hash{$key1}{$key2}};
for(0..$#tmp){$tmp{$key1}{$key2}[$_]=$hash{$key1}{$key2}[$_]}учитесь таки пользоваться перлом (c)
и читать. вопрос был: как упростить до %tmp=%hash
> а зачем же там функция отдельная, когда можно прям там же:
> my@tmp=@{$hash{$key1}{$key2}};
> for(0..$#tmp){$tmp{$key1}{$key2}[$_]=$hash{$key1}{$key2}[$_]}Как я и писал, зависит от задачи. Здесь такой способ годится, в другом случае может и нет. Мы ваших задач не знаем, а общий случай слишком заковыристый, чтобы объяснить в двух строчках на форуме и написать в двух строчках на Пёрле. Как, например, будете обрабатывать циклические ссылки? В общем случае они, конечно же, есть. А всякие blessed объекты, требующие инициализации? Их нельзя просто так копировать.
PS. Моё личное вам «фи» за ответ хамством на хамство по нарастающей. А Pahanivo тут штатный, пора бы привыкнуть. Я его когда-то чайникодавом назвал, и он по-прежнему оправдывает это звание :-)
шо вы таки меня палите ))
use Storable qw(dclone);
[...]
%tmp = %{ dclone( \%hash ) };