Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can anybody please explain (my $self = shift) in Perl

I'm having a really hard time understanding the intersection of OO Perl and my $self = shift; The documentation on these individual elements is great, but none of them that I've found touch on how they work together.

I've been using Moose to make modules with attributes, and of course, it's useful to reference a module's attribute within said module. I've been told over and over again to use my $self = shift; within a subroutine to assign the module's attributes to that variable. This makes sense and works, but when I'm also passing arguments to the subroutine, this process clearly takes the first element of the @ARGV array and assigns it to $self as well.

Can someone offer an explanation of how I can use shift to gain internal access to a module's attributes, while also passing in arguments in the @ARGV array?

like image 290
Alex H Hadik Avatar asked Oct 03 '13 14:10

Alex H Hadik


People also ask

What does shift mean in Perl?

shift() function in Perl returns the first value in an array, removing it and shifting the elements of the array list to the left by one. Shift operation removes the value like pop but is taken from the start of the array instead of the end as in pop.

What is the use of shift @_ in Perl subroutine?

Description. This function returns the first value in an array, deleting it and shifting the elements of the array list to the left by one. If ARRAY is not specified, shifts the @_ array within a subroutine, or @ARGV otherwise.

What does self mean in Perl?

Examples - an object-method A regular or object-method: Methods always get the current object as the first parameter, therefore we need a way to assign that to a variable that is easily recognizable. That's what $self is.

What does @_ mean in Perl?

Using the Parameter Array (@_) Perl lets you pass any number of parameters to a function. The function decides which parameters to use and in what order.


2 Answers

First off, a subroutine isn't passed the @ARGV array. Rather all the parameters passed to a subroutine are flattened into a single list represented by @_ inside the subroutine. The @ARGV array is available at the top-level of your script, containing the command line arguments passed to you script.

Now, in Perl, when you call a method on an object, the object is implicitly passed as a parameter to the method.

If you ignore inheritance,

 $obj->doCoolStuff($a, $b); 

is equivalent to

 doCoolStuff($obj, $a, $b); 

Which means the contents of @_ in the method doCoolStuff would be: @_ = ($obj, $a, $b);

Now, the shift builtin function, without any parameters, shifts an element out of the default array variable @_. In this case, that would be $obj.

So when you do $self = shift, you are effectively saying $self = $obj.

I also hope this explains how to pass other parameters to a method via the -> notation. Continuing the example I've stated above, this would be like:

sub doCoolStuff {   # Remember @_ = ($obj, $a, $b)   my $self = shift;   my ($a, $b) = @_; 

Additionally, while Moose is a great object layer for Perl, it doesn't take away from the requirement that you need to initialize the $self yourself in each method. Always remember this. While language like C++ and Java initialize the object reference this implicitly, in Perl you need to do it explicitly for every method you write.

like image 117
Nikhil Avatar answered Sep 20 '22 02:09

Nikhil


In top level-code, shift() is short for shift(@ARGV). @ARGV contains the command-line arguments.

In a sub, shift() is short for shift(@_). @_ contains the sub's arguments.

So my $self = shift; is grabbing the sub's first argument. When calling a method, the invocant (what's left of the ->) is passed as the first parameter. In other words,

$o->method(@a)

is similar to

my $sub = $o->can('method');
$sub->($o, @a);

In that example, my $self = shift; will assign $o to $self.

like image 21
ikegami Avatar answered Sep 20 '22 02:09

ikegami