Perl: argument passing weirdness

The project I’m currently working on is using Perl scripts. I usually use Python for scripting, but introducing another programming language didn’t seem like a good idea, so I decided to write in Perl.

At first, I was struck with $all @the %decorators which make the code @$difficult $to @#read. Nothing to do about it.

Next thing, a very strange way of reading function arguments. You don’t define them, all the stuff comes in something with a friendly name of @_ which is basically a lump of arguments. It’s your job to make it useful. And it isn’t necessarily easy to do.

Let me give you an example. I’ll start off with a Python function that prints a list to the screen:

a = ['a', 'b', 'c', 'd']
print a

When executed, it prints this:

['a', 'b', 'c', 'd']

A corresponding Perl code looks like this:

@a = ('a', 'b', 'c', 'd');
print "@a∖n";

And produces:

a b c d

As you can see, Python code is a little cleaner, as it doesn’t have @decorators and you don’t need to surround the list with “all the weird stuff∖n” to get the list on the screen in a comprehensive form.

Let’s get back to our code. Let us write a function that takes a list as an argument and prints it. In Python:

def one_list(list_a):
    print list_a

It’s pretty straightforward. We need to write the name of our function, then the arguments (currently just one) in the brackets and then the function body. The same in Perl:

sub one_list {
    my @list_a = @_;
    print "@list_a∖n";
}

What’s strange here is that there is no way to specify the list of arguments that the function accepts. There’s only the lumpy @_ variable which contains a list that the function was called with. You don’t actually know, how was the function called, because it could be one_list(@a) as well as one_list(‘a’, ‘b’, ‘c’, ‘d’) and you can’t tell any difference in the @_. That’s why I call it a lump.

Now that we have a function which accepts a list, let’s try two lists. With Python, we can just extrapolate what we had before. One more thing in the brackets, voila, two lists ready to use.

def two_lists(list_a, list_b):
    print list_a
    print list_b

What about Perl? Can we extrapolate the one_list function? Perhaps I’m spoiled, but usually as I learn how to declare a function with one argument, I don’t need to learn anything more to write a two-argument one. So, I’ve tried this…

sub two_lists {
    my ($list_a, $list_b) = @_;
    print "@list_a∖n";
    print "@list_b∖n";
}

…no error message. And… somehow, @list_a swallowed the second argument, leaving @list_b empty. The two list were just concatenated somewhere on the way and function sees just one list instead of original two. Ouch.

Finally, a friend brought a solution. It looks like this:

sub two_lists {
    my ($list_a_ref, $list_b_ref) = @_;
    my @list_a = @$list_a_ref;
    my @list_b = @$list_b_ref;
    print "@list_a∖n";
    print "@list_b∖n";
}

What it does, is it reads references to the lists and then uses weird @$ syntax to dereference them, er, make them usable.

In this example, there are additional lines of code that wouldn’t have to be there if… well… never mind.

Whatever the reason, instead of simply declaring a list of arguments, I have to wrestle with @_ and references.

Life with Python was so easy… I think you can now understand this picture (even though it was Perl 5 in the examples):

Perl 6

Programming with Perl looks more like something weird, geeky and obscure. It’s easy to write “Hello, world”, but one you want to write any complex data structure, references and inconsistent syntax will quickly get you down. Since data structures are difficult to handle in Perl, you will tend to write complex procedures, making your program difficult to read and understand and therefore difficult to maintain. It’s the opposite to what Eric Raymond says about handling complexity.

Perl seems to be a quintessence of what I don’t like in programming languages.

Author: automatthias

You won't believe what a skeptic I am.

8 thoughts on “Perl: argument passing weirdness”

  1. Well… The decorators, the curly braces, indentation independence are nothing more than synctatic sugar and a matter of convention. (Or maybe the decorators are of more importance. At least they remind me of what I’m looking at when I look at a variable.) I like them, I like C-like syntax. I don’t like the importance of whitespace (vide your Python-emacs coding problem :)). You wouldn’t need the quotes if the variable included a newline (or if you didn’t want a newline at all)… So that’s a non-argument.

    Entirely another story is the argument passing problem and I will tend to agree here. Still, somehow Perl fits my mind so much better for the simple tasks I do. I tried Python and somehow never could get over the basics.

  2. I ran across this post while I was trying to write my own ‘two_lists’ function. Very helpful, but it took me a while to figure out the final piece of the puzzle. You need to call ‘two_lists’ in a special way:

    @list_a;
    @list_b;
    two_lists(\@list_a, \@list_b);

    The ‘\’ passes references to the lists which are dereferenced in ‘two_lists’.

    …obviously…

  3. Hi,

    thanks for the insight. It seems one should always pass lists by reference to avoid the problem. Later I came across a possible explanation of the behaviour here: http://perldoc.perl.org/perldata.html#List-value-constructors

    “LISTs do automatic interpolation of sublists. That is, when a LIST is evaluated, each element of the list is evaluated in list context, and the resulting list value is interpolated into LIST just as if each individual element were a member of LIST. Thus arrays and hashes lose their identity in a LIST”

  4. People learn to see things one way and when they try something new and it doesn’t behave like they are used to and have come to expect, they don’t like it.
    Of course not knowing and trying to do something anyway is difficult.
    But people need to understand that another language is another language. It just takes time to learn a new way of thinking.
    I’m tired of Python-Perl wars. I think they are both great languages with their own strengths and weaknesses.

  5. I agree Gable , its also clear author does not know how to use references, de-referencing should be a last resort as it adds overhead to a program.

    my $love={};
    $love->{you}=’always’;

    makelove($love);

    sub makelove {
    my $self=shift;
    print “I will love you $love->{you}\n”;
    }

Comments are closed.