On Wed, 20 Jun 2007 5:15 am, Mike South wrote:
On 6/19/07, Joshua Kronengold <mneme-Xhj3G7Rj6JI@xxxxxxxxxxxxxxxx> 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.
|