1

Consider the following basic Perl modulino:

#!/usr/bin/perl -l
package Toto;

__PACKAGE__->run(@ARGV) unless caller();

sub run 
{
  print "@ARGV";
  print "@_";
}

1;

If I run it on the command line, I get:

$ ./Toto.pm 1 2 3
1 2 3
Toto 1 2 3

If I call it from a test:

$ perl -MToto -le 'Toto::run(1,2,3)'    
#first line blank - no ARGV set
1 2 3

In other words, the contents of @_ inside run() changes depending on how the function is called.

Can you explain what is going on?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Philippe A.
  • 2,885
  • 2
  • 28
  • 37

2 Answers2

6

You mean why is "Toto" in @_? Because you are calling it as a class method, so it implicitly passes the class as the first parameter. If you don't want to do that, just do run(@ARGV) unless caller() instead.

ysth
  • 96,171
  • 6
  • 121
  • 214
  • Note that there could be a problem using this call when also using `Getopt::Long::GetOptions`, see [Error “panic: attempt to copy freed scalar” when using Getopt::Long](http://stackoverflow.com/questions/26508899/error-panic-attempt-to-copy-freed-scalar-when-using-getoptlong) – Håkon Hægland Oct 17 '15 at 08:52
  • @HåkonHægland a modulino (also sometimes called a progmod) shouldn't be calling GetOptions in the code that is run when it is used as a module, not a program. But your point is taken: passing globals in general is a bad idea because they can change out from under you. – ysth Oct 18 '15 at 05:09
6
__PACKAGE__->run(@ARGV)

is equivalent to

Toto->run(1,2,3)

This is a class method call. Method calls pass the invocant (the value to which the LHS of the -> evaluated) as the first argument. This differs from

Toto::run(1,2,3)

which is a simple sub call. The following will call run as a sub:

run(@ARGV) unless caller();
ikegami
  • 367,544
  • 15
  • 269
  • 518