#perl #object #subroutine #method-invocation
#perl #объект #подпрограмма #метод-вызов
Вопрос:
Вы можете вызвать подпрограмму как метод, используя два синтаксиса в примере ниже.
Но вы также можете вызвать ее не как объект.
#====================================================
package Opa;
sub opa{
$first= shift;
$second= shift;
print "Opa $first -- $secondn";
}
package main;
# as object:
Opa->opa("uno");
opa Opa ("uno");
# not as object
Opa::opa("uno","segundo");
Opa::opa("Opa","uno");
#====================================================
Есть ли способ изнутри подпрограммы узнать «в целом», какой вызов получил sub ?.
Комментарии:
1. Зачем вам это знать? Это звучит как xy-проблема.
Ответ №1:
Вы можете использовать called_as_method
from Devel::Caller .
use Devel::Caller qw( called_as_method );
sub opa{
print called_as_method(0) ? 'object: ' : 'class: ';
$first= shift;
$second= shift;
print "Opa $first -- $secondn";
}
Вывод:
object: Opa Opa -- uno
object: Opa Opa -- uno
class: Opa uno -- segundo
class: Opa Opa -- uno
Ответ №2:
Вы также можете сделать это с ref()
помощью функции вместо использования внешних модулей:
use warnings;
use strict;
package Test;
sub new {
return bless {}, shift;
}
sub blah {
if (ref $_[0]){
print "method calln";
}
else {
print "class calln";
}
}
package main;
my $obj = Test->new;
$obj->blah;
Test::blah;
Вывод:
method call
class call
Комментарии:
1. Подпрограммы могут принимать ссылки в качестве аргументов, так как это ненадежно для обнаружения вызова метода. Но ref() предоставляет больше: используйте его, чтобы проверить, предоставляет ли ref($_[0]) имя класса / пакета: if (ref($_[0]) eq PACKAGE ) { … }
2. [ Укушено Markdown: это два символа подчеркивания, объединенные с ‘PACKAGE’, объединенным с еще двумя символами подчеркивания. ]