Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Изменение копии хэша приводит к изменению оригинала...  (Прочитано 6852 раз)
0 Пользователей и 1 Гость смотрят эту тему.
asa
Новенький

ua
Offline Offline

« : 10-11-2012 19:30 » 

Привет!

Наткнулся как-то в работе, не могу понять - это бага, или фича.

Суть в том, что я меняю значение ключа "a1" хэша, который является значением ключа "qwer" копии хэша %hash - %tash.

Но при этом меняется аналогичное значение хэша %hash.

В другом случае, создается пара ключ-значение в хэше %hash, при изменении хеша %tash.

Код: (Perl)
my (%hash,%tash);
$hash{'qwer'}{'a1'} = '10';
%tash = %hash;
$tash{'qwer'}{'a1'} = '20';
print 'hash: ',$hash{'qwer'}{'a1'},"\n";
print 'tash: ',$tash{'qwer'}{'a1'},"\n";
print "\%hash keys: ",join (' ',(keys %{$hash{"qwer"}})) . "\n";
$tash{'qwer'}{'a2'} = 'test';
print 'hash: ',$hash{'qwer'}{'a2'},"\n";
print 'tash: ',$tash{'qwer'}{'a2'},"\n";
print "\%hash keys: ",join (' ',(keys %{$hash{"qwer"}})) . "\n";
Код: (Text) вывод
hash: 20
tash: 20
%hash keys: a1
hash: test
tash: test
%hash keys: a2 a1

Если убрать строку
Код: (Perl)
$hash{'qwer'}{'a1'} = '10';

Код: (Text) вывод
hash:
tash: 20
%hash keys:
hash:
tash: test
%hash keys:

если её же заменить на
Код: (Perl)
$hash{'qwer'}{'a3'} = '10';

Код: (Text) вывод
hash: 20
tash: 20
%hash keys: a1 a3
hash: test
tash: test
%hash keys: a2 a1 a3

А если не использовать вложенный хэш - содержимое %hash не меняется, при изменении %tash, что свидетельствует в пользу баги...
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 10-11-2012 20:06 » 

Наткнулся как-то в работе, не могу понять - это бага, или фича.

Моя практика говорит, что бага сидит в голове, а фича — в непонимании этой баги. Ага

Цитата
Суть в том, что я меняю значение ключа "a1" хэша, который является значением ключа "qwer" копии хэша %hash - %tash.

Э... Кто на ком стоял?
Это тем более не понятно:

Цитата
Но при этом меняется аналогичное значение хэша %hash.

В другом случае, создается пара ключ-значение в хэше %hash, при изменении хеша %tash.

Давай посмотрим код...

Цитата
Код: (Perl)
$hash{'qwer'}{'a1'} = '10';

Запомни: в Perl нет многомерных массивов и хешей. Но можно хранить ссылку на анонимный массив или хеш.
Так правильнее и понятнее: значением является ссылка на анонимный хеш.

Код: (Perl)
$hash{'qwer'} = {'a1' => '10'};

Корректное обращение:

Код: (Perl)
$a = $hash{'qwer'}->{'a1'};

Опускать «стрелку» здесь нельзя. Не, можно. Опускать также допускается последующие идущие подряд стрелки при использовании ссылки:

Код: (Perl)
$hashref = {'a' => 1, 'b' => 2};
$a = $hashref->{'a1'}->{'b2'}->{'c3'};
$a = $hashref->{'a1'}{'b2'}{'c3'};

Стрелка является операцией разыменованием ссылки.

Код: (Perl)
%hash = ('a' => 1, 'b' => 2);
$a = $hash{'a1'}->{'b2'}->{'c3'};
$a = $hash{'a1'}{'b2'}{'c3'};

Настоятельно рекомендую начинать код с «use strict;», будет меньше сюрпризов.

Что дальше?

Цитата
Код: (Perl)
%tash = %hash;

У тебя присвоение списком: копия помещается в %tash. А вот про ссылки ты забыл? Они то по прежнему ссылаются на анонимные хеши.
В общем, копировать в лоб можно только скаляры встроенных типов. Остальные скаляры являются явными или неявными ссылками.

Если не понятно, спрашивай.
« Последнее редактирование: 10-11-2012 20:29 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
asa
Новенький

ua
Offline Offline

« Ответ #2 : 10-11-2012 20:35 » new

А вот про ссылки ты забыл? Они то по прежнему ссылаются на анонимные хеши.
Спасибо, RXL.

 Быть такого не может
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines