• Perl code
    В перле можно вызывать функции следующим способом:
    > $ perl -e 'sub xx {print "Hello\n"}; ("xx")->(1)'
    > Hello
    
    Соответственно если внутри скобок есть какой-то вызов, то он отработает и вызов нового метода будет от результата:
    > $ perl -e 'sub ss { return "xx" }; sub xx {print "Hello\n"}; (ss)->(123);'
    > Hello
    
    Тут всё прекрасно, но есть забавное поведение в случае возврата булевого значение из встроенной функции. Если возвращается false, то всё нормально:
    > $ perl -e '(exists $h{1})->()'
    > Undefined subroutine &main:: called at -e line 1.
    
    А если возвращается true, то мы получаем особую перловую магию:
    > $ perl -e '++$h{1}; (exists $h{1})->()'
    > $
    
    Причём возврат булевого значения из определённых пользователем методов так не работает:
    > $ perl -e 'sub x {1==1}; (x)->()'
    > Undefined subroutine &main::1 called at -e line 1.
    > $ perl -e 'sub x {return 1==1}; (x)->()'
    > Undefined subroutine &main::1 called at -e line 1.
    
    Зато булево значение можно передавать внутрь:
    > $ perl -e 'sub x {$_[0]->(1)}; x(1==1);'
    > $ perl -e 'sub x {shift->(1)}; x(1==1);'
    > $ perl -e 'sub x {my $x=shift; $x->(1)}; x(1==1);'
    > Undefined subroutine &main::1 called at -e line 1.
    > $
    
    В чём тут магия спросите вы? А магия тут в том как перл хранит переменные и вызывает методы. Если вдруг так случилось, что в вашей скалярной (SV в терминах перловых исходников) переменной оказалась не строка "", не число 1, а волшебная переменная из кода на C под именем PL_sv_yes, которая в исходниках перла описана в pod/perlapi.pod, то при вызове метода (а это действие реализовано в методе PP(pp_entersub) в файле pp_hot.c) вы попадёте на код pp_hot.c:2856:
    > if (sv == &PL_sv_yes) {		/* unfound import, ignore */
    > …
    >   RETURN;
    > }
    
    Таким образом знайте, что вызов метода, где в качестве ссылки на метод используется значение true, интерпретируется как импорт несуществующего модуля и игнорируется. Сраные костыли, да.

Replies (0)