Reputation: 335
Can someone tell me what
shift if(@_)
means in perl?
and so what would
sub id {
my $self = shift;
$self->{ID} = shift if @_;
return $self->{ID};
}
mean? Thanks.
Upvotes: 2
Views: 1486
Reputation: 35198
That is a handrolled accessor/mutator for an object
print $obj->id; # Accessor form
$obj->id(NEW_VAL); # Mutator form
It is functionally equivalent to:
sub id {
my $self = shift;
if (@_) { # If called with additional parameters, set the value:
$self->{ID} = shift(@_);
}
return $self->{ID};
}
Upvotes: 5
Reputation: 781068
There is no shift if @_
in your example -- if
applies to the entire statement, not just the shift
expression (because if
has very low precedence in the expression hierarchy).
$self->{ID} = shift if @_;
is short for:
if (@_) {
$self->{ID} = shift;
}
shift
with no argument pulls the first element off the @_
list, so this sets $self->{ID}
to the first argument of the subroutine if there are any arguments.
The general rule regarding postfix use of if
is that:
<expression1> if <expression2>;
is short for:
if (<expression2>) {
<expression1>;
}
Upvotes: 0
Reputation: 3382
shift if(@_)
says "if @_
has any elements (i.e., evaluating @_
in scalar context is greater than zero), shift off the first element of the default argument (inside a subroutine, this is @_
)".
The sub is a standard pre-Moose setter/getter method. Commented to explain:
sub id {
my $self = shift; # @_ is the implied argument of shift.
# Since method calls prepend the object reference to @_,
# this grabs the object itself, assumed by the later code
# to be a hash reference.
$self->{ID} = shift if @_;
# If there's still anything left in @_ (`if @_`), get
# the first item and stash it under the ID key in
# the hash referenced by $self (note that if there is more
# than one item, we'll only stash the first one).
return $self->{ID}; # Return whatever the value of the item stored under ID in the
# hash referenced by $self is. This will be the value just
# assigned if the method was called with a scalar argument,
# or whatever value was there before if no argument was passed.
# This will be undef if nothing was ever stored under the ID key.
}
Invocation would be
$obj->id();
to fetch, and
$obj->id($value);
to set.
A standard pre-Moose constructor would create an anonymous hash reference, bless
it to turn it into an object (connecting a package implementing the class's behavior to that reference), and return it:
sub new {
my($class) = @_; # List assignment to a list; puts first item in one into the first
# item in another; a call to a class method prepends the package
# (class) name to @_, so this gets us the name of the class this
# object is to belong to.
my $self = {}; # Gets a new anonymous hash reference into $self.
bless $self, $class; # Connects the hash reference to the package, so that method calls
# made on this object are directed to this class (and its @ISA
# ancestors) to find the sub to be called to implement the method.
return $self; # Hands the object back to the caller.
}
Upvotes: 1
Reputation: 50647
In a sub, shift
without argument uses @_
array.
So
$self->{ID} = shift if @_;
is equal to
$self->{ID} = shift(@_) if @_;
(remove leftmost element from @_
array and assign it to $self->{ID}
)
Upvotes: 4
Reputation: 4311
shift
takes the first element off an array and returns it. If no array is given, it operates on @_
, the array containing function arguments. The if @_
statement modifier causes the preceding statement to be executed only if @_
has at least one element.
In your example, $self->{ID} = shift @_ if @_;
means "If there is a function argument, assign it to $self->{ID}
.
Upvotes: 1