Подтвердить что ты не робот

Как проверить, имеет ли объект определенный метод?

Я хочу использовать метод объекта. Как $myObject->helloWorld().

Однако существует несколько методов, поэтому я просматриваю массив имен методов и вызываю метод следующим образом:

my $methodName ="helloWorld";
$myObject->$methodNames;

Это работает довольно хорошо, но некоторые объекты не имеют всех методов.

Как я могу определить, имеет ли $myObject метод под названием helloWorld или нет?

4b9b3361

Ответ 1

Вы можете использовать метод UNIVERSAL::can для всех объектов, чтобы определить, какие методы он поддерживает:

if ($myObject->can($methodName)) {
    $myObject->$methodName;
}

Ответ 2

Как отметил Эрик, вы обычно можете использовать 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 и т.д.)

Ответ 3

Канонический способ использования can находится внутри блока eval, если предмет, который у вас есть в вашей скалярной переменной, на самом деле не является объектом. Вам не нужно беспокоиться об этом, потому что вы все равно получите правильный ответ (не объект или класс не могут ответить на метод):

 if( my $ref = eval { $obj->can( $method ) } )
      {
      $obj->$ref( @args );
      }

can имеет добавленную функцию, которая возвращает ссылку на код для метода. Иногда это может быть удобно.

Ответ 4

Я использовал этот метод при проверке соединений с базой данных, переданных в функцию, например

my $method = "ping";
if(defined ($local_dbh) && eval{ $local_dbh->can($method) } ) {
    if ($local_dbh->ping) {
        return $local_dbh;
    }
}
else {
    ## do connection
    ...
}