У меня есть полиморфный массив объектов, реализующих два (неформальных) интерфейса. Я хочу иметь возможность различать их с помощью отражения по линиям:
if (hasattr(obj, 'some_method')) {
# `some_method` is only implemented by one interface.
# Now I can use the appropriate dispatch semantics.
} else {
# This must be the other interface.
# Use the alternative dispatch semantics.
}
Может как то так работает ?:
if (*ref(obj)::'some_method') {
# ...
Мне трудно сказать, когда синтаксис попытается вызвать подпрограмму, а когда вернет ссылку на подпрограмму. Я не слишком знаком с таблицами символов пакетов ATM и просто пытаюсь что-то взломать. :-)
Заранее спасибо!





use Scalar::Util qw(blessed);
if ( blessed($obj) and $obj->can('some_method') ){
}
«can» здесь - это метод, унаследованный всеми классами от УНИВЕРСАЛЬНЫЙ. Классы может переопределяют этот метод, но это не лучшая идея.
Кроме того, «can» возвращает ссылку на функцию, поэтому вы можете:
$foo->can('some_method')->( $foo , @args );
или же
my $sub = $foo->can('some_method');
$foo->$sub( @args );
Редактировать Обновленный синтаксис цепочки, благодаря Брайану Филлипсу
Не забывайте, что вам нужно явно передать объект в ссылку на функцию, возвращаемую can: $ foo-> can ('some_method') -> ($ foo, @args). В качестве альтернативы мой $ sub = $ foo-> can ('some_method'); $ foo -> $ sub (@args);
Общий запрет на отмену can немного строг. Для этого есть веские и веские причины.
can- это каким-то образом зарезервированное имя метода, или вы просто случайно выстрелите себе в ногу, если реализуете его?