On Monday 29 December 2008 13:10:46 Vladimir V. Perepelitsa wrote: > 2008/12/29 Alexander Lourier <[email protected]>: > > On Monday 29 December 2008 12:53:43 Dmitry E. Oboukhov wrote: > >> >> &App::foo и &main::foo это ссылки на одну и ту-же функцию. > >> >> так что выяснить что является настоящим именем, а что алиасом - > >> >> неоднозначно. можно к примеру пройтись рекурсивно по всем неймспейсам > >> >> и найти все имена по равенству ссылок. > >> > >> AL> Тоже хотел так ответить сначала. А потом подумал, что caller > >> каким-то макаром AL> догадывается о настоящем имени. > >> > >> это caller вызваный ИЗНУТРИ функции. > >> там можно и просто тупо __PACKAGE__ или даже __FILE__ юзать. > >> а надо снаружи функции эту же задачу решить > > > > Чуть меняем пример: > > > > == > > package Ap; > > > > use base 'Exporter'; > > our @EXPORT=qw(foo); > > > > sub foo > > { > > $_[0]->(); > > } > > > > package main; > > > > Ap->import(); > > > > sub foo1 > > { > > my @caller = caller(1); > > > > use Data::Dumper; > > print STDERR Dumper(\...@caller); > > } > > > > foo(\&foo1); > > == > > > > $VAR1 = [ > > 'main', > > 'a.pl', > > 23, > > 'Ap::foo', > > 1, > > undef, > > undef, > > undef, > > 256, > > '', > > undef > > ]; > > > > > > На момент вызова caller __PACKAGE__ уже другой (main), но тем не менее, > > функция идентифицирована как Ap::foo. Это значит лишь одно - что в где-то > > глубоко в душе Perl помнит исходное имя каждой подпрограммы, даже > > несмотря на то, что её экспортировали в другой неймспейс. > > Извините меня... > а что еще может вернуть (caller 1)[3], если мы !внутри! сабы Ap::foo > вызывает другую сабу и проверяем в ней caller(1)?
Вот о чём и говорю. Каким образом caller узнал, что мы внутри Ap::foo, а не main::foo? Если бы Ap::foo и main::foo были совершенно симметричными алиасами, то Perl не догадался бы, что это Ap::foo. Он бы подумал так - если из пакета main вызывается foo(), значит это main::foo. А он так не думает. Он лезет в табличку и вспоминает, что foo изначально все-таки объявлялось в Ap, даже вспоминает, в каком файле это было и в какой строке. Поэтому, практически уверен, что задачу можно решить без всякого рекурсивного обхода пакетов, а просто добравшись до этой таблички. Посмотрел исходники функции caller, ничего не понял в терминах (stash и иже с ним) и закрыл. Может кто умеет всё это читать, разберётся. -- Moscow.pm mailing list [email protected] | http://moscow.pm.org
