В Perl есть ли способ завязать тайник?
-
25-10-2019 - |
Вопрос
Похоже на путь 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;
Линия удаляется, программа работает и выходит правильно.
Я предполагаю, что неудача связана с тем, что тайные тайники, но не такие же, как хэши, поэтому стандартный механизм галстука не работает правильно (или, возможно, просто то, что поиск в тайне никогда не вызывает магию Tie).
Кто-нибудь знает возможно ли это? Чистый Perl был бы лучшим, но решения XS в порядке.
Решение
Вы попадаете в внутреннюю ошибку времени компиляции («плохой символ для скаляра»), это происходит, в то время как Perl пытается выяснить, какой должен быть «$ target :: x», что вы можете проверить, выполнив отладку Perl с:
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:
Другие советы
Немного опоздал на вопрос, но, хотя для этого невозможно использовать Tie, переменная :: Magic позволяет прикрепить магию к тайнике и тем самым достичь чего -то подобного.