http://qs1969.pair.com?node_id=444880


in reply to Re: Turning foreach into map?
in thread Turning foreach into map?

Wow! This will take me a while to properly digest, but my first question is, why is:

my ($url, @list) = @_;

now:

my $sub = shift;

I have seen loads of people do this. Even merlyn now suggests it in another thread that I can't remember, when it's his book I learnt it from ;-)

Walking the road to enlightenment... I found a penguin and a camel on the way.....
Fancy a yourname@perl.me.uk? Just ask!!!

Replies are listed 'Best First'.
Re^3: Turning foreach into map?
by polettix (Vicar) on Apr 05, 2005 at 09:55 UTC
    Arguments are passed "by reference" in perl subs, allowing in-place modification. So, you can do things like the following:
    sub double_it { $_[0] *= 2 } my $x = 1; print "\$x is $x\n"; double_it($x); print "\$x is now $x\n";
    and have
    $x is 1 $x is now 2
    When you use:
    my ($url, @list) = @_;
    you're creating copies of the input arguments, so when you modify them you don't have any side-effect outside the function. In your code, these copies are inefficient and not needed, because the code is quite simple and you don't perform in-place modifications. So, you simply grab the first parameter, and use the resulting @_ instead of @list, saving space and time:
    sub links { my $url = shift; # This removes the first element of @_ map { "$url/$_" } @_; # You don't need return :) }
    I also find this construct useful when porting functions into classes. When you transform a plain function in a class/object method, the first parameter that's passed is the class name/reference to object, so if you have a function:
    sub some_func { # ... some stuff? my ($foo, $bar, $baz) = @_; # ... other stuff }
    you can transform it at once:
    sub some_func { my $self = shift; # Maybe do some checks with $self first? # ... some stuff? my ($foo, $bar, $baz) = @_; # ... other stuff }
    in a much cut-and-paste fashion. But do check the code!

    Flavio (perl -e "print(scalar(reverse('ti.xittelop@oivalf')))")

    Don't fool yourself.
Re^3: Turning foreach into map?
by tlm (Prior) on Apr 05, 2005 at 09:30 UTC

    They're both correct; it all depends on what you want to do. In the example I gave, I was re-implementing Perl's built-in map, not your links function. What my code does is to pluck out the first argument from the arguments list, and later process the remaining arguments directly from the arguments list.

    the lowliest monk