passing argument to a subroutine

C

ccc31807

If you call a sub like this:
some_sub($arg);

You can copy the argument like this:
sub some_sub
{
my $arg_copy = shift;
...
}

However, I've noticed that some BIG NAMES in the Perl community do
this:
my ($arg_copy) = @_;

Is there any real difference between the two? If so, what is the
difference?

CC.
 
J

Jürgen Exner

ccc31807 said:
If you call a sub like this:
some_sub($arg);

You can copy the argument like this:
sub some_sub
{
my $arg_copy = shift;
...
}

However, I've noticed that some BIG NAMES in the Perl community do
this:
my ($arg_copy) = @_;

Is there any real difference between the two? If so, what is the
difference?

The first version consumes the first argument, i.e. it is gone from @_
after the shift.
The second version preserves the first argument, i.e. it is still
present in @_ after the assignment.

jue
 
W

Willem

ccc31807 wrote:
) If you call a sub like this:
) some_sub($arg);
)
) You can copy the argument like this:
) sub some_sub
) {
) my $arg_copy = shift;
) ...
) }
)
) However, I've noticed that some BIG NAMES in the Perl community do
) this:
) my ($arg_copy) = @_;
)
) Is there any real difference between the two? If so, what is the
) difference?

Technically speaking, the second form preserves the @_ array.

But I think the main reason is for consistency. Think about
the two above conventions in the case of, say, a five-arg function.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
R

Randal L. Schwartz

ccc31807> Is there any real difference between the two? If so, what is the
ccc31807> difference?

I use:

my $self = shift;

or

my $class = shift;

on instance and class methods, simply because the first parameter
is special. For the remaining arguments, I'm all over the map. :)

print "Just another Perl hacker,"; # the original
 
J

Jochen Lehmeier

ccc31807> Is there any real difference between the two? If so, what is
the
ccc31807> difference?

The difference is that "shift" is changing the array, while the assignment
does not.

So, if you're pedantic, you might ask why all those bytes have to be
shifted around just to get at the first argument.

I prefer "my ($a,$b,$c)=@_;" as well, because it does exactly what is
meant without any side effects or superflous shuffling of RAM. Also, it
looks *just* like the argument declarations in other languages ("void
xyz(int a,int b,int c)"), so is very clear to understand.

In class methods, I use

sub fn
{
my $self=shift @_;
my ($args...)=@_;

for no particular technical reason except that by doing this, after the
shift, @_ looks just like what the caller saw.
 
W

Willem

Jochen Lehmeier wrote:
) In class methods, I use
)
) sub fn
) {
) my $self=shift @_;
) my ($args...)=@_;
)
) for no particular technical reason except that by doing this, after the
) shift, @_ looks just like what the caller saw.

And, additionally, you can do $self->foobar(@_) which (I think ?) will
find the method in a child object which inherited your package.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
D

Dr.Ruud

Willem said:
Jochen Lehmeier wrote:
) In class methods, I use
)
) sub fn
) {
) my $self=shift @_;
) my ($args...)=@_;
)
) for no particular technical reason except that by doing this, after the
) shift, @_ looks just like what the caller saw.

And, additionally, you can do $self->foobar(@_) which (I think ?) will
find the method in a child object which inherited your package.

Variant:

shift->foobar(@_)
 
J

Jochen Lehmeier

All which bytes? shift on @_ is special-cased, since it's so common, to
do nothing more than adjust a pointer.

I love perl.

Performance aside, let me rephrase my answer:

"So, if you're pedantic, you might ask why the @_ array should be
modified just to get at the first argument."

Which is be the reason why I (and possibly others) use "my (...)=@_"
instead of "my $x=shift @_".
 
J

Jürgen Exner

Jochen Lehmeier said:
The difference is that "shift" is changing the array, while the assignment
does not.

So, if you're pedantic, you might ask why all those bytes have to be
shifted around just to get at the first argument.

What bytes do you mean when talking about "bytes have to be shifted
around"?
I prefer "my ($a,$b,$c)=@_;" as well, because it does exactly what is
meant without any side effects or superflous shuffling of RAM. Also, it

What shuffling of RAM are you talking about?

jue
 
J

Jürgen Exner

Jochen Lehmeier said:
"So, if you're pedantic, you might ask why the @_ array should be
modified just to get at the first argument."

A valid question. And depending upon your style an answer may be:

Because I got the first argument, I dealt with it, and now I want to
move on to the next argument.

This is particularly useful when you are dealing with a list of unknown
length, let's say an arbitrary number of filenames and each file needs
to be treated the same. Then just loop over shift(@_) until @_ is empty.
Which is be the reason why I (and possibly others) use "my (...)=@_"
instead of "my $x=shift @_".

Which is IMO a nice way to assign a meaningful name to each argument for
a known number of arguments.

jue
 
S

sln

Quoth "Jochen Lehmeier said:
The difference is that "shift" is changing the array, while the assignment
does not.

So, if you're pedantic, you might ask why all those bytes have to be
shifted around just to get at the first argument.

All which bytes? shift on @_ is special-cased, since it's so common, to
do nothing more than adjust a pointer.
[snip]

Ben

Hey Ben. I'm not really sure but since Perl doesn't seem to give anything
back, adjusting the pointer would seem all it does on "shift,pop" .. and
"unshift,push,splice" if there is room to expand at the boundries without
needing more memory.

For example unshift grows down, push grows up, shift shrinks up, pop shrinks
down via head/tail pointers.

Of course, this is if internally, a Perl array is really an array of pointers
to structures with pointers to data grabbed from a free pool that is managed by Perl.
Its hard to fathom it could be done any other way with typless data (elements) but
I'm sure there is optimizations or some hybrid methods being used.

And within the array's current block of pointers, anything that can be moved
around without re-allocation is prefferable, say from using splice.

I don't know for sure, I'm sure there is some paper on implementing a typeless
language, but if shift @array did a re-alloc then move every time, or just a
move, then performance would really fall off.

-sln
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top