Ответ 1
Вы можете использовать метод UNIVERSAL::can
для всех объектов, чтобы определить, какие методы он поддерживает:
if ($myObject->can($methodName)) {
$myObject->$methodName;
}
Я хочу использовать метод объекта.
Как $myObject->helloWorld()
.
Однако существует несколько методов, поэтому я просматриваю массив имен методов и вызываю метод следующим образом:
my $methodName ="helloWorld";
$myObject->$methodNames;
Это работает довольно хорошо, но некоторые объекты не имеют всех методов.
Как я могу определить, имеет ли $myObject
метод под названием helloWorld
или нет?
Вы можете использовать метод UNIVERSAL::can
для всех объектов, чтобы определить, какие методы он поддерживает:
if ($myObject->can($methodName)) {
$myObject->$methodName;
}
Как отметил Эрик, вы обычно можете использовать UNIVERSAL::can
Он может использоваться как на объекте, так и в вашем примере ($obj->can($methodName)
) или статически, в классе: (CLASS->can($methodName)
)
Обратите внимание, что возможны возможные ложные негативы, связанные с использованием UNIVERSAL::can
для объектов/классов, которые имеют методы AUTOLOAD-ed - см. perldoc для деталей. Поэтому перед тем, как использовать can()
для объекта/класса, будьте осторожны, чтобы убедиться, что рассматриваемый класс не использует AUTOLOAD или переопределяет can()
для компенсации или использует форвардную декларацию для компенсации, как описано в can()
perldoc - подсказка шляпы для brian d foy)
Кроме того, будьте внимательны либо ТОЛЬКО называть can()
на реальных объектах, либо инкапсулировать его в eval. Он будет умирать, если вызван не-объект (например, undef, scalar и т.д.)
Канонический способ использования can
находится внутри блока eval
, если предмет, который у вас есть в вашей скалярной переменной, на самом деле не является объектом. Вам не нужно беспокоиться об этом, потому что вы все равно получите правильный ответ (не объект или класс не могут ответить на метод):
if( my $ref = eval { $obj->can( $method ) } )
{
$obj->$ref( @args );
}
can
имеет добавленную функцию, которая возвращает ссылку на код для метода. Иногда это может быть удобно.
Я использовал этот метод при проверке соединений с базой данных, переданных в функцию, например
my $method = "ping";
if(defined ($local_dbh) && eval{ $local_dbh->can($method) } ) {
if ($local_dbh->ping) {
return $local_dbh;
}
}
else {
## do connection
...
}