Perlでは、コールバックとして使用するメソッドをどのように動的に選択しますか?

StackOverflow https://stackoverflow.com/questions/1039601

質問

Perlでは、パッケージが既知の場合、コールバックまたはコード参照を指定するのは非常に簡単です:

package Foo;

sub foo { print "in foo" }

# and then
package main;

sub baz {
    my $code = shift;
    $code->();
}

baz( \&Foo::foo );

そして、これは in foo を出力します。

次のように、非常に簡単なオブジェクトがあるとしましょう:

package Foo;

sub new { bless {}, shift }
sub bar { print "in bar" }
sub baz { print "in baz" }

上記の方法(\& Package:Method)を使用してメソッドを検索し、次のように呼び出すことができます

package main;
my $foo = Foo->new();
my $ref = \&Foo::bar;
$foo->$ref();

しかし、時には(大抵、しばしば)明示的な型がわからないことがあります。 Foo Bar Baz があり、それらはすべて独自の blat メソッドを持っているとしましょう。パッケージではなくオブジェクトに基づいて、適切なメソッドへの参照を取得する必要があります。それについてどうしますか?

役に立ちましたか?

解決

my $ref = $obj->can('blat');

$ refがundefの場合、オブジェクトはblatできません。 $ refがundefでない場合、問題の関数への有効なCODE参照で、" $ obj-> $ ref(@args)"の呼び出しに適しています。

他のヒント

メソッドルックアップで作業を行います:

$ cat try
#! /usr/bin/perl

use warnings;
use strict;

package Foo;
sub new { bless {} => shift }
sub blat { "Foo blat" }

package Bar;
sub new { bless {} => shift }
sub blat { "Bar blat" }

package Baz;
sub new { bless {} => shift }
sub blat { "Baz blat" }

package main;

my $method = "blat";
foreach my $obj (Foo->new, Bar->new, Baz->new) {
  print $obj->$method, "\n";
}

$ ./try
Foo blat
Bar blat
Baz blat

参照が必要な場合、Perlにはデリゲートがありませんが、親しくできることを覚えておいてください:

my @objs = (Foo->new, Bar->new, Baz->new);

my $method = "blat";
my $obj = $objs[rand @objs];
my $ref = $obj->can($method);

if ($ref) {
  print $ref->($obj), "\n";
}
else {
  print "$obj: no can $method\n";
}

さらに近いもの:

my $delegate = sub { $obj->$ref };
#           or sub { $obj->$method }
print $delegate->(), "\n";
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top