--- Michael Fowler <[EMAIL PROTECTED]> wrote:
> You could also make your own print function that appends to the variable of
> your choice:
> 
>     sub append_and_print (\$@) {
>         my($var_ref, @stuff_to_print) = @_;
> 
>         $$var_ref  = '' unless defined($$var_ref);
>         my $sep = defined($,) ? $, : "";
>         $$var_ref .= join($sep, @stuff_to_print);
> 
>         print @stuff_to_print;
>     }
> 
>     append_and_print($stuff_to_print, "hi");

Michael,

I'd be very careful about recommending something like the above to someone who's not 
terribly
familiar with Perl.  It's going to bite them and bite them badly.

I don't particularly care for prototypes 
(http://www.perl.com/pub/a/language/misc/fmproto.html),
so I rarely use them (some many have seen the "try/catch" snippet I posted the other 
day (and
stole from someone else). That used prototypes, so just pretend I didn't mention it :)

One of the problems with prototypes is that they are not prototypes, at least not in 
the sense
that other programming languages use them.  Instead, they allow us, amongt other 
things, to force
function arguments into a particular context.  In your example, the first argument 
*doesn't* have
to have a scalar value.  If you pass an array or hash reference as the first argument, 
it is
silently coerced into scalar context.  Run the following snippet:

    use strict;
    use warnings;
    sub append_and_print(\$@);

    my $stuff_to_print = ["Foo"];

    append_and_print $stuff_to_print, "hi", " there\n";

    print $stuff_to_print;

    sub append_and_print (\$@) {
        my($var_ref, @stuff_to_print) = @_;
        $$var_ref  = '' unless defined($$var_ref);
        my $sep = defined($,) ? $, : "";
        $$var_ref .= join($sep, @stuff_to_print);
        
        print @stuff_to_print;
    }

It runs fine and you don't get any warnings, but the output may not be what one 
expects:

    hi there
    ARRAY(0x1a7f018)hi there

That's because the first argument is an array ref that gets stringified!  In your 
example, that's
likely to be caught quickly because this is stuff to be printed and therefore will 
have an
immediate visual response for the programmer.  However, if this is some obscure 
subroutine that's
munging internal data, it will silently corrupt that data and this could be a nasty 
bug to track
down.

There is one other problem I have with it.  Many times, new Perl programmers ask why 
the following
doesn't work:

    while (<>) {
        my $line = chomp;
        # do more stuff here
    }

That's because chomp acts directly on the variable in question (in this case, $_) and 
returns the
number of characters that it chomped.  There are a few functions in Perl that act 
directly on the
variable, but these cause much confusion.  In your routine above, I would return the 
new data,
rather than directly changing the first argument passed to it.

Cheers,
Curtis "Ovid" Poe

=====
Senior Programmer
Onsite! Technology (http://www.onsitetech.com/)
"Ovid" on http://www.perlmonks.org/

__________________________________________________
Do You Yahoo!?
Listen to your Yahoo! Mail messages from any phone.
http://phone.yahoo.com

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to