Hello,
What I have done in the while loop, I check the stringified reference of that hash reference. If that is equal, the the same hash reference is there and I return the output. If there are more then one equal hash references you have to put the keys into an array and do not return.
Steffen

auto translated
Здравствуйте,
В цикле while я проверяю строковую ссылку на эту хэш-ссылку. Если она равна, то это одна и та же хэш-ссылка и я возвращаю вывод. Если равных хэш-ссылок больше одной, то нужно поместить ключи в массив и не возвращать.
Штеффен

Am 01.10.2024 um 14:03 schrieb Коваль Вячеслав via Moscow-pm:
Смотри, во-первых, в данном случае нет необходимости разыменовывать хэш и брать из него ссылку. Можено сразу передавать нужный хэш: $h{aa}. Во-вторых, в функцию (в нижеприведенном коде вместо функции выступает переменная $val) мы уже передаем ссылку на хэш
{ bb => 2 }. Функция ничего не знает о ключе, он есть только в хэше.
#!/usr/bin/perl -w
use strict;
use warnings;
use feature 'say';
use DDP;
use Scalar::Util qw/refaddr/;
my %h = ( a => { b => 1 }, aa => { bb => 2 } );
p %h;
say refaddr $h{aa};
my $val = $h{aa};
p $val;
say refaddr $val;
say refaddr $h{aa} == refaddr $val;
Как вариант можно передавать предыдущее значение, где есть ключ.
my %h = (aa => { bb => { cc => 3}});
where_key('bb', $h{aa});

Либо передавать исходных хэш:

where_key($искомая_ссылка, \%h);
----------------
01.10.2024, 14:44, "Alessandro Gorohovski" <[email protected]>:
Кому: Коваль Вячеслав ([email protected]);
Копия: Moscow.pm group ([email protected]);
Тема: [Moscow.pm] Узнать родительский ключ по ссылке;

    Вообще то передаётся ссылка (фактически адрес)
     \%{ $h{aa} }
    , а не просто значение.
    вт, 1 окт. 2024 г. в 14:37, Коваль Вячеслав <[email protected]>:

        Для решения задачи все равно нужен доступ к исходному хэшу,
        т.к. в изначальном коде мы передаем уже обращаемся по ключу и
        в функцию уже передается значение, т.е. какой-то хэш или
        массив или значение. А чтобы получить ключ, то нужно
        рекурсивно пройтись по исходному хэшу и сравнить
        Scalar::Util::refaddr всех значений с исходным.
        ----------------
        01.10.2024, 13:47, "Alessandro Gorohovski via Moscow-pm"
        <[email protected]>:
        Кому: Moscow.pm group ([email protected]);
        Копия: Alessandro Gorohovski ([email protected]);
        Тема: [Moscow.pm] Узнать родительский ключ по ссылке;

            Нет, это не вариант.
            Функция не знает о хеше %h и его структуре, совсем не знает :)
            Представьте, что этот хеш может быть не 2х уровневый, а
            много-много-вложенный по уровням
            и
            $ref eq $value
            может случится на другом уровне.
            вт, 1 окт. 2024 г. в 13:03, Steffen Winkler via Moscow-pm
            <[email protected]>:

                use strict;
                use warnings;

                my %h = ( a => { b=> 1}, aa=> {bb=>2, }, );

                sub where_key {
                     my $ref = shift;

                     while ( my ($key, $value) = each %h ) {
                         $ref eq $value
                              and return $key;
                     }

                     return;
                }

                my $k = where_key( $h{aa} );
                print $k;
                exit;


                --
                Moscow.pm mailing list
                [email protected] | http://moscow.pm.org

            ,--
            Moscow.pm mailing list
            [email protected] | http://moscow.pm.org

-- Яндекс.Почта — надёжная почта
        http://mail.yandex.ru/neo2/collect/?exp=1&t=1
        <http://mail.yandex.ru/neo2/collect/?exp=1&t=1>

--
Яндекс.Почта — надёжная почта
http://mail.yandex.ru/neo2/collect/?exp=1&t=1
-- 
Moscow.pm mailing list
[email protected] | http://moscow.pm.org

Ответить