[template] url = http://www.wired.com/news_drop/palmpilot/ AvantGo = No maxdepth = 2 bpp = 4 compression = zlib title = Wired News no_url_info = True beamable = False ... # about 15 other arguments possible here [end_template]
There are several ways the arguments can be passed, depending on the nature of the arguments. Some arguments to the system command being called are boolean, on and off. An example is beamable = 1, which is associated with the --beamable argument that the system binary expects. If beamable = 0, then --not-beamable is passed to the system binary.
Another one is no_url_info = 1, which translates to a --no-urlinfo argument being passed to the system binary. If no_url_info = 0 in the template, then --no-urlinfo is not sent as an argument (i.e. undef), because there is no complementary "false" argument string for this binary. In code, the tests for this look like the following:
# Thanks for the help here 'demerphq' and 'hiseldl' if (defined $beamable && ($beamable =~ /1|true|yes/i)) { $beamable = '--beamable'; $beamable_msg = "Yes, document is beamable"; } elsif (defined $beamable && ($beamable =~ /0|false|no/i)) { $beamable = '--not-beamable'; $beamable_msg = "No, document is copy-protected"; } else { $beamable_msg = "Unspecified, defaults to beamable"; } print LOG " Beamable: $beamable\n"; # Test for no_url_info = value in the template if (defined $no_url_info && ($no_url_info =~ /1|true|yes/i)) { $no_url_info = '--no-urlinfo'; $no_url_info_msg = "No, url information disabled"; } elsif (defined $no_url_info && ($no_url_info =~ /0|false|no/i)) { $no_url_info = (); $no_url_info_msg = "Yes, url information shown"; } else { $no_url_info_msg = "Unspecified, url information shown"; } print LOG " url Info: $no_url_info\n";
Then I stack these arguments, and pass them to the system via system() in list-mode as follows:
my $systemcmd = "/usr/bin/appname"; my @systemargs = ('-p', $workpath, '-P', $workpath, '-H', $url, ($maxdepth < 3 ? "--maxdepth=$maxdepth" : "--maxdepth=2"), $bpp ? "--bpp=$bpp" : (), # thanks to 'tye' ($compression ? "--${compression}-compression" : ''), '-N', $title, $beamable ? $beamable : (), $no_url_info ? $no_url_info : (), '-V1', '-f', "$workpath/$md5file"); print LOG "Command: $systemcmd @systemargs\n"; system($systemcmd, @systemargs);
So far, so good, but here's where I need some extra eyes: As I add more arguments to compensate for everything this binary can accept, bools, values, and so on, I am going to need to test them for the same true, false, undef, and output the right value to the system call accordingly.
Each of the two tests above were 10 lines, not including the line for the ternary in the system call itself. Across about 2-dozen possible arguments to the system call, this could baloon very fast, and be quite a lot of duplicated code, except for the actual key name itself. I'd like to eliminate that duplication as much as possible.
I'm thinking that this could be done with a hash of some sort, which contains the argument name and the values it can take, such as:
my @args = ({s_arg =>'beamable', # argument name t_arg =>'--beamable', # true argument t_msg =>'Document is beamable', # true message f_arg =>'--not-beamable', # false argument f_msg =>'Document is protected},# false message s_arg =>'urlinfo', t_arg =>'', t_msg =>'Yes, url information provided', f_arg =>'--no-urlinfo', f_msg =>'No, no url information provided'})
At some point, I also need to test that the value passed in the template was either true, false, or undef, and then pull the right member out of the hash, and send it to the system call.
Is there an easy way to "walk the hash" and set options accordingly, based on what values are found in the template?
In reply to Cleansing and stacking arguments before calling system() by hacker
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |