Den
Den

Reputation: 183

How do I assign an element of @ARGV to a $variable, then print it?

It has been frequently asked in various ways, however, I am going to ask again because I do not fully comprehend the application of @ARGV and because I have not found an answer to this issue (or, more likely, I do not understand the answers and solutions already provided).

The question is, why is nothing being read from the command-line? Also, how do I decrypt the error message,

Use of uninitialised value $name in concatenation (.) or string at ... ?

I understand that @ARGV is an array that stores command-line arguments (files). I also understand that it can be manipulated like any other array (bearing in mind index $ARGV[0] is not the same as the command-line feature of filename variable, $0). I understand that when in a while-loop, the diamond operator will automatically shift the first element of @ARGV as $ARGV[ ], having read a line at input.

What I do not understand is how to assign an element of @ARGV to a scalar variable and then print the datum. For example (code concept taken from Learning Perl),

my $name = shift @ARGV;

while (<>) {
    print “The input was $name found at the start of $_\n”;
    exit;
}

As the code stands, $name’s output is blank; were I to omit shift(), $name would output 0, as I believe it should, being in scalar context, but it does not answer the question of why input from the command-line is nor being accepted. Your insights will be appreciated.

Thank you.

Upvotes: 3

Views: 892

Answers (1)

ikegami
ikegami

Reputation: 385915

my $name = shift @ARGV; does indeed assign the program's first argument. If you get Use of uninitialised value $name in concatenation (.) or string at ..., it's because you didn't provide any arguments to your program.

$ perl -we'my $name = shift(@ARGV); print "My name is $name.\n"'
Use of uninitialized value $name in concatenation (.) or string at -e line 1.
My name is .

$ perl -we'my $name = shift(@ARGV); print "My name is $name.\n"' ikegami
My name is ikegami.

There's absolutely no problem with using <> afterwards.

$ cat foo
foo1
foo2

$ cat bar
bar1
bar2

$ perl -we'
   print "(\@ARGV is now @ARGV)\n";
   my $prefix = shift(@ARGV);

   print "(\@ARGV is now @ARGV)\n";
   while (<>) {
      print "$prefix$_";
      print "(\@ARGV is now @ARGV)\n";
   }
' '>>>' foo bar
(@ARGV is now >>> foo bar)
(@ARGV is now foo bar)
>>>foo1
(@ARGV is now bar)
>>>foo2
(@ARGV is now bar)
>>>bar1
(@ARGV is now )
>>>bar2
(@ARGV is now )

Upvotes: 5

Related Questions