perl

Positional parameters usage example


This question is specifically for Perl 5 instead of Perl 6.

The printf function in Perl allows for positional parameters in its format string, providing a way to reorder or reuse arguments. Positional parameters are specified using the %n$ syntax within the format string, where n is the index of the argument to be used, starting from 1.

For example:

$ perl -e 'printf "%2\$s %1\$d, %2\$s %1\$d\n", 10, "hello";'
hello 10, hello 10

However, I've stared at my following code many many times, but still am unable to figure out what's going wrong:

$ perl -e 'my $i, $j = 10, 20; printf "i = %1\$d, j = %2\$d, i again = %1\$d, j again = %2\$d\n", $i, $j;'
i = 0, j = 10, i again = 0, j again = 10

$ perl -v
This is perl 5, version 36, subversion 0 (v5.36.0) built for x86_64-linux-gnu-thread-multi

$ apt-cache policy perl
perl:
  Installed: 5.36.0-7

Solution

  • It's a precedence issue.


    You have the following:

    my $i, $j = 10, 20;
    

    It's equivalent to the following:

    ( my $i ), ( $j = 10 ), 20;
    

    It could also be written as follows:

    my $i;
    $j = 10;
    20;
    

    You were going for the following:

    my ( $i, $j ) = ( 10, 20 );
    

    I'd write it as follows:

    my $i = 10; my $j = 20;
    

    Enabling string and/or warnings (as done using use v5.36 below) would have helped you spot the error.

    $ perl -Mv5.36 -e'
       my $i, $j = 10, 20;
       printf "%2\$s %1\$d, %2\$s %1\$d\n", 10, "hello";
    '
    Parentheses missing around "my" list at -e line 2.
    Global symbol "$j" requires explicit package name (did you forget to declare "my $j"?) at -e line 2.
    Execution of -e aborted due to compilation errors.
    
    $ perl -Mv5.36 -e'
       my ( $i, $j ) = ( 10, 20 );
       printf "%2\$s %1\$d, %2\$s %1\$d\n", 10, "hello";
    '
    hello 10, hello 10
    
    $ perl -Mv5.36 -e'
       my $i = 10;
       my $j = 20;
       printf "%2\$s %1\$d, %2\$s %1\$d\n", 10, "hello";
    '
    hello 10, hello 10