Frage

In Perl, es ist ziemlich trivial einen Rückruf oder Referenz-Code angeben, wenn sein Paket bekannt ist:

package Foo;

sub foo { print "in foo" }

# and then
package main;

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

baz( \&Foo::foo );

Und das druckt in foo.

Lassen Sie uns sagen Sie ein Objekt haben, noch so trivial, wie folgt aus:

package Foo;

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

Sie können die Methode unter Verwendung der obigen Art und Weise nachschlagen (\ & Package: Methode) und nennen Sie es wie

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

Aber manchmal (okay, oft) Sie wissen nicht, den expliziten Typ. Nehmen wir an, es gibt Foo, Bar, Baz, und sie alle haben ihre eigenen blat Methode haben. Sie würden wollen den Verweis auf die entsprechende Methode erhalten, bezogen auf das Objekt anstelle des Pakets. Wie würden Sie das gehen über?

War es hilfreich?

Lösung

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

Wenn $ ref undef ist, das Objekt kann nicht Blat. Wenn $ ref nicht undef, es ist ein gültiger Code Bezug auf die betreffende Funktion, geeignet für Ihren Anruf. "$ Obj -> $ ref (@args)"

Andere Tipps

Lassen Methode Lookup tun, um die Arbeit für Sie:

$ 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

Wenn Sie eine Referenz benötigen, bedenken Sie, dass Perl nicht delegiert hat, aber Sie können in der Nähe bekommen:

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

Noch näher wäre:

my $delegate = sub { $obj->$ref };
#           or sub { $obj->$method }
print $delegate->(), "\n";
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top