in reply to Re^4: setting up boolean parameters from keywords
in thread setting up boolean parameters from keywords
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:
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.my %control = map { $_ => 'false' } split ' ', 'play ctrl loop' %control = map { $_ => 'true' } split ' ', $4;
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.
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{$_} = 'true' for 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.my %control = map { $_ => 'false' } qw(play ctrl loop); %control = (%control, map { $_ => 'true' } split ' ', $4);
Second option, setting everything found to true, and setting the rest to false:
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{$_} ||= 'false' for qw(play ctrl loop);
I think by now, you should be able to figure this out. Finally, one last alternative:my %control = map { $_ => 'true' } split ' ', $4; %control = ((map { $_ => 'false' } qw(play ctrl loop)), %control);
Here we're doing the same as before, but all in one line.my %control = ((map { $_ => 'false' } qw(play ctrl loop)), (map { $_ => 'true' } split ' ', $4));
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.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^6: setting up boolean parameters from keywords
by rand0mmm (Acolyte) on Mar 20, 2006 at 21:57 UTC |