21

In C++ I would do something like this:

void some_func(const char *str, ...);
some_func("hi %s u r %d", "n00b", 420);

In PHP I would do like this:

function some_func()
{
    $args = func_get_args();
}
some_func($holy, $moly, $guacomole);

How do I do that in Perl?

sub wut {
    # What goes here?
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JOSHUA
  • 223
  • 1
  • 2
  • 4
  • There ***must*** be a canonical question from 2008 somewhere for this (*this* question may be the top search engine hit). An even younger one is *[Perl subroutine arguments](https://stackoverflow.com/questions/19234209/)*. Related (not duplicate): *[Perl Subroutine Prototyping -- The correct way to do it](https://stackoverflow.com/questions/8128918/)* – Peter Mortensen Oct 06 '22 at 10:41
  • Related (but that is for the command-line): *[How can I pass command-line arguments to a Perl program?](https://stackoverflow.com/questions/361752/how-can-i-pass-command-line-arguments-to-a-perl-program)* – Peter Mortensen Oct 06 '22 at 10:51

1 Answers1

34

You would do:

sub wut {
  my @args = @_;
  ...
}

Perl automatically populates the special @_ variable when you call a function. You can access it in multiple ways:

  • directly, by simply using @_ or individual elements within it as $_[0], $_[1], and so on
  • by assigning it to another array, as shown above
  • by assigning it to a list of scalars (or possibly a hash, or another array, or combinations thereof):

    sub wut {
      my ( $arg1, $arg2, $arg3, @others ) = @_;
      ...
    }

Note that in this form you need to put the array @others at the end, because if you put it in earlier, it'll slurp up all of the elements of @_. In other words, this won't work:

sub wut {
  my ( $arg1, @others, $arg2 ) = @_;
  ...
}

You can also use shift to pull values off of @_:

sub wut {
  my $arg1 = shift;
  my $arg2 = shift;
  my @others = @_;
  ...
}

Note that shift will automatically work on @_ if you don't supply it with an argument.

Edit: You can also use named arguments by using a hash or a hash reference. For example, if you called wut() like:

wut($arg1, { option1 => 'hello', option2 => 'goodbye' });

...you could then do something like:

sub wut {
  my $arg1 = shift;
  my $opts = shift;
  my $option1 = $opts->{option1} || "default";
  my $option2 = $opts->{option2} || "default2";
  ...
}

This would be a good way to introduce named parameters into your functions, so that you can add parameters later and you don't have to worry about the order in which they're passed.

phuclv
  • 37,963
  • 15
  • 156
  • 475
CanSpice
  • 34,814
  • 10
  • 72
  • 86
  • 3
    If you have *many, many* args, you may want to avoid copying them: `sub wut { for my $arg (@_) { blah blah blah } }`. Be careful with this, though, because each element in `@_` is an alias to the original argument and you can **change your calling variables**. – daotoad Apr 19 '11 at 16:01
  • 1
    You might also want to mention doing named parameters via `my %args = @_;` – friedo Apr 19 '11 at 18:52