<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:large"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">пт, 4 окт. 2024 г. в 16:20, Mons Anderson <<a href="mailto:mons@cpan.org">mons@cpan.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">On Fri, Oct 4, 2024 at 3:50 PM Alessandro Gorohovski via Moscow-pm <<a href="mailto:moscow-pm@pm.org" target="_blank">moscow-pm@pm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div style="font-size:large"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">пт, 4 окт. 2024 г. в 13:35, Mons Anderson <<a href="mailto:mons@cpan.org" target="_blank">mons@cpan.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">On Fri, Oct 4, 2024 at 1:21 PM Alessandro Gorohovski via Moscow-pm <<a href="mailto:moscow-pm@pm.org" target="_blank">moscow-pm@pm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div style="font-size:large">По всей видимости, Denis имел ввиду</div><div style="font-size:large">say</div><div style="font-size:large">но это не имеет отношение к функции</div><div style="font-size:large"><br></div><div style="font-size:large">А всё остально будет работать на старых тоже.</div><div style="font-size:large">:)</div><div style="font-size:large"><br></div><div style="font-size:large">Конечно, "положа руку на сердце", предложенная функция -- это вариация через for</div><div style="font-size:large">первоначального алгоритма через while, который предложил ув.</div><div style="margin:0px;min-width:0px;padding:0px 0px 20px;width:initial;font-family:"Google Sans",Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:medium"><div style="font-size:0.875rem;padding:20px 0px 0px"><table cellpadding="0" style="border-collapse:collapse;margin-top:0px;width:auto;font-size:0.875rem;display:block"><tbody style="display:block"><tr style="height:auto;display:flex"><td style="padding:0px;vertical-align:top;width:813.688px;line-height:20px;display:block;max-height:20px"><table cellpadding="0" style="border-collapse:collapse;table-layout:fixed;width:813.688px"><tbody><tr><td style="display:flex"><h3 style="overflow:hidden;font-size:0.75rem;font-weight:inherit;margin:inherit;text-overflow:ellipsis;color:rgb(95,99,104);line-height:20px"><span role="gridcell"><span name="Steffen Winkler via Moscow-pm" style="color:rgb(31,31,31);font-size:0.875rem;font-weight:bold;display:inline;vertical-align:top;line-height:20px"><span style="vertical-align:top">Steffen Winkler</span></span></span></h3></td></tr></tbody></table></td></tr></tbody></table></div></div><div style="font-size:large"><span style="font-size:small">sub where_key {</span><br style="font-size:small"><span style="font-size:small">     my $ref = shift;</span><br style="font-size:small"><span style="font-size:small">     while ( my ($key, $value) = each %h ) {</span></div></div></blockquote><div><br></div><div>откуда тут возьмётся  %h?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div style="font-size:large"><span style="font-size:small">         $ref eq $value</span></div></div></blockquote><div><br></div><div>это неверное сравнение.</div><div>переменные могут быть равны по строковому значению, но быть разными переменными.</div><div>\$ref == \$value более правильное.</div></div></div></blockquote><div><br></div><div><div style="font-size:large">Да, конечно первоначальный вариант с while</div><div style="font-size:large">не совсем корректно отработает на таком случае</div><br></div><div><span style="background-color:rgb(255,153,0)">my %h = ( a => { b=> 1}, aa=> {bb=>2, ac=>2, ab=>2, }, );</span><br><br>sub <span class="gmail_default" style="font-size:large"></span>where_key {<br><span class="gmail_default" style="font-size:large"> </span>my<span class="gmail_default" style="font-size:large"></span> $hash = shift;<br><span class="gmail_default" style="font-size:large"> </span>my $ref = shift;<br><span class="gmail_default" style="font-size:large"> </span>while( my ($key, $value) = each %$hash ) {<br><span class="gmail_default" style="font-size:large">  </span>$ref eq $value<span class="gmail_default" style="font-size:large"> </span>and return $key;<br><span class="gmail_default" style="font-size:large"> </span>}<br>}<br><br><span class="gmail_default" style="font-size:large"></span><span class="gmail_default" style="font-size:large">say</span> where_key( $h{aa}, $h{aa}{bb} );<br></div><div><br></div><div><div style="font-size:large">может выдать не только ожидаемый bb , а любой из </div><div style="font-size:large">ab</div><div style="font-size:large">ac</div><div style="font-size:large">bb</div></div><div><br></div><div><div style="font-size:large">Вот поэтому и предложил другой вариант с for</div><div style="font-size:large"><br></div><div style="font-size:large"><span style="background-color:rgb(182,215,168)"><span style="color:rgb(80,0,80);font-size:small">sub </span><span style="font-size:small">where_key </span><span style="color:rgb(80,0,80);font-size:small">{</span></span><br style="color:rgb(80,0,80);font-size:small"><span style="background-color:rgb(182,215,168);color:rgb(80,0,80);font-size:small"> my $hash  = shift;</span><br style="color:rgb(80,0,80);font-size:small"><span style="background-color:rgb(182,215,168);color:rgb(80,0,80);font-size:small"> my $v;</span><br style="color:rgb(80,0,80);font-size:small"><span style="background-color:rgb(182,215,168);color:rgb(80,0,80);font-size:small"> for( %$hash ) {</span><br style="color:rgb(80,0,80);font-size:small"><span style="background-color:rgb(182,215,168);color:rgb(80,0,80);font-size:small">     return $v if \$_[ 0 ] eq \$_;</span><br style="color:rgb(80,0,80);font-size:small"><span style="background-color:rgb(182,215,168);color:rgb(80,0,80);font-size:small">     $v = $_;</span><br style="color:rgb(80,0,80);font-size:small"><span style="background-color:rgb(182,215,168);color:rgb(80,0,80);font-size:small">   }</span><br style="color:rgb(80,0,80);font-size:small"><span style="background-color:rgb(182,215,168);color:rgb(80,0,80);font-size:small">}</span><br></div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div style="font-size:large"><br style="font-size:small"><span style="font-size:small">              and return $key;</span><br style="font-size:small"><span style="font-size:small">     }</span><br style="font-size:small"><span style="font-size:small">     return;</span><br style="font-size:small"><span style="font-size:small">}</span></div></div></blockquote><div><br></div><div>А вообще имхо вся эта затея полный бред.</div></div></div></blockquote><div><br></div><div><div style="font-size:large">Кому как.</div></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div>Значение не несёт в себе информации о том, кто и откуда на него ссылается.</div><div>Поэтому только по значению такой поиск не может считаться корректным.</div><div>Только с передачей хэша в котором ищем это имеет смысл.</div></div></div></blockquote><div><br></div><div><div style="font-size:large">Вообще здесь вопрос  звучит более широко:</div><div style="font-size:large"><br></div><div style="font-size:large">Как зная ссылку на переменную (scalar, array or hash) найти её название?</div><div style="font-size:large">Perl интерпретатор как то же находит, справляется с этим.</div></div></div></div></div></div></blockquote><div><br></div><div>Perl никак не справляется с этим. Значение не имеет имени. Оно имеет >= 1 ссылок на себя, каждая из которых равнозначно является её именем. Можно иметь на одну и ту же переменную ссылки из нескольких источников. И никакая из ссылок не является её "именем".</div><div><br></div><div>Так что если поставить вопрос правильно, то задача начинает иметь смысл.</div><div>Например:</div><div>- как найти все ссылки на переменную?</div><div><br></div><div>Я постарался подобрать решение исходя из поставленной задачи (по какой из ссылок переменную передали (скорее всего), если исходить из того, что она была передана из хэша.</div><div>Поскольку мы обращались к хэшу прямо перед вызовом, это значит, что padwalker увидит переменную на один стекфрейм выше.</div><div><br></div></div></div></blockquote><div><br></div><div><div class="gmail_default" style="font-size:large">Да, ваше решение неплохо работает,</div><div class="gmail_default" style="font-size:large">хотя не очень лаконичное и требует внешнего модуля</div><div class="gmail_default" style="font-size:large"><b>use PadWalker ':all';</b><br></div><br></div><div><div class="gmail_default" style="font-size:large">действительно "видит" только на один уровень</div><div class="gmail_default" style="font-size:large">и с такими случаями уже не справляется (не находит ничего)</div><br></div><div><span style="background-color:rgb(255,217,102)">my %h = ( a => { b=> 1}, aa=> {bb=>2, ac=>2, ab=>{ bb=>2, ac=>2,  }, } );</span><br><br>detect( $h{aa}{ab} );<br></div><div><br></div></div></div>