Reputation: 1
I have the following code, which will set the value of $mystring
by reading from a file.
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my $mystring1 = "vault.\$_[0].org/\$_[1].\$_[2]/os/\$_[4]";
my $mystring2 = "vault.$_[0].org/$_[1].$_[2]/os/$_[4]";
&myfunc ("A1", "b2", "C3", "d4");
sub myfunc {
print Dumper(\@_);
print ("Before=$mystring1\n");
my $test = eval($mystring1);
print ("test=$test\n");
print ("Before=$mystring2\n");
$test = eval($mystring2);
print ("test=$test\n");
}
However, the following output is produced:
Use of uninitialized value $_[0] in concatenation (.) or string at ./t.pl line 7.
Use of uninitialized value in concatenation (.) or string at ./t.pl line 7.
Use of uninitialized value in concatenation (.) or string at ./t.pl line 7.
Use of uninitialized value in concatenation (.) or string at ./t.pl line 7.
$VAR1 = [
'A1',
'b2',
'C3',
'd4'
];
Before=vault.$_[0].org/$_[1].$_[2]/os/$_[4]
Use of uninitialized value $test in concatenation (.) or string at ./t.pl line 15.
test=
Before=vault..org/./os/
Use of uninitialized value $test in concatenation (.) or string at ./t.pl line 18.
test=
What is causing the issues and how can I achieve the following?
test=vault.A1.org/b2.C3/os/d4
How would I use eval
or create a subroutine to get this to work?
Upvotes: 0
Views: 294
Reputation: 97918
You are not using eval correctly. It tries to execute some statement, like vault..
, which results in an error (inspect $@
after eval
).
This works as expected, because the quotes make it evaluate as a string:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my $mystring1 = '"vault.$_[0].org/$_[1].$_[2]/os/$_[3]"';
&myfunc("A1", "b2", "C3", "d4");
sub myfunc {
print Dumper(\@_);
print("Before=$mystring1\n");
my $test = eval($mystring1);
print("test=$test\n");
}
But using eval [for this particular task] doesn't make any sense.
Upvotes: 0
Reputation: 2808
I would not use eval
. In general it should be avoided unless absolutely necessary due to the security implications linked to it. In your case it's probably a bad idea as you say
The value of mystring is set in a file being read in
Which means that your eval
call could execute arbitrary user input... a bad idea!
Use sprintf instead:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my $mystring1="vault.%s.org/%s.%s/os/%s";
myfunc ("A1", "b2", "C3", "d4");
sub myfunc {
print Dumper(\@_);
my $test = sprintf $mystring1, @_;
print ("test=$test\n");
}
A simple solution that does everything you require.
Upvotes: 5