Bad_ptr
Bad_ptr

Reputation: 603

Perl. Access caller arguments (like shift, pop, etc)

In perl there is the shift function that can act on the @_(arguments of a function in scope of which it was called) if no arguments supplied.

Can I write a custom function in perl with the same behavior(some kind of my_shift)?

I tried this:

use Data::Dumper;

sub get_caller_args (;$) {
  my $n = shift;
  $n = defined $n? $n:1;
  my $ret;
  package DB {
    my($t,$t1) = caller($n);
  };
  $ret = \@DB::args;
  return $ret;
}

sub test ($@) {
  my $self = shift;
  print "Self: $self.\n";
  print Dumper(get_caller_args()), "\n";
}

It kind of works, but

test(1,2,3)

outputs:

Self: 1.
$VAR1 = [
          1,
          2,
          3
        ];

So it doesn't see changes made by shift (though it can see changes made by pop).

But I want it to act like this:

sub test {
  my $self = shift;
  print my_function;
}

Here the my_function called without arguments must act on the @_, in this case on the rest of the arguments, without the first as it was shifted(actually I need only to read arguments, not to do changes).

Upvotes: 2

Views: 298

Answers (1)

Bad_ptr
Bad_ptr

Reputation: 603

Ok, I found an answer:

use feature 'say';

sub my_shift {
 say "Arguments before shift: ", @_;
 shift;
 say "Arguments after shift: ", @_;
}

sub test {
 say "Arguments before my_shift: ", @_;
 &my_shift;
 say "Arguments after my_shift: ", @_;
}

The 'tricky' thing here is to call the my_shift with an ampersand(&) before the function name -- then the function gets arguments of the calling function as it's input.

However I'll not accept this self-answer, because I'm still interested if it possible to do this without that ampersand magic and what if i need to pass other arguments and access the calling function arguments at the same time, etc.

Upvotes: 1

Related Questions