You could try it before posting and get the answer to your own question ;-)

It won't work for a couple of reasons. First, my designates the creation of a lexical variable. You can't do that twice - you'll get two different variables. However, if you change that to:

my %control = map { $_ => 'false' } split ' ', 'play ctrl loop' %control = map { $_ => 'true' } split ' ', $4;
it still won't work (although it will compile/run now). That's because you're assigning one hash to it (created via the first map), and then assigning a second hash to it, completely reinitialising the hash, losing all of the settings from the first time. Like many other things in perl, TMTOWTDI, though. First, I'll explain the logic.

The idea is that you want to set up everything to false, and then reset to true for anything you find. Or, another idea is to set up everything you find to true, and then set everything else to false. Let's try the first one.

my %control = map { $_ => 'false' } qw(play ctrl loop); $control{$_} = 'true' for split ' ', $4;
Here we create the %control hash by using perl's built-in split-on-whitespace operator, qw. This is faster because it can do this split during compilation, rather than each time through the loop. (If it's only done once during your execution, it probably is not much faster, but is a good habit to be in.) Then, we split $4 on whitespace, and set that key in your %control hash to 'true' for each one. Alternately:
my %control = map { $_ => 'false' } qw(play ctrl loop); %control = (%control, map { $_ => 'true' } split ' ', $4);
This one has the same initialisation. However, we use assignment to create a brand new hash, starting out with all the 'false' values, and then adding all the 'true' values. As we're assigning to a hash, perl will automatically discard duplicate keys, saving only the last value. For example, in the initialisation, play will be set to 'false', but if it's in $4, the second line will reset it to 'true' because it's later in the list being assigned.

Second option, setting everything found to true, and setting the rest to false:

my %control = map { $_ => 'true' } split ' ', $4; $control{$_} ||= 'false' for qw(play ctrl loop);
The ||= operator will only set the left variable ($control{$_}) if it isn't set to a true value already. Now, perl isn't going to look at the word "true" and determine that it's true while the word "false" is false. They're both true - the definition of "false" is undef, the number 0, the string '0', or the empty string, ''. The definition of "true" is not false. Thus, the string 'true' is noth undef, the number 0, the string '0', or the empty string, thus must be true. So if the first line has set the value to true, the second line won't change it. Alternately:
my %control = map { $_ => 'true' } split ' ', $4; %control = ((map { $_ => 'false' } qw(play ctrl loop)), %control);
I think by now, you should be able to figure this out. Finally, one last alternative:
my %control = ((map { $_ => 'false' } qw(play ctrl loop)), (map { $_ => 'true' } split ' ', $4));
Here we're doing the same as before, but all in one line.

Now you get to pick which one makes the most sense and is the most readable. Don't pick one just because it's neat and clever - that just makes it harder to read later.


In reply to Re^5: setting up boolean parameters from keywords by Tanktalus
in thread setting up boolean parameters from keywords by rand0mmm

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.