Detect how a subroutine is called in Perl
Asked Answered
D

3

7

I would like to detect how a subroutine is called so I can make it behave differently depending on each case:

# If it is equaled to a variable, do something:
$var = my_subroutine();

# But if it's not, do something else:
my_subroutine();

Is that possible?

Declarer answered 20/8, 2013 at 14:10 Comment(0)
M
17

Use wantarray

if(not defined wantarray) {
    # void context: foo()
}
elsif(not wantarray) {
    # scalar context: $x = foo()
}
else {
    # list context: @x = foo()
}
Maxinemaxiskirt answered 20/8, 2013 at 14:14 Comment(1)
There is also p3rl.org/Want module, but for this case it might be overkill.Piapiacenza
E
9

Yes, what you're looking for is wantarray:

use strict;
use warnings;

sub foo{
  if(not defined wantarray){
    print "Called in void context!\n";
  }
  elsif(wantarray){
    print "Called and assigned to an array!\n";
  }
  else{
    print "Called and assigned to a scalar!\n";
  }
}

my @a = foo();
my $b = foo();
foo();

This code produces the following output:

Called and assigned to an array!
Called and assigned to a scalar!
Called in void context!
Epicycloid answered 20/8, 2013 at 14:15 Comment(0)
P
1

There is a powerful and very useful XS module called Want developed by Robin Houston. It extends what the core perl function wantarray() offers and enables you to find out if your method for example was called in an object context.

$object->do_something->some_more;

Here in do_something you could write before returning:

if( want('OBJECT') )
{
    return( $object );
}
else
{
    return; # return undef();
}
Parochialism answered 14/5, 2021 at 6:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.