3 ms·
When he explains how Perl handles an array passed as an argument to a function: my @list = ('b', 'c'); test('a', @list, 'd'); Which ends up flatting t
by ceronman 12y ago
When he explains how Perl handles an array passed as an argument to a function:
my @list = ('b', 'c');
test('a', @list, 'd');
Which ends up flatting the @list array into the argument list and printing 'a', 'b', 'c', most Perl programmers defend the language saying that the author just doesn't understand Perl, and that's how things are done in the language since forever. The response is basically a RTFM.
If you really wanted to send the whole list as single argument to the function, you should have sent an array reference, like this:
test('a', \@list, 'd');
Perl programmers say that if you took a minute to understand the language, you should have known this. However, what they don't realize is that Perl gives you ambiguous hints about this all the time. For example, the built in push function doesn't seem to follow this logic:
push(@list, "item2", "item2");
This function knows perfectly that the list is a single argument and the other ones are the items to push into the list. You don't have to pass a reference to the array to make it work.
The push function works like this because it uses an obscure feature called function prototypes. Which is rarely mentioned in any tutorial.
When a Perl newbie sees the push function, it's more than reasonable to think that passing arrays as function arguments will work as in any other language. When they find what really happens, it can be very frustrating, specially because Perl won't give you any error whatsoever. This is one of the reasons why Perl is so difficult to learn.
- pwr22 12y agoGranted, and most people think prototypes are evil for similar reasons. Perl doesn't have the same design goals as something like Python, it will accept inconsistencies and complexity if they're deemed useful I personally like this, assuming the complexities aren't too great and the documentation is good but to each their own Edit: In Perl land it is a bad idea to treat built ins as being identical to subs, and this was taught to me by the books I learnt from. The rub of this is that it is bad to generalise from stuff like print, push etc
- laumars 12y agoThat's a fair point and it was certainly true that this tripped me up when I was learning Perl too. But now I've wrapped my head around the concept, I love it.
- collyw 12y agoAs an ex Perl guy (well I still use it sometimes), I find append and extend an endless source of confusion in Python. Especially as strings do the opposite of what I expect, and get treated as character arrays with extend (or was it append). I like the way that in Perl you have to explicitly reference the array, as this leaves no ambiguity about what is happening. I guess its just what I am used to.
- haypo 12y ago"As an ex Perl guy (well I still use it sometimes), I find append and extend an endless source of confusion in Python. Especially as strings do the opposite of what I expect, and get treated as character arrays with extend (or was it append)." list.extend(data) works like "for item in data: list.append(item)" strings (str) do not behave differently than a list or a set. Try .append() on a list or a set, you get the same behaviour. Maybe your confusion comes from the fact that strings are immutable in Python, and a list is not a string. You may like bytearray() in Python 2 (bytearray.append raises an error if you pass a string longer than 1 character), but there is not mutable type for Unicode strings.
- collyw 12y agoYes but I would expect my strings to behave as a scalar variable, not a list or set. I prefer the Perl way of having one function push, and specifically referencing the list if you want it stored that way. That has caused me far less confusion in Perl than the Python way of doing things.
- maxlybbert 12y ago> The push function works like this because it uses an obscure feature called function prototypes. Which is rarely mentioned in any tutorial. I think the push function behaves differently mainly because it's a builtin. It is possible to use function prototypes to make your functions act like builtins, but the reason that isn't mentioned in tutorials is that most Perl programmers are less than impressed with prototypes. Except when passing code blocks as subroutine references, since prototypes allow you to omit the comma after the code block.
- CoconutPilot 12y agoI think push is better understood if you realize its an operator. At a higher level what is happening is you are adding "item2" (and another "item2") to the array @list. ie @list += ("item2", "item2")