use strict;
use warnings;
my $var1 ="a.pl";
my %hash = (
"command1" => "type $var1"
);
system ($hash{"command1"});
Update:
I was thinking of adding this update, and at the same time, I saw the reply from emilford. I like this better:
use strict;
use warnings;
my %hash = (
"command1" => "type %s"
);
my $var1 ="a.pl";
system(sprintf($hash{"command1"}, $var1));
| [reply] [d/l] [select] |
I think this only works because $var1 is defined prior to being stored in the hash. My variables could be definied/changed anywhere in the script. I'm looking for a way to have the scalars in the hash replaced with the most current values. Thanks.
| [reply] |
I think that you have answered your question for yourself. What do I mean by that? "Some of the parameters are stored elsewhere in the script as scalars and would need to be evaluated at the time of use." That's what eval is for! It evaluates things at run time. I'm thinking the last line should be: system(eval{$hash{command1}});
But I did not test it, YMMV, objects in mirror may be closer than they appear, any bit rot caused by using this is to be blamed upon alpha particles and not me.
Updated the code snippet (eval needed braces and not parentheses). I did test it, but as always: YMMV, objects in mirror may be closer than they appear, any bit rot caused by using this is to be blamed upon alpha particles and not me.
| [reply] [d/l] |
I still don't think this works. Here's what I have:
%alerts = ('command1' => 'Command1 = $val1');
$val1 = 'foobar';
print "eval {$alerts{command1}}";
This prints out "Command1 = ". | [reply] [d/l] |
What you need is eval, BUT 'command $foo' is unlikely to be valid perl so the eval will fail. This regex method works because we capture the scalar and perform the required (double) eval (first eval gets you $var out of $1, second gets you 'value' out of $var). You may wish to add more than \w in the capture after the $ for things like $foo->{bar} if you are getting that weird.
%hash = ( 'command' => 'command_name -n $var1 -p $var2' );
$var1 = 'foo';
$var2 = 'bar';
$command = $hash{'command'};
$command =~ s/(\$\w+)/$1/gee;
print $command;
# system ($command);
__DATA__
command_name -n foo -p bar
This is almost certainly a bad way to do it BTW.
| [reply] [d/l] |
Now I'm not even sure how I got it working because I didn't keep my snippet. Oh, well. I really like pg's update that uses sprintf.
| [reply] |
Actually, it may not be obvious and apparent, but what you are really in need of is a closure. That is, at one point in time, you want to create a hash-value which will depend on the values which other variables have *at a later time* when you look to that value. Here's an example:
%hash = (
# the sub { ... } means that this is a closure (a subroutine refere
+nce)
command1 => sub { "command_name -n $var1 -p $var2" }
);
$var1 = 'foo';
$var2 = 'bar';
# added "->()" because we are dereferencing a subroutine reference...
+a closure
system ($hash{'command1'}->());
Who loves closures? This guy.
------------
:Wq
Not an editor command: Wq
| [reply] [d/l] |
Actually... I suppose, as a more direct answer to your question... you can do this:
%hash = (
# note the single-quotes wrapping the double-quotes...
# I've defined a character string which is, itself, a valid
# perl expression... which can be eval'd later
command1 => ' "command_name -n $var1 -p $var2" '
);
$var1 = 'foo';
$var2 = 'bar';
# this is the "later" I promised above, when we eval
# the character string which contains the perl expression
system (eval $hash{'command1'});
The difference between this post and the parent post is actually only a very slight difference. This code is still, in essence, defining a subroutine reference, but it is not a closure. A closure implies static scoping, that is: the $var1 and $var2 which are visible at the time the closure is defined will be the $var1 and $var2 which are referenced at the time the code is executed. This example, however, uses dynamic scoping, that is: the $var1 and $var2 which get referenced when the code is executed are whatever variables named $var1 and $var2 are visible to the scope which executes the code. (static scoping=bound to the scope in which it was defined, dynamic scoping=scoped to wherever it is executed, whenever it is executed)
Anyway, in this very simple example, the two are functionally equivalent, but if you imagine that the hash is defined in a different scope than the value is asked for (=code is executed), then they will behave differently. Without your full code, I couldn't say which is the right one... but the dynamicaly scoped one is closer to the title of your question at least.
Aside: In college, I learned about dynamic lexical scoping, and thought someone would have to be on crack to use it, let alone implement it in a language. Then I met eval, and my life was forever changed.
------------
:Wq
Not an editor command: Wq
| [reply] [d/l] [select] |
The interpolation trick is:
$perl -de1
DB<1> x $a
0 undef
DB<2> x $str = ' \$a is $a and \$a*2 is ${\($a*2)} '
0 ' \\$a is $a and \\$a*2 is ${\\($a*2)} '
DB<3> $a = 3
DB<4> x eval qq{"$str"}
0 ' $a is 3 and $a*2 is 6 '
DB<5> $a = 5
DB<6> x eval qq{"$str"}
0 ' $a is 5 and $a*2 is 10 '
But think twice before sending the result to system() | [reply] [d/l] |