Search code examples
perlperl-module

how to get the name of invocant as string in perl


In perl, a class "Lamba" implements a method called "process".

use Lambda;
my $omega = Lambda->new();
$omega->process();

in the process method, how can we get the name of it's invocant?

package Lambda;
use strict;

sub new {
    my $class = shift;
    my $self = {};
    bless ($self, $class);
    return $self; 
} 

sub process {
    my $self = shift;
    my $invocant;
    #
    # ??? what is the variable name of my caller ???
    #
    # ie. how to set $invocant = 'omega';
    #
    return $self;
} 

Solution

  • Update

    I've just realised that you want the name of the variable that was used to call the process method. You can't do that without a source filter, because there may be several names all referring to the same object, like this

    my $omega = Lambda->new;
    my $aa    = $omega;
    my $bb    = $omega;
    
    $aa->process;
    

    and there is quite sensibly no way to get hold of the name actually used to call the method

    This is an X Y problem, and is comparable to asking how to use data strings to name a variable. Variable identifiers are purely for the consumption of the programmer, and if you think your program needs to know them then you have a design problem. If you explain exactly what it is that you want to achieve via this mechanism then I am sure we could help you better



    Original solution

    I've left this here in cased someone arrives at this page looking for a way to discover the name of the calling code

    You can use the caller function

    A call without parameters like caller() will return the package name, source file name, and line number where the current call was made

    You get get more detailed information by adding a parameter that represents the depth on the call stack that you want to examine, so caller(0) will return information about the current subroutine, while the values from caller(1) will be about the calling subroutine

    If we change your main code to use a subroutine to call the method, then we can write this

    Lambda.pm

    package Lambda;
    
    use strict;
    use warnings;
    
    sub new {
        bless {}, shift;
    } 
    
    sub process {
        my $self = shift;
    
        #
        # ??? what is the variable name of my caller ???
        #
        # ie. how to set $invocant = 'omega';
        #
        my $calling_sub = (caller(1))[3];
        print "Called by $calling_sub\n";
    
        return $self;
    } 
    
    1;
    

    main.pl

    use strict;
    use warnings 'all';
    
    use Lambda;
    
    mysub();
    
    sub mysub {
        my $omega = Lambda->new;
        $omega->process;
    }
    

    output

    Called by main::mysub