في بيرل كيف يمكنك اختيار حيوي ما طريقة لاستخدام الاستدعاء؟

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

سؤال

في بيرل، انها تافهة جدا لتحديد رد أو رمز إشارة إذا كان من المعروف عبوتها:

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 main;
my $foo = Foo->new();
my $ref = \&Foo::bar;
$foo->$ref();

ولكن في بعض الأحيان (حسنا، في كثير من الأحيان) كنت لا تعرف نوع صريح. دعونا نقول هناك Foo، Bar، Baz، وأنهم جميعا لديهم طريقة blat الخاصة بهم. وكنت ترغب في الحصول على الإشارة إلى الطريقة المناسبة، استنادا إلى الكائن بدلا من الحزمة. كيف يمكنك أن تذهب نحو ذلك؟

هل كانت مفيدة؟

المحلول

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

إذا $ المرجع هو نديف، وجوه الخاص بك لا يمكن البلاط. إذا $ المرجع لا نديف، انها إشارة CODE صالحة إلى وظيفة في السؤال، ومناسبة للدعوة ". $ الكائنات -> $ المرجع (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

إذا كنت في حاجة الى الإشارة، أن نضع في اعتبارنا أن بيرل لم يكن لديك المندوبين، ولكن يمكنك الحصول على وثيقة:

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