Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Re: tr operator in eval -- updated

by BillKSmith (Prior)
on Sep 26, 2020 at 17:04 UTC ( #11122242=note: print w/replies, xml ) Need Help??

in reply to tr operator in eval -- updated

The documentation for tr clearly states that it does not interpolate. As a workaround, we can interpolate into a string and then evaluate that string. The first two tests below demonstrate that we build the expected string and that it evaluates correctly. As a notational convenience, we can combine these two steps into one statement. The third test below demonstrates that form.
use strict; use warnings; use Test::Simple tests=>3; my $kards; my $bad = 'AKQJT98765432KKKK'; my $card = 'K'; my $string = "\$bad =~ tr/$card//"; ok($string eq '$bad =~ tr/K//', "string = '$string'"); $kards = eval $string; ok($kards == 5, "Number of K's in $bad is $kards"); $kards = eval "\$bad =~ tr/$card//"; ok($kards == 5, "Combined form");


1..3 ok 1 - string = '$bad =~ tr/K//' ok 2 - Number of K's in AKQJT98765432KKKK is 5 ok 3 - Combined form

Replies are listed 'Best First'.
Re^2: tr operator in eval -- updated
by pgmer6809 (Acolyte) on Sep 27, 2020 at 03:16 UTC
    Thanks Bill.

    I was aware that tr did not interpolate, but the (very old) edition of Camel book said I could achieve the effect I wanted with eval.

    The example they gave omitted a few key characters, and a more complete statement. I missed the necessity of having the backslash escape before the source string and also having ; characters to terminate both the expression to be eval'ed and also the eval statement itself.

    Thanks to the various posts here I am now more enlightened. Appreciated your use of Test:: in your post. I need to make better use of that package.

      I missed the necessity of ... having ; characters to terminate both the expression to be eval'ed and also the eval statement itself.

      A ; (semicolon) is not necessary to terminate the last statement in a file, block, or an eval string derived from an expression; if any of these have only a single statement, no semicolon termination at all is necessary. The eval statement itself must be ;-terminated because other statements follow it.

      Update: Another, more general and perhaps better way to put it is that every statement must be terminated, either by a semicolon or by the end of the block, file or eval string containing it. And, of course, extra semicolons have no effect.

      Give a man a fish:  <%-{-{-{-<

      Try removing the first backslash from my post and run it again. Study the output. It should be very clear that the first two tests are "not ok". Could you have found the problem yourself if you had seen this before you posted? After the first test fails, it should be clear that the second test does not stand a chance because it is evaluating the wrong string. Look at the string in the output. Note that both variables are interpolated. If you could not solve the problem at this point you could at least have asked the right question: "How can I interpolate one variable in a string, but not the other?" (The answer of course is to escape the dollar sign so that it will be treated as a literal character, not as the sigil of a variable.)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11122242]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (7)
As of 2021-06-20 20:02 GMT
Find Nodes?
    Voting Booth?
    What does the "s" stand for in "perls"? (Whence perls)

    Results (95 votes). Check out past polls.