[Moscow.pm] Узнать родительский ключ по ссылке
Denis Evdokimov
evdokimov.denis на gmail.com
Пт Окт 4 06:54:53 PDT 2024
Я перепутал. Будет работать
пт, 4 окт. 2024 г., 16:46 Alessandro Gorohovski via Moscow-pm <
moscow-pm на pm.org>:
>
>
> пт, 4 окт. 2024 г. в 16:20, Mons Anderson <mons на cpan.org>:
>
>> On Fri, Oct 4, 2024 at 3:50 PM Alessandro Gorohovski via Moscow-pm <
>> moscow-pm на pm.org> wrote:
>>
>>>
>>>
>>> пт, 4 окт. 2024 г. в 13:35, Mons Anderson <mons на cpan.org>:
>>>
>>>> On Fri, Oct 4, 2024 at 1:21 PM Alessandro Gorohovski via Moscow-pm <
>>>> moscow-pm на pm.org> wrote:
>>>>
>>>>> По всей видимости, Denis имел ввиду
>>>>> say
>>>>> но это не имеет отношение к функции
>>>>>
>>>>> А всё остально будет работать на старых тоже.
>>>>> :)
>>>>>
>>>>> Конечно, "положа руку на сердце", предложенная функция -- это вариация
>>>>> через for
>>>>> первоначального алгоритма через while, который предложил ув.
>>>>> Steffen Winkler
>>>>> sub where_key {
>>>>> my $ref = shift;
>>>>> while ( my ($key, $value) = each %h ) {
>>>>>
>>>>
>>>> откуда тут возьмётся %h?
>>>>
>>>> $ref eq $value
>>>>>
>>>>
>>>> это неверное сравнение.
>>>> переменные могут быть равны по строковому значению, но быть разными
>>>> переменными.
>>>> \$ref == \$value более правильное.
>>>>
>>>
>>> Да, конечно первоначальный вариант с while
>>> не совсем корректно отработает на таком случае
>>>
>>> my %h = ( a => { b=> 1}, aa=> {bb=>2, ac=>2, ab=>2, }, );
>>>
>>> sub where_key {
>>> my $hash = shift;
>>> my $ref = shift;
>>> while( my ($key, $value) = each %$hash ) {
>>> $ref eq $value and return $key;
>>> }
>>> }
>>>
>>> say where_key( $h{aa}, $h{aa}{bb} );
>>>
>>> может выдать не только ожидаемый bb , а любой из
>>> ab
>>> ac
>>> bb
>>>
>>> Вот поэтому и предложил другой вариант с for
>>>
>>> sub where_key {
>>> my $hash = shift;
>>> my $v;
>>> for( %$hash ) {
>>> return $v if \$_[ 0 ] eq \$_;
>>> $v = $_;
>>> }
>>> }
>>>
>>>
>>>
>>>
>>>>
>>>>
>>>>>
>>>>> and return $key;
>>>>> }
>>>>> return;
>>>>> }
>>>>>
>>>>
>>>> А вообще имхо вся эта затея полный бред.
>>>>
>>>
>>> Кому как.
>>>
>>>
>>>
>>>> Значение не несёт в себе информации о том, кто и откуда на него
>>>> ссылается.
>>>> Поэтому только по значению такой поиск не может считаться корректным.
>>>> Только с передачей хэша в котором ищем это имеет смысл.
>>>>
>>>
>>> Вообще здесь вопрос звучит более широко:
>>>
>>> Как зная ссылку на переменную (scalar, array or hash) найти её название?
>>> Perl интерпретатор как то же находит, справляется с этим.
>>>
>>
>> Perl никак не справляется с этим. Значение не имеет имени. Оно имеет >= 1
>> ссылок на себя, каждая из которых равнозначно является её именем. Можно
>> иметь на одну и ту же переменную ссылки из нескольких источников. И никакая
>> из ссылок не является её "именем".
>>
>> Так что если поставить вопрос правильно, то задача начинает иметь смысл.
>> Например:
>> - как найти все ссылки на переменную?
>>
>> Я постарался подобрать решение исходя из поставленной задачи (по какой из
>> ссылок переменную передали (скорее всего), если исходить из того, что она
>> была передана из хэша.
>> Поскольку мы обращались к хэшу прямо перед вызовом, это значит, что
>> padwalker увидит переменную на один стекфрейм выше.
>>
>>
> Да, ваше решение неплохо работает,
> хотя не очень лаконичное и требует внешнего модуля
> *use PadWalker ':all';*
>
> действительно "видит" только на один уровень
> и с такими случаями уже не справляется (не находит ничего)
>
> my %h = ( a => { b=> 1}, aa=> {bb=>2, ac=>2, ab=>{ bb=>2, ac=>2, }, } );
>
> detect( $h{aa}{ab} );
>
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org
>
----------- следующая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20241004/12de996f/attachment-0001.html>
Подробная информация о списке рассылки Moscow-pm