try { die } catch { warn };Huh? This piece of code should catch the die and emit a warning instead, but here it was, dying on me. What was going on?
Actually, there's nothing wrong with that code, and it will do exactly what it is meant to do. Unless you forget the use Try::Tiny. Then all hell breaks loose.
In most cases, failing to use a module will typically result in a "Undefined subroutine" or "Can't locate object method" error message that will point to your mistake in an obvious manner. But in this case, the manifestation can be quite puzzling.
At first, I figured that maybe perl was parsing the first block (i.e. the first argument of the try subroutine) as an anonymous hash; since the try prototype hasn't been declared yet, there's no way to know that this argument is actually a block. The die will then be executed during the evaluation of the try arguments.
Close, but no cigar. Turns out that perl is indeed parsing it as a block -- just not in the context we expect:
$ perl -MO=Deparse -e 'try { die } catch { warn }'Here's the indirect object syntax rearing it ugly head; Perl assumes that try is actually a method to be called on whatever class/object the following block will return. Yuck. (Notice that the same also applies to catch.)
do {
die
}->try(do {
warn
}->catch);
(Maybe this will finally push me to break the habit of using that syntax for class methods. Yeah, I know it's unhealthy, but I can't resist...)
No comments:
Post a Comment