Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > особенность ссылок на функции


Автор: KSURi 16.12.2008, 21:29
Столкнулся с неявной (для меня) проблемой при отладке. Может кому-то пригодится в будущем.
Был примерно такой код:
Код

my %dispatch = (
  foo => \&foo,
  bar => \&bar,
);

# ...

return unless __PACKAGE__->can($method) # в $method один из ключей %dispatch

# ...

$dispatch{$method}->()

Во время первого запуска я получил ошибку о вызове несуществующего саба. Не понял в чем дело, т.к. у меня есть проверка can для такого случая. Посмотрел код. Оказалось что один из сабов который упомянут в %dispatch действительно не определен (я забыл). Однако проверка can проходила успешно!
Оказывается при упоминании ссылки на саб в таблицу символов добавляется соответствующая запись, даже если такой саб на самом деле не определен.
Код

C:\>perl -MData::Dumper -e"\&foo;print Dumper(\%main::), __PACKAGE__->can('foo')"
$VAR1 = {
...
          'foo' => *::foo,
...
        };
CODE(0x68fb0)

Автор: gcc 17.12.2008, 00:22
если бы можно посмотреть на пример конструктора и методов с этим хэшем...
нигдне не видел

Автор: KSURi 17.12.2008, 00:45
gcc, не совсем понял, что вы хотите увидеть? Код методов из %dispatch? Или полный код в котором происходит проверка и вызов метода из %dispatch?

Автор: gcc 17.12.2008, 04:12
не знаю, нигде не видел чтобы так записывали:
Код

my %dispatch = (
  foo => \&foo,
  bar => \&bar,
);


 &foo это подпрограмма приватная, наверное...
 

Автор: KSURi 17.12.2008, 11:33
Это ссылка на подпрограмму.
perldoc perlref

Автор: ginnie 17.12.2008, 12:37
KSURi, нашел вариант, при котором can отрабатывает правильно:

Код

my %dispatch = (
  foo => *foo{CODE},
  bar => *bar{CODE},
);

Автор: KSURi 17.12.2008, 14:32
ginnie, спасибо конечно, буду иметь ввиду. Однако, честно говоря, пользоваться таким вариантом мне что-то не хочется... Слишком он какой-то искуственный для меня чтоли... А для некоторых программистов может показаться вообще не понятным.

Автор: ginnie 17.12.2008, 15:24
KSURi, не подскажите, в чем искусственность этого варианта? В http://perldoc.perl.org/perlref.html#Making-References (пункт 7) он описан как альтернативный рабочий.

Автор: KSURi 19.12.2008, 14:02
ginnie, "искуственный" не значит "неправильный". Для меня это проявляется в том, что такой способ записи встречается довольно редко. Да и  банально длиннее получается)

Автор: gcc 19.12.2008, 20:32
можно еще так:  smile 
Код

my %dispatch = (
# http://perldoc.perl.org/perlref.html#Making-References (Point 7)
  foo => *foo{CODE},
  bar => *bar{CODE},
);


я почти всегда передаю в классы хэши, но иногда надо просто переменную, то так переопределяю:

Код

sub new {
 my ($self, %common) = @_;
.....................
 if ($common{'file'}) {$self = &File($self, $common{'file'})}
..........
}


Код

sub File{
my ($self, $file) = @_;
}



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)