2016-10-10 4 views
5

Вы можете вызвать подпрограмму как метод, используя два синтаксиса в приведенном ниже примере.Как проверить, вызывалась ли подпрограмма с помощью метода вызова объекта или нет

Но вы также можете ссылаться на него не как объект.

#==================================================== 
package Opa; 
sub opa{ 
    $first= shift; 
    $second= shift; 
    print "Opa $first -- $second\n"; 
} 

package main; 
# as object: 
Opa->opa("uno"); 
opa Opa ("uno"); 
# not as object 
Opa::opa("uno","segundo"); 
Opa::opa("Opa","uno"); 
#==================================================== 

Он есть путь, внутри подпрограммы, чтобы знать, «в целом», какого рода вызов к югу получил ?.

+6

Почему нужно знать? Это звучит как xy-проблема. – simbabque

ответ

2

Вы можете использовать called_as_method от 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 -- $second\n"; 
} 

Выход:

object: Opa Opa -- uno 
object: Opa Opa -- uno 
class: Opa uno -- segundo 
class: Opa Opa -- uno 
+0

Большое спасибо! –

0

Вы также можете сделать это с помощью функции ref() вместо использования внешних модулей:

use warnings; 
use strict; 

package Test; 

sub new { 
    return bless {}, shift; 
} 
sub blah { 
    if (ref $_[0]){ 
     print "method call\n"; 
    } 
    else { 
     print "class call\n"; 
    } 
} 

package main; 

my $obj = Test->new; 

$obj->blah; 
Test::blah; 

Выход:

method call 
class call 
+1

Подпрограммы могут принимать ссылки как аргументы, так как это ненадежно для обнаружения вызова метода. Но ref() предоставляет больше: используйте его, чтобы проверить, соответствует ли ref ($ _ [0]) имя класса/пакета: if (ref ($ _ [0]) eq __PACKAGE__) {...} –

+0

[Bitten by Markdown : Это два символа подчеркивания, объединенные с «ПАКЕТ», объединены с еще двумя символами подчеркивания. ] –