Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused about whether I'm passing a scalar or an array to a subroutine in perl?

I've just started learning perl and I am am confused by this exercise (from Learning Perl Chapter 4).

At the beginning of the greet() subroutine, I am trying to assign the argument $_ to my $name (my $name = $_) variable but it doesn't work. The book says to use "my name = shift;" but I don't understand why. shift is used to remove a value from an array and my argument is not an array as far as I can tell, it's a string inside a scalar!

Could anyone explain what I'm not understanding?

Thanks! Here is the entirety of the code.

use 5.012;
use warnings;
use utf8;

sub greet {
   my $name = $_;
   state $last_person ;
   if (defined $last_person ) {
          print "Hi $name! $last_person is also here!\n";

   } else {
          print "Hi $name! You are the first one here!\n";
   }
   $last_person = $name;
}

greet( 'Fred' );
greet( 'Barney' );
greet( 'Wilma' );
greet( 'Betty' );
like image 266
gozu Avatar asked Dec 09 '22 23:12

gozu


1 Answers

In chapter 4 of Learning Perl (6th edition) there's a section called Arguments. There it states the following:

This means that the first subroutine parameter is in $_[0], the second one is stored in $_[1], and so on. But - and here's an important note - these variables have nothing whatsoever to do with the $_ variable, any more than $dino[3] (an element of the @dino array) has to do with $dino (a completely distinct scalar variable). It's just that the parameter list must be in some array variable for your subroutine to use it, and Perl uses the @_ for this purpose.

(Learning Perl, 6th Edition, Chapter 4)

So you're probably mistaken in using $_, when you should either be using my $name = $_[0];, or my $name = shift @_;. As a convenience, when you're inside of a subroutine, shift defaults to shifting off of @_ if you provide no explicit argument, so the common idiom is to say my $name = shift;.

For those in need of another resource, perldoc perlintro also has a good (and appropriately brief) explanation of passing parameters to subroutines and accessing them via @_ or shift.

Here's a brief snippet from perlintro:

What's that shift? Well, the arguments to a subroutine are available to us as a special array called @_ (see perlvar for more on that). The default argument to the shift function just happens to be @_ . So my $logmessage = shift; shifts the first item off the list of arguments and assigns it to $logmessage.

like image 173
DavidO Avatar answered Apr 12 '23 23:04

DavidO