Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^4: why lexical variables can not be interpolated?

by lightoverhead (Pilgrim)
on Oct 21, 2013 at 17:42 UTC ( #1059148=note: print w/replies, xml ) Need Help??


in reply to Re^3: why lexical variables can not be interpolated?
in thread why lexical variables can not be interpolated?

kennethk

Thank you for your detailed answers to this question.

I know if I use a symbolic reference will get this done. But it will not work for lexical scope variable. If, for example, I use:

my $AGE =17 #instead of $AGE=17

your solution will fail.

It seems to me that it's impossible to use /e to solve this situation when variable is lexical scoped.

Yes, sprintf will work for this case as we know it's a number; but in other cases we may not know if $AGE holds a numeric value.

Any thoughts?

Thank you!

Replies are listed 'Best First'.
Re^5: why lexical variables can not be interpolated?
by SuicideJunkie (Vicar) on Oct 21, 2013 at 18:25 UTC
    use strict; use warnings; my %legalReplacements = (name=>'Joe', age=>42); my $text = q(Hi I'm $name and happen to be $age. You can call me $nam +e, if you tell me your $ARGV.); my $regex = qr/\$([a-zA-Z]+)/; while ($text =~ /$regex/) { if (not exists $legalReplacements{$1}) { warn "INTRUDER ALERT: attempting access to '$1'"; last; } $text =~ s/$regex/$legalReplacements{$1}/; } print "Final text:\n"; print $text;
    gives
    C:\>perl Test.pl INTRUDER ALERT: attempting access to 'ARGV' at test.pl line 13. Final text: Hi I'm Joe and happen to be 42. You can call me Joe, if you tell me y +our $ARGV. C:\>_

      Nice solution! Hash is used here too. Thank you.

Re^5: why lexical variables can not be interpolated?
by kennethk (Abbot) on Oct 21, 2013 at 18:16 UTC
    It seems to me that it's impossible to use /e to solve this situation when variable is lexical scoped.
    There's no way around that using symbolic variables because symbolic variables only access package variables. The easiest drop in would be using a hash, which might look like:
    my %hash = (AGE => 17, ); $text =~ s/\$(\w+)/$hash{$1}/g;

    This has the advantage of removing a bunch of misdirection and potential security complications. If you wanted to make key misses fatal, you can use lock_hash in Hash::Util; of course, your symbolic reference code doesn't die on misses.

    Yes, sprintf will work for this case as we know it's a number; but in other cases we may not know if $AGE holds a numeric value.

    sprintf works for any string. Note I use %s for string replacement; numerical replacement would be %d. Obviously the multiplication only works if $AGE is a number, but that's sort of given.

    If you are learning this with an eye toward production code, please read Why it's stupid to use a variable as a variable name. Also, there are a large number of real templating packages out there, such as HTML::Template for simple projects and Template::Toolkit for more complex ones.


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      Thanks hash will work! and Thank you for your recommendations too.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1059148]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (1)
As of 2017-12-16 10:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What programming language do you hate the most?




















    Results (449 votes). Check out past polls.

    Notices?