antjock has asked for the wisdom of the Perl Monks concerning the following question:

So yesterday I posted this function:

sub clean_data { my @fields = map { s/\s+/ /g; s/\|/-/g; s/^\s//; s/\s$//; } @_; }

or something very similar. It's much cleaner now, thanks to feedback from other monks. Anyway it's being called as such:

foreach my $field ( @fieldnames ) { my $value = $q->param($field); clean_data( $value ); push( @rec, $value ); }

What I don't understand is, the sub doesn't have a return statement, so why does it work? Where is it getting a return value from? @fields should be local to the sub, and well, I don't see anything else that would indicate a return value. Why does this function return something?

I'm going to look at the perlfunc page again (I still don't understand exactly what map {...} is doing), in the meantime if somebody can help make this make sense, that would be fabulous.

cheers

Replies are listed 'Best First'.
(tye)Re: Global, Local, what the..?
by tye (Sage) on Dec 15, 2000 at 02:36 UTC

    I don't think I understand the previous answers.

    To me, the crux is that when you pass scalars to a subroutine, @_ actually contains aliases to the scalars themselves so that modifying $_[0] directly actually modifies the caller's scalar. Similarly, modifying $_ in a map, for, or foreach actually modifies the elements of the list that you are looping over.

    So $_ is an alias for $_[0] which is an alias for the caller's $value and $value gets modified in-place and the return value doesn't matter because you call the function in a void context and the return value is thrown away.

            - tye (but my friends call me "Tye")
      tye: I think you're confusion stems from our bad examples :)

      You are right in your assessment, but the code below should clarify this. Because we're localizing arguments to the sub, you can see how it returns the last evaluated statement. The code below will print "his hat" (without the quotes):

      use strict; my @list = qw( this that foo bar ); print join ' ', mungeIt( @list ); sub mungeIt { my @localList = @_; my @stuff = map { s/th/h/ ? $_ : () } @localList; }

      Cheers,
      Ovid

      Update: Oh! I misunderstood tye's question, but clarified the answer. Oh well. All's well that ends well.

      Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

        FYI, I understood that return is optional and that a subroutine will return the value of the last statement executed. I just didn't see what that had to do with the original question. I mean, antjock asked several questions about the lack of the return and return values, but I thought the real question was "why does this work?" and I didn't think anyone had answered that... and I wasn't sure I was just missing something (I can be slow some days). (:

                - tye (but my friends call me "Tye")
Re: Global, Local, what the..?
by boo_radley (Parson) on Dec 15, 2000 at 01:18 UTC
    This got me too... a sub will return the last successfully executed statement if there's no explicit return. so if $gne .= "foo"; is the last statement in a sub, it'll return $gne.
(Ovid) Re: Global, Local, what the..?
by Ovid (Cardinal) on Dec 15, 2000 at 01:21 UTC
    Subroutines automatically return the value of the last statement executed. return is often optional.

    map is iterating over the elements in @_ (each element is in $_) and it's substituting as appropriate and passing the changed value to @fields. You can read through this node for some good examples.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Global, Local, what the..?
by lemming (Priest) on Dec 15, 2000 at 01:20 UTC
    You want to look closely at what would be a default condition if nothing is specified. Very similar to just saying "chomp;".
    I'm being vague, but you seem willing to look stuff up.

    Update: This now seems silly that boo answered...