We help IT Professionals succeed at work.

Why this perl code about eval not work

Chunhua Du
Chunhua Du asked
on
189 Views
Last Modified: 2018-12-30
Code is here:

my $a1 = ‘a1_v’;
my $c1;
my $varName;

my $code = qq(
      \$varName = ‘a1’;
      eval(‘\$c1 = \$\$varName;’);
);

eval($code);

# I hope this line print a1_v, but print nothing
print “$c1\n”;
Comment
Watch Question

CERTIFIED EXPERT
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION

Author

Commented:
could I understand in this way: every layer of eval function add in code string, add \\ to begin of $ in parameter of added eval function?

thanks
CERTIFIED EXPERT

Commented:
Yes.  Generally, for every level of eval, add \ per level (which means \\ for beyond the first).

Anytime you have an eval that doesn't work, the first thing to check on is the escapes and quotes and try debugging if they are what you want for the level of eval nesting you are using.

Author

Commented:
In the nesting eval function, if I want to use single quote on the parameter of eval, how should I code

thanks
CERTIFIED EXPERT

Commented:
I don't think you can in this case (not positive) as you have variables at different nesting.  Why do you want to use single quotes?

Let me start even more basic - what are you trying to do with the nested evals?  You can probably do something else that would be simpler and much more efficient.

Author

Commented:
I want to know why this works:

my $code = qq(
   \$str =~ m"$pattern";
   for(\$xx = 1; \$xx <=2; $xx++)
   {
      eval('\$backRef = \$\$xx;');
      push(\@\$backRefArr, \$backRef);
   }
);

eval($code);

print "@$backRRefArr";
CERTIFIED EXPERT
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION

Author

Commented:
In my last code, variable $refBack and @refBackArr are defined out of $code

$xx++ in my last post is mistake, in my code it is \$xx++, it is my mistake sorry for this
nociSoftware Engineer
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
not need to add a \  you need to escape everythin double

so \ -> \\   $ needs \$  etc.      $var -> \$var
Each needs to be escaped again...:   \$var -> \\\$var
Next level:                                              \\\$var -> \\\\\\\$var
etc.

Author

Commented:
Thanks, I would try it

Author

Commented:
Do you mean \\\$->\\+\\+\\\$

Author

Commented:
How can I understand 'double', I am not sure double what
Software Engineer
CERTIFIED EXPERT
Distinguished Expert 2019
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION
CERTIFIED EXPERT

Commented:
To rephrase what noci (and I) are saying...

For each nesting of eval that something should be evaluated at, you need to add an escape.  qq(...) is equivalent to double-quoting.

Given the example:
my $code = qq(
   \$str =~ m"$pattern";
   for(\$xx = 1; \$xx <=2; $xx++)
   {
      eval('\$backRef = \$\$xx;');
      push(\@\$backRefArr, \$backRef);
   }
);

eval($code);

print "@$backRRefArr";

Open in new window


$pattern will be evaluated when $code is defined
everything with \x becomes x when $code is defined
everything that had \x is evaluated when the first eval occurs (except the things in the second eval because they are enclosed in single quotes)
the single quoted string is then eval'd by the second eval
CERTIFIED EXPERT
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION

Author

Commented:
Why this not work:

my $a1 = 'a1_v';
my $varName;

my $code = qq(
      \$varName = 'a1';
      print \$\$varName;
);

eval($code);

# This do not work, either
$varName = 'a1';
print "$$varName"
nociSoftware Engineer
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
Why should it:
I translated your $code to the equivalent $code2...
my $a1 = 'a1_v';
my $varName;

my $code = qq(
      $varName = 'a1';
      print \$\$varName;
);
my $code2 = "
    $varName = 'a1';
    print \$\$varName;
    ";

print "code=$code\n";
print "code2=$code2\n";
#(That should explain the first part... qq is realy the same as "..., if you have an ebcdic system qq( ) is simpler than just "...

# This do not work, either
$varName = 'a1';
print "\$$varName"
#This does what you told it to do print $ and the contents of $varName:   result: $a1    (without line feed)...

Open in new window



You may meant it to do:

$varName = 'a1';
eval( "print \$$varName; " );
print "\n";
eval( "print \"\${$varName}\"; " );
print "\n";
eval( "\$x = \"\${$varName}\"; print \$x;" );
print "\n";

Open in new window


again look at the intermediate results:
$varName = 'a1';
print( "print \$$varName; " );
print "\n";
print( "print \"\${$varName}\"; " );
print "\n";
print( "\$x = \"\${$varName}\"; print \$x;" );
print "\n";

Open in new window


Which requires proper quoting, including the " getting quoted, if needed.

Author

Commented:
In my code:

print $$varName;

at this line, I hope to get value of $a1, why getting nothing? Must it use eval?

Author

Commented:
By my understanding, if I write:

$$varName

in level N of eval, $varName must be defined and get value in level N-1

Author

Commented:
I mean that get value of $a1 by $$varName, $varName has string value 'a1'.

For example: $a1 has value 'v1', I want $$varName return value 'v1'. I am not sure whether it must use eval here
nociSoftware Engineer
CERTIFIED EXPERT
Distinguished Expert 2019
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION

Author

Commented:
But why this works:

$str = m{$pattern};
for($xx = 1; $xx <= 2; $xx++)
{
      print $$xx;
}
nociSoftware Engineer
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
They work at printing nothing?.... as there is quite some missing context. Syntax is correct though.
Anyway what is $pattern...
The pattern isn't matched to anything using =~ ....

Please try the code fragments you wish us to evaluate First as such and describe what you get and what you expect...
CERTIFIED EXPERT

Commented:
Doing something like this:
my $a1 = 'v_1';
my $varName = 'a1';
{ # begin closure
no strict 'refs';
print $$varName, "\n";
} # end closure

Open in new window

does not require an eval.  That is a symbolic ref and works fine.

You are doing "use strict; use warnings;" in your code, right?  If not, you ALWAYS should be as it will catch a lot of errors (and I assume you are which is why I put "no strict 'refs'" since strict disallows symbolic references and you should only allow them where expected).

Author

Commented:
Full code in my last post:

my $s1 = 'xxa1xxb2xx';
$s1 =~ m{(a\d+).*?(b\d+)};

for($xx = 1; $xx <= 2; $xx++)
{
      # why this line get value 'a1' and 'b2' without eval
      print "$$xx";
      print "\n";
}

Author

Commented:
I have try your code with:

no strict 'refs';

I get empty output.
CERTIFIED EXPERT

Commented:
Your code works fine because it uses symbolic refs.  $$xx evaluates to $1 and then $2.

Apparently I shouldn't do symbolic refs or evals from memory (my code doesn't work as posted and I don't see why).  I'll double-check it later and report a snippet that works...
CERTIFIED EXPERT
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION

Author

Commented:
Thanks to all your help these days. I have understood and got ways to do on those issues by your posts.

I think it is time to stop.

Thanks everyone who help.

Happy New Year!

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions