Используйте asp:Panel
для этого. Это переводит в отделение
Ага! Чтобы сделать это с помощью ограничений, используйте can
.
package Foo::Bar;
use strict;
use warnings;
sub baz
{
return "Passed in '@_' and ran baz!";
}
package main;
use strict;
use warnings;
my $class = 'Foo::Bar';
if (my $method = $class->can('baz'))
{
print "yup it can, and it ";
print $method->();
}
else
{
print "No it can't!";
}
can
возвращает ссылку на метод undef / false. Затем вам просто нужно вызвать метод с синтаксисом разыменования.
Он дает:
> perl foobar.pl yup it can, and it Passed in '' and ran baz!
Как всегда с Perl, есть несколько способов сделать это .
use strict;
use warnings;
{
package Test::Class;
sub static_method{ print join(' ', @_), "\n" }
}
Вы можете использовать специальную переменную % ::
для доступ к таблице символов.
my $ class = 'Test :: Class';
мой @depth = split '::', $ class;
мой $ ref = \% ::;
$ ref = $ glob -> {$ _. '::'} для @depth; # $ :: {'Test ::'} {'Class ::'}
$ code = $ glob -> {'static_method'};
$ code -> ('Привет', 'Мир');
Вы можете просто использовать символическую ссылку ;
без строгих ссылок;
мой $ code = & {"$ {class} :: static_method"};
# или
мой $ code = * {"$ {class} :: static_method"} {CODE};
$ code -> ('Привет', 'Мир');
Вы также можете использовать строку eval
.
eval "$ {class} :: static_method ('Hello', 'World')";
Самым простым в этом случае было бы использовать UNIVERSAL :: can
.
$ code = $ class-> can ('static_method');
$ code -> ('Привет', 'Мир');
Я не знаю особенно хорошего способа сделать это, но есть и менее приятные способы, такие как эта программа :
#!/usr/bin/perl -w
use strict;
package Test::Class1;
sub static_method {
print join(", ", @_) . "\n";
}
package main;
my $class = "Test::Class1";
{
no strict "refs";
&{${class}. "::static_method"}(1, 2, 3);
}
Я добавил переменную $ class
, поскольку именно так вы задали вопрос, и она показывает, как имя класса может быть выбрано во время выполнения, но если вы знаете класс заранее, вы можете так же легко вызовите & {"Test :: Class1 :: static_method"} (1, 2, 3);
Обратите внимание, что вы должны отключить строгие "ссылки"
, если у вас есть это дальше.
Вы можете использовать строку eval :
#!/usr/bin/perl
use strict; use warnings;
package Test::Class1;
sub static_method {
print join(", ", @_) . "\n";
}
package main;
my $class = 'Test::Class1';
my $static_method = 'static_method';
my $subref = eval q{ \&{ "${class}::${static_method}" } };
$subref->(1, 2, 3);
Вывод:
C:\Temp> z 1, 2, 3
Тесты:
#!/usr/bin/perl
use strict; use warnings;
package Test::Class1;
sub static_method { "@_" }
package main;
use strict; use warnings;
use Benchmark qw( cmpthese );
my $class = 'Test::Class1';
my $static_method = 'static_method';
cmpthese -1, {
'can' => sub { my $r = $class->can($static_method); $r->(1, 2, 3) },
'eval' => sub {
my $r = eval q/ \&{ "${class}::${static_method}" } /;
$r->(1, 2, 3);
},
'nostrict' => sub {
no strict "refs";
my $r = \&{ "${class}::static_method" };
$r->(1, 2, 3);
}
};
Вывод:
Rate eval can nostrict eval 12775/s -- -94% -95% can 206355/s 1515% -- -15% nostrict 241889/s 1793% 17% --
Есть три основных способа вызвать статическую функцию:
$ object-> static_method ()
Classname-> static_method ()
Classname :: static_method ()
Вы можете определить свою функцию так:
# callable as $object->static_method() or Classname->static_method()
sub static_method
{
my $class = shift; # ignore; not needed
# ...
}
или подобным этому, которая работает во всех трех сценариях вызова и не работает » t несут какие-либо накладные расходы на вызывающей стороне, как это делает решение Роберта П.:
use UNIVERSAL qw(isa);
sub static_method
{
my $class = shift if $_[0] and isa($_[0], __PACKAGE__);
# ...
}