Re: mini-quiz
Joshua Kronengold <[email protected]> Wed, 20 Jun 2007 10:09:04 -0400
| Newsgroups | gmane.comp.lang.perl.qotw.discuss |
|---|---|
| Message-ID | <[email protected]> |
On Wed, 20 Jun 2007 5:15 am, Mike South wrote: > On 6/19/07, Joshua Kronengold <[email protected]> wrote: >> On Tue, 19 Jun 2007 12:50am, Ron Isaacson wrote: >>> Joshua Kronengold wrote: >>>> >> my $country = map +(/^(?:|gbr)$/ ? '' : uc),$card->country; > The part where you are using map, which returns an array, and you are > getting a scalar back which will always be 1? :) Of course I'm partly > saying that just to be funny, but there are a lot of things that have > to be right in your idiom: It's true. And this is an interesting conundrum -- I chose map because it's the only really appropriate "filter" that avoids redundantly referring to the same variable more than once and avoids explicitly making a temp variable or reusing $country for that purpose. But really, it's not ideal for the reasons you list. If there were a scalar map (ie "filter", that would work better, but there isn't one. I think this is a "fixed in six" issue, but then, isn't everything? > ^, $ anchors on the regex because you're really specifying values for > the whole string Yes. That said, this is something perl programmers need to learn to get right by habit -- all too often, I've run into the opposite issue with insufficiently bound regexps. > parens on the regex so that you don't get alternation between the ^ > zero-width assertion and gbr$ Same as the above. > + in front of the () after the map so it doesn't look like map() Actually, to be fair, the parens are unnecessary here -- since the fancy comma binds more loosely than the alternation. The reason I keep it in here is that it's generally useful for clarity -- and because it's -very- important that people use parentheses when using alternations that returns lists rather than scalars. > , after the () after the map since it's the map EXPR, ARRAY form > > (Everything else aside, I would use the "map {} " form--is there a > reason not to? All I see is two extra characters to type, but I'm > interested to know if there's a good reason.) This is an interesting question. Your objections to expr map are -largely- the general unfamiliarity with that form, but in fact I've tended over the last 4-5 years to gravitate to using expression map over block map (except when block map is actually called for, because a map involves more than one phrase or because it needs a lexical scope) for a couple of reasons: 1. Efficiency. It's a stupid reason, but nevertheless, expr map is faster than block map, which can matter in some applications. 2. Clarity. Once you get over the fact that most perl programmers have never seen an expr map in their life, the fact that there are a lot of limitations to what the enclosing expression can do (has no scope, cannot contain more than an rvalue, no semicolons) is very useful to the reader as bounding the purpose of the expression, as is the connotation that the expression is unlikely to produce side effects (not that side effects aren't generally a bad idea in maps, because they are). This is in some ways similar to why it's better to use undefs, not positive values, for an assertion hash -- if you can only use exists() to test for truth, you're only going to -see- exists() used for that purpose, and much less likely to see obsucre bugs showing up because people used a mix of that and naked truth tests. And, of course, there are outside the scope of this, maps where using a naked expression provides added clarity, like when you're mapping to a list. At least, I think the first of these is clearer: my %h = map +($_ => undef) => @keys; vs my %h = map { $_ => undef } @keys; (even if you add the parentheses back in) (questions of whether the above is better/worse than "my %h; @h{@keys} = ()" aside.) > like "best idiom" is > problematic, as idioms tend to localize. Yup. Depending on your idiomatic familiarity, a new idiom might be immediately obvious or beyond the pale -- especially when (as in my example) it actually embeds other potentially unfamiliar idioms.