في بيرل كيف يمكنك اختيار حيوي ما طريقة لاستخدام الاستدعاء؟
سؤال
في بيرل، انها تافهة جدا لتحديد رد أو رمز إشارة إذا كان من المعروف عبوتها:
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";