| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Perl: Общие вопросы > Контекст вызова функции |
| Автор: pavels 26.9.2010, 18:54 |
| Кто знает как из вызываемой ф-ии узнать каким образом она была вызвана Package::function('Package') или Package->function() ? Спасибо! |
| Автор: arto 26.9.2010, 19:26 |
| $_[0] |
| Автор: pavels 26.9.2010, 21:06 | ||
Таким образом я получаю строку 'Package', вопрос каким образом функция вызвалась (через :: или ->) |
| Автор: infarch 27.9.2010, 10:33 |
| Если $_[0] равно имени пакета то вызвана как -> |
| Автор: Logo 27.9.2010, 10:56 |
| $_[0] в обоих случаях будет равно 'Package'. В обычно определять как вызывалася функция, через -> или как обычная не нужно, т. к. Perl допускает оба способа вызова. Когда-то видел на CPAN модуль, позволяющий определить сабж. |
| Автор: KSURi 27.9.2010, 11:51 |
| Как сделать это в общем случае не знаю, но здесь в первом случае будет два аргумента, во втором - один. |
| Автор: Logo 27.9.2010, 13:19 |
| Между этими способами разница только в том, что во втором случае включается механизм наследования, а в первом нет. Поэтому стандартными средствами не определить. Но повторюсь, если не ошибаюсь, где-то видел модуль, это делающий. |
| Автор: Jimy 27.9.2010, 15:18 | ||||||
Здесь будет один аргумент в обоих случаях.
Смысла передавать название пакета в качестве аргумента не вижу поскольку его можно узнать внутри пакета в переменной __PACKAGE__. Определить, как был вызван метод можно анализируя первый аргумент. Во втором случае следующий код вернет истину:
|
| Автор: arto 27.9.2010, 16:32 |
| # perl -l =( cat ) package AA; use base "Exporter"; our @EXPORT = qw( aa ); sub aa ($$) { return sprintf "<%s> (%s) %s",__PACKAGE__, join ( ",",map { m#\D# ? "'$_'" : $_ } @_ ), join ",",caller (0); } package main; print "AA::aa (1,2) => ",AA::aa (1,2); print "AA->aa (1,2) => ",AA->aa (1,2); print "aa AA (1,2) => ",aa AA (1,2); ^D AA::aa (1,2) => <AA> (1,2) main,/tmp/zshcEGVK6,14,AA::aa,1,1,,,256,, AA->aa (1,2) => <AA> ('AA',1,2) main,/tmp/zshcEGVK6,15,AA::aa,1,1,,,256,, aa AA (1,2) => <AA> ('AA',1,2) main,/tmp/zshcEGVK6,16,AA::aa,1,1,,,256,, # |
| Автор: pavels 27.9.2010, 18:41 | ||||||||
Спасибо всем, кто пытается помочь..
Я пытаюсь написать маленький модуль, для автозагрузки модулей (в проекте много модулей, имена пакетов которых совпадает с именами модулей) чтоб модуль подтягивался по запросу (вместо require Module; перед вызовом ф-ии) Известно, что логику можно посадить на UNIVERSAL::AUTOLOAD, которая запустится, если ф-ия не найдена, которая в свою очередь должна подгрузить модуль и запустить ф-ию из нее. Возможно, что вызываемая ф-ия является наследуемым методом базового класса, соответственно нужно вызывать как -> (например my $order = Order->new()), соответственно в UNIVERSAL::AUTOLOAD я должен различать способ вызова (через :: или ->). |
| Автор: KSURi 27.9.2010, 23:07 |
О, точно. Не заметил, что второй вызов без аргументов был. |
| Автор: Jimy 29.9.2010, 09:06 | ||||||
Совершенно верно, и это говорит о том, что была статично вызвана функция пакета. А при вызове из объекта будет выполняться равенство
|
| Автор: Logo 16.12.2010, 14:02 |
| Сегодня наткнулся на модуль, о котором говорил. Devel::Caller. Кстати, проверка не работает под отладчиком, т.к. отладчик перехватывает вызовы функций, и вызывыет их самостоятельно. |