The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"почему если %tmp=%hash, то изменяются оба??"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Perl)
Изначальное сообщение [ Отслеживать ]

"почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от greenwar (ok) on 15-Окт-14, 00:19 
доброй ночи
присваиваю %tmp=%hash и работаю ТОЛЬКО с %tmp, но при этом данные в %hash также меняются.
не меняются они, только если прогнать while по всему %hash и поскалярно перекинуть данные в %tmp
т.е. $tmp{$key}=$hash{$key}
это баг или фича?
Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от XAnder (ok) on 15-Окт-14, 08:51 
> присваиваю %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'
        };

Приведите минимальный пример, где наблюдается поведение, которое вы описали. Не используются ли там ссылки?

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от greenwar (ok) on 15-Окт-14, 12:30 
>[оверквотинг удален]
> $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";

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

3. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от XAnder (ok) on 15-Окт-14, 12:44 
> строго говоря это хеш хешей, а с простым хешем всё ок:

Ага, ссылки.

> 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";

И получили закономерный результат.

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от greenwar (ok) on 15-Окт-14, 13:02 
>[оверквотинг удален]
> хеш.
>> my%tmp=%hash;
> Новый хеш %tmp содержит то же, что и старый: одну ссылку на
> тот же самый безымянный хеш. Естественно его копия не была создана.
> Теперь $hash{cat} и $tmp{cat} - один и тот же хеш. Обращаться к
> нему можно и так, и так.
>> $tmp{cat}{1}[0]=25;
> Тут мы поменяли что-то в недрах всё того же безымянного хеша.
>> print"$hash{cat}{1}[0]\n";
> И получили закономерный результат.

ну а как правильно?

Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

5. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от XAnder (ok) on 15-Окт-14, 13:32 
> ну а как правильно?

Трудно сказать, от задачи зависит. В общем случае для копирования сложной структуры можно сделать рекурсивную функцию.

Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

6. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от greenwar (ok) on 15-Окт-14, 13:38 
>> ну а как правильно?
> Трудно сказать, от задачи зависит. В общем случае для копирования сложной структуры
> можно сделать рекурсивную функцию.

ну у меня пока решение такое:
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]
    }
}

но если массив будет помассивней, херня получится

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

7. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от Pahanivo (ok) on 15-Окт-14, 14:49 
>[оверквотинг удален]
> ну у меня пока решение такое:
> 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]
>     }
> }
> но если массив будет помассивней, херня получится

ну дак вы учитесь таки пользоваться перлом.
вам же правильно говорят - делайте функцию копирования для структуры,
а то ни про ссылки не знаете, ни про циклы по массиву ...

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

8. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от greenwar (ok) on 15-Окт-14, 15:30 
>[оверквотинг удален]
>>     {
>>         $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

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

9. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от XAnder (ok) on 15-Окт-14, 16:12 
> а зачем же там функция отдельная, когда можно прям там же:
> my@tmp=@{$hash{$key1}{$key2}};
> for(0..$#tmp){$tmp{$key1}{$key2}[$_]=$hash{$key1}{$key2}[$_]}

Как я и писал, зависит от задачи. Здесь такой способ годится, в другом случае может и нет. Мы ваших задач не знаем, а общий случай слишком заковыристый, чтобы объяснить в двух строчках на форуме и написать в двух строчках на Пёрле. Как, например, будете обрабатывать циклические ссылки? В общем случае они, конечно же, есть. А всякие blessed объекты, требующие инициализации? Их нельзя просто так копировать.

PS. Моё личное вам «фи» за ответ хамством на хамство по нарастающей. А Pahanivo тут штатный, пора бы привыкнуть. Я его когда-то чайникодавом назвал, и он по-прежнему оправдывает это звание :-)

Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

10. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от Pahanivo (ok) on 15-Окт-14, 22:26 
шо вы таки меня палите ))


Ответить | Правка | ^ к родителю #9 | Наверх | Cообщить модератору

11. "почему если %tmp=%hash, то изменяются оба??"  +/
Сообщение от ACCA (ok) on 29-Окт-14, 21:33 

use Storable qw(dclone);
[...]
%tmp = %{ dclone( \%hash ) };

Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру