"be consistent" | |
PerlMonks |
Sub signatures, and a vexing parseby davido (Cardinal) |
on Nov 18, 2014 at 21:53 UTC ( [id://1107656]=perlmeditation: print w/replies, xml ) | Need Help?? |
I was experimenting with the experimental subroutine signatures feature of Perl 5.20 today along with the much maligned prototypes feature of old, and encountered a most vexing parse that interested me. So I wanted to mention it here. First, something that is not a problem:
This parses correctly, and will generate a subroutine named mysub with a prototype of \@\@, and with named parameters of $left and $right, which when called will contain array refs. But this doesn't do much. My real goal was generating several similar subroutines, and called upon map in a BEGIN{ ... } block to do the heavy lifting. Here is a contrived example that isn't terribly useful, but that works, and demonstrates the issue:
Do you see what the problem is? The compiler doesn't care for this at all, and will throw a pretty useless compiletime error:
Q: So what changed between the first example, that works, and the second example, that doesn't? A: Lacking other cues, the compiler parses sub : as a label named sub, and thinks that I'm trying to call a subroutine named prototype... and from that point on things are totally out of whack. Solution: +. Anything that can remind the parser that it's not looking at a label will do the trick. Parenthesis around the sub : ... construct works, but + is easier, and probably more familiar to programmers who use + to get {....} to be treated as an anonymous hash ref constructor rather than as a lexical block. With that in mind, here's code that works:
...or how a single keystroke de-vexed the parse. A really simple example that breaks is this:
I don't really see any way around the parsing confusion in the original version that doesn't work. That perl considers sub : to be a label in the absence of other cues is probably not something that can be fixed without making sub an illegal label. But if I were to file a bug report (which I haven't done yet), it would probably be related to the useless error message. This example is fairly contrived, but it's not impossible to think that subs with signatures and prototypes might be generated in some similar way as to fall prey to this mis-parse. Credit to mst and mauke on irc.perl.org#perl for deciphering why the compiler fails to DWIW. Dave
Back to
Meditations
|
|