简体   繁体   中英

In Perl, how can I determine if a subroutine was invoked as a method?

Is there a way to determine whether a subroutine is invoked as a method (with @ISA probing) or as a plain subroutine? Perhaps with some sort of extension module super- caller() ?

For example, given

package Ad::Hoc;

sub func() { ... }

How can func() discriminate between the following two invocations:

Ad::Hoc->func;            # or $obj->func

Ad::Hoc::func('Ad::Hoc'); # or func($obj)

(I know, the desire to do this is a Likely Indication of Poor Design™ .)

See if Devel::Caller helps. I changed the code to invoke func on an object and it seems to work on my Mac with perl 5.14.3 (and 5.24.0):

called_as_method($level)

called_as_method returns true if the subroutine at $level was called as a method.

#!/usr/bin/env perl

package Ad::Hoc;
use strict; use warnings;

use Devel::Caller qw( called_as_method );

sub func {
    printf "%s\n", called_as_method(0) ? 'method' : 'function';
    return;
}

package main;
use strict; use warnings;

Ad::Hoc->func;
Ad::Hoc::func();

Output:

method
function
package Ad::Hoc;

sub foo {
    my $self = shift;
    if(ref($self) ne 'Ad::Hoc') {
        unshift @_, $self;
        undef $self;
    }

    if($self) {
        # I'm a method
    } else {
        # I'm a sub
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM