В Perl есть ли способ завязать тайник? - PullRequest
8 голосов
/ 28 апреля 2011

Подобно тому, как AUTOLOAD может использоваться для определения подпрограмм по требованию, мне интересно, есть ли способ связать тайник пакета, чтобы я мог перехватить доступ к переменным в этом пакете.

Я пробовал различные варианты следующей идеи, но, похоже, ни одна из них не работает:

{package Tie::Stash;
    use Tie::Hash;
    BEGIN {our @ISA = 'Tie::StdHash'}
    sub FETCH {
        print "calling fetch\n";
    }
}

{package Target}

BEGIN {tie %Target::, 'Tie::Stash'}

say $Target::x;  

Умирает с Bad symbol for scalar ... в последней строке, без печати "calling fetch". Если строка say $Target::x; удалена, программа запускается и завершается правильно.

Я предполагаю, что ошибка связана с тем, что тайники похожи, но не совпадают с хешами, поэтому стандартный механизм связывания работает неправильно (или это может быть просто, что поиск в тайнике никогда не вызывает магию связи). *

Кто-нибудь знает, возможно ли это? Чистый Perl был бы лучшим, но решения XS в порядке.

Ответы [ 2 ]

4 голосов
/ 28 апреля 2011

Вы попали во внутреннюю ошибку времени компиляции («Плохой символ для скаляра»), это происходит, когда Perl пытается выяснить, каким должен быть «$ Target :: x», что можно проверить, запустив отладочный Perlwith:

perl -DT foo.pl
...
### 14:LEX_NORMAL/XOPERATOR ";\n"
### Pending identifier '$Target::x'
Bad symbol for scalar at foo.pl line 14.

Я думаю, что GV для ':: Target' заменяется чем-то другим, когда вы связываете его (), так что все, что в конечном итоге пытается получить его внутренний хеш, не может.Учитывая, что tie () немного беспорядок, я подозреваю, что то, что вы пытаетесь сделать, не сработает, что также предлагается этим (старым) набором обменов на p5p:

https://groups.google.com/group/perl.perl5.porters/browse_thread/thread/f93da6bde02a91c0/ba43854e3c59a744?hl=en&ie=UTF-8&q=perl+tie+stash#ba43854e3c59a744

1 голос
/ 15 августа 2013

Немного опоздал с вопросом, но хотя для этого и не было возможности использовать tie, Variable :: Magic позволяет вам прикреплять магию к тайнику и таким образом достигать чего-то похожего.

...