Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Difference between my $self = shift and my ($self) = @_

by Doctrin (Beadle)
on Feb 21, 2013 at 15:13 UTC ( #1019959=perlquestion: print w/replies, xml ) Need Help??
Doctrin has asked for the wisdom of the Perl Monks concerning the following question:

Hello dear Monks! I just wanted to know - is there any REAL difference between following. Say, I do:
And my subroutine is:
sub contents { my $self = shift; # WHAT IF I CALL my ($self) = @_ ? #so something return; }
So, is there any real difference between my $self = shift and my ($self) = @_ Thanks!

Replies are listed 'Best First'.
Re: Difference between my $self = shift and my ($self) = @_
by tobyink (Abbot) on Feb 21, 2013 at 15:20 UTC

    my $self = shift not only defines $self; it also modifies @_ (removing the first array item). The difference is only significant if you intend on using @_ or goto later on in the sub.

    Update: Personally I've recently decided to adopt a coding style where I use shift for the invocant (i.e. $self or $class; but also "conceptual invocants" like $orig in Moose around method modifiers, or $ctx in Catalyst actions) and list assignment for other parameters.

    For example:

    use v5.14; package Person { use Moose; has first_name => (is => 'rw', isa => 'Str'); has last_name => (is => 'rw', isa => 'Str'); sub set_name { my $self = shift; my ($first, $last) = @_; $self->first_name($first); $self->last_name($last); } } package LoudNameChanges { use Moose::Role; around set_name => sub { my $orig = shift; my $self = shift; say "Changing name to: @_"; $self->$orig(@_); }; } package Person::LoudNameChanges { use Moose; extends 'Person'; with 'LoudNameChanges'; } my $bob = Person::LoudNameChanges->new( first_name => 'Robert', last_name => 'Smith', ); $bob->set_name('David', 'Jones'); print $bob->dump;

    For regular subs which are not intended to be called as methods, there is no invocant, so I just use list assignment to unpack all the arguments.

    Why did I decide to adopt this style? I find it works nicely in terms of delegating method calls and so forth where you often need to pass on @_ to other methods and functions, but without passing on the invocant.

    I'm not yet very strict with myself about this style, but hopefully it will become habit soon.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re: Difference between my $self = shift and my ($self) = @_
by topher (Scribe) on Feb 22, 2013 at 06:27 UTC

    As tobyink pointed out, there's no difference in what ends up in $self, but there is a big difference in what's left in @_. If your subroutine isn't expecting arguments, then you can use either method without concern. If you are going to be taking arguments, then you have a choice to make.

    Personally, I'm a big fan of using my $self = shift;. For me, it makes the code cleaner and more mentally straightforward. When using shift, the contents of @_ end up being exactly the same as the arguments I passed to the subroutine. If I use assignment from @_, then I have to constantly account for that $self at the first position, complicating things.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1019959]
Front-paged by Corion
[ambrus]: MLX: if it's a work email, then it's probably not Uncle Sam that matters, but what the account managing server at work thinks your name is. Those can differ. For example, we've had two co-workers with identical real name at one point,
[ambrus]: so one got a stupid suffix in the email account (people have email address based on their real name here usually).

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (14)
As of 2017-01-19 14:03 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (170 votes). Check out past polls.