Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

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:
$bag->contents();
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!

Comment on Difference between my $self = shift and my ($self) = @_
Select or Download Code
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?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1019959]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (8)
As of 2014-08-20 16:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (119 votes), past polls