Question

En Perl, il est assez simple de spécifier un rappel ou une référence de code si son package est connu:

package Foo;

sub foo { print "in foo" }

# and then
package main;

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

baz( \&Foo::foo );

Et cela affiche dans foo .

Disons que vous avez un objet très trivial, comme ceci:

package Foo;

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

Vous pouvez rechercher la méthode en utilisant la méthode ci-dessus (\ & amp; Package: Method) et l'appeler comme suit

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

Mais parfois (d'accord, souvent) vous ne connaissez pas le type explicite. Disons qu'il existe Foo , Bar , Baz et qu'ils ont tous leur propre méthode blat . Vous voudriez obtenir la référence à la méthode appropriée, basée sur l'objet plutôt que sur le package. Comment vous y prendriez-vous?

Était-ce utile?

La solution

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

Si $ ref est undef, votre objet ne peut pas blater. Si $ ref n’est pas undef, il s’agit d’une référence CODE valide à la fonction en question, qui convient à l’appel " $ obj- > $ ref (@args) ".

.

Autres conseils

Laissez la recherche de méthode faire le travail à votre place:

$ 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

Si vous avez besoin d'une référence, n'oubliez pas que Perl n'a pas de délégué, mais vous pouvez vous en approcher:

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";
}

Encore plus proche serait:

my $delegate = sub { $obj->$ref };
#           or sub { $obj->$method }
print $delegate->(), "\n";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top