The OpenNET Project / Index page

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




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
почему если %tmp=%hash, то изменяются оба??, !*! greenwar, 15-Окт-14, 00:19  [смотреть все]
доброй ночи
присваиваю %tmp=%hash и работаю ТОЛЬКО с %tmp, но при этом данные в %hash также меняются.
не меняются они, только если прогнать while по всему %hash и поскалярно перекинуть данные в %tmp
т.е. $tmp{$key}=$hash{$key}
это баг или фича?
  • почему если %tmp=%hash, то изменяются оба??, !*! XAnder, 08:51 , 15-Окт-14 (1)
    > присваиваю %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'
            };

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

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

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

        Ага, ссылки.

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

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

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

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

          • почему если %tmp=%hash, то изменяются оба??, !*! XAnder, 13:32 , 15-Окт-14 (5)
            > ну а как правильно?

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

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

              ну у меня пока решение такое:
              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=%hash, то изменяются оба??, !*! Pahanivo, 14:49 , 15-Окт-14 (7)
                >[оверквотинг удален]
                > ну у меня пока решение такое:
                > 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=%hash, то изменяются оба??, !*! greenwar, 15:30 , 15-Окт-14 (8)
                  >[оверквотинг удален]
                  >>     {
                  >>         $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

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

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

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

          • почему если %tmp=%hash, то изменяются оба??, !*! ACCA, 21:33 , 29-Окт-14 (11)

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




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

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