News for hackers. Stuff that matters.
Re:An experiment-driven guide to Perl by theOnliest on Tuesday February 11, 2014 @05:43PM (#7221057)
> In Perl, there are three contexts in which an expression may be evaluated.

> 1. scalar

> 2. array

> 3. void

There's actually no such thing as "array context" in Perl; instead there's "list context". An array is a list that's been stored in a variable (this is a fairly common mistake).

See http://friedo.com/blog/2013/07/arrays-vs-lists-in-perl and http://perlmaven.com/scalar-and-list-context-in-perl for good examples/discussion.

EDIT:

Posted this before I finished the article. Understanding the difference between arrays and lists makes the following potential WTFs a lot clearer:

    sub take_two_arrs (\@\@) {
      print $_[0], $_[1] ;
    }

    take_two_arrs @a1, @b1 ;         # prints ARRAY(0xAddr) ARRAY(0xAddr)

    take_two_arrs ((1,2),(3,4)) ;    # error: arrays must be named
The second doesn't work because the prototyped function takes array references, not lists. It would work if you called it like this:

    take_two_arrs ([1,2],[3,4])
  
I'll admit that this is baffling.

    sub what_are (++) {
      print $_[0], " ", $_[1] ;
    }

    what_are ((1,2),(3,4)) # prints 2, then 4
(This is part of the reason that Perl programmers don't use prototypes very often.) perlsub warns:

> When using the + prototype, your function must check that the argument is of an acceptable type.

The plus here forces scalar context on the arguments, which are lists (not arrays!), so they return their last elements. This would work how the author probably wants if called like this:

    what_are ([1,2],[3,4]);   # prints ARRAY(0xAddr), ARRAY(0xAddr)
Re:An experiment-driven guide to Perl by chromatic on Tuesday February 11, 2014 @06:52PM (#7221489)
I'll admit that this is baffling.

The inner parentheses force evaluation of the two inner comma operators in the scalar context provided by the function prototype. `1` and `3` get evaluated in void context and discarded, leaving `2` and `4` as the two arguments to the function. (I had to look up `+` in prototypes, however.)

Without a working understanding of lists and context, this example is undoubtedly baffling, but that's why the documentation exists.

Re:An experiment-driven guide to Perl by theOnliest on Tuesday February 11, 2014 @08:35PM (#7221907)
I guess I really meant "is baffling without a thorough understanding of context." I feel better about looking up the + now that I know you did too, though! I don't think I've ever seen code like that in the wild, and I've never seen a Perl programmer attempt to call a sub with nested parens, like what_are((1,2),(3,4)) before.
Re:An experiment-driven guide to Perl by perigrin on Tuesday February 11, 2014 @08:58PM (#7221996)
You may not realized that's what you saw, but for example all of the Moose documentation uses effectively a nested param:

    has foo => ( is => 'ro' );
is equivalent to:

    has('foo', ('is', 'ro'));
because Moose's `has` sugar is written as a exported function.
Re:An experiment-driven guide to Perl by theOnliest on Wednesday February 12, 2014 @07:01AM (#7223832)
That's true, but I've never actually seen anyone call 'has' like that. Plus, Perl's behavior on lists makes sense (always flatten) if there's no mucking around with prototypes, so that's much less confusing than the behavior in the article.
Re:An experiment-driven guide to Perl by perigrin on Wednesday February 12, 2014 @01:21PM (#7226165)
The first one I presented is the way the Moose documentation calls has, the way the Moose test suite typically calls has, and the way I and most of the rest of the Moose Cabal call has.

The second one isn't common at all, but I have seen people both completely leave out the parentheses:

    has foo => is => 'ro', isa => 'Str', ...;
or treat has as a straight function

    has(foo, is => 'ro', isa => 'Str');
both of which cause Perl::Tidy to do weird things.
Re:An experiment-driven guide to Perl by theOnliest on Wednesday February 12, 2014 @02:11PM (#7226531)
Sorry, I meant I'd never seen it called the second way (nested parens). I also haven't seen the no-parens version, which looks really bizarre!