in reply to Function Prototype Context Conversion

why can't @foo be treated as an implicit list for DWIM purposes?

What DWIM purposes? You want a scalar as first argument to foo, so Perl is doing exactly that, evaluating the first argument of foo in scalar context.

This is a known issue with prototypes, and one of the reasons prototypes in Perl are often thought of a "a failed experiment". If you prototype foo as taking one scalar as argument, and you want foo @foo to succeed, what's the point of using a scalar prototype? Any argument is going to be scalar anyway. The only "use" could be to fail if @foo != 1. But that means you cannot do prototype checking at compile time, but have to defer it to runtime. But the neat thing about prototypes is compile time checking.

Abigail

Replies are listed 'Best First'.
Re^2: Function Prototype Context Conversion
by tadman (Prior) on Jun 13, 2002 at 13:02 UTC
    Well, it is clear the way Perl operates, but that is merely one interpretation of how it could be done. What burned me was that I do this sort of thing all the time with regular, unprototyped functions. It just goes to show you never can be too careful when programming.

    I suppose the unfortunate thing is that Perl doesn't differentiate between "scalars" and scalar-like things in the same way that it differentiates between "arrays" and lists. Using prototypes to merely mandate how many paramters should be passed to a function doesn't seem to be the best way to go about it anyway.

    Maybe I'm too shell oriented, where I expect things to be automatically expanded before being processed. Meaning, something like this:
    % /bin/foo foo_a foo_b foo_c
    Where there you have three distinct parameters being passed to /bin/foo and it will complain if it doesn't have, let's say, at least two.
    % /bin/foo foo_?
    Now here there's technically one element being passed to the shell, which expands it into a list before being proccesed. Same thing goes if you had a variable $FOO which was 'foo_a foo_b foo_c' of course.

    In summary, I suppose the only way to do this reliably is something like this:
    sub foo { croak "foo() only takes one argument" if (@_ > 1); print "$_[0]\n"; }
    But you're not likely to see that put into general practice any time soon.

    I understand that Perl and the shell are two different things, so this whole thing is really just one big assumption that I made.

    The only reason I would even think of Perl functions and command-line programs as the same thing is the whole laissez-faire way of handling arguments that Perl has. They're not typed (normally), they're not named, heck, they're not even declared unless you use prototypes! In that regard, I was figuring that @_ would operate along the same lines as @ARGV since the two are so alike in that respect.
      It all has to do with compile time and run time. Prototyping has a compile time effect, while the number of elements in an array isn't known till run time. I fail the see the relevancy of your shell example. Prototyping changes the way perl parses Perl. Expecting no changes when using prototypes is a mistake (if you don't want changes, don't change your code! ;-)).

      Abigail