Just another Perl shrine | |
PerlMonks |
comment on |
( [id://3333]=superdoc: print w/replies, xml ) | Need Help?? |
I feel like a broken recordAre you like me, and often find yourself wanting to include an element in a list conditionally (often depending on whether it is defined)? F.ex., I may want to construct a URI which has a number of moving parts.
There are two dead obvious approaches to write this in Perl:
But both approaches require you to repeat yourself unncessarily. In the push case, you have to repeat the push @part bit, and in the ternary case, you have to supply : () as an else clause for every case. Enter x!!Obviously, this is a composite operator, consisting of x and two ! negations. The double negation is there to forcibly convert the right side to a boolean value with the same truthness as the original value:
So the !! will force anything that shows up on the right side to be either 1 or !1. The x is, of course, Perl’s repetition operator:
Of interest to us are the cases where the number of repetitions is 1 or 0:
Since boolean values in Perl are either 1 or !1, that means ( $something ) x $boolean will do exactly what we want. And we can force everything to be a boolean using the !! double negative. That is how we get x!!. Update: caveat codor – as ikegami emphasises, the parens are required! ( $something ) x $boolean does a very different thing from $something x $boolean. I knew this, but forgot to harp on it. (Yes, this difference is too subtle. In Perl 6, there will therefore be two different operators, x for strings and xx for lists.) Bottom line: the example I gave can be written like this:
Neato! Not only is it nicer, but I also find that x!! has a beautifully evocative quality. :-) Update: but note that ( $x ) x!! $cond differs from $cond ? $x : () in shortcircuiting behaviour: the ternary will avoid evaluating $x if $cond is false, but x!! will always evaluate it. Conventional notesYou’ll notice that defined always returns a boolean anyway, so the !! isn’t actually necessary in three of our cases, and might not be necessary in the first one either. However, I find that one should use x!! anyway, for two reasons:
ConclusionSo there you have it. If you want to conditionally include a sub-list within a larger list, you can use the composite x!! operator express exactly that. Makeshifts last the longest.
|
|