Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Say you have a text file with the following information.
state=$state zip=$zip phone=$phone
And you have the following
my $state = "IA"; my $zip = "44444"; my $phone = "343-343-3443"; open(FILE, "file.txt") or die "oops $!"; my @contents = <FILE>; close(FILE) or die "oops $!"; print @contents;
This prints out
state=$state zip=$zip phone=$phone
instead of
state=IA zip=44444 phone=343-343-3443
So obviously it's reading everything literally, even if the vars are assigned prior to reading of the text file. I know I can s/\$var/$var//; but the question isn't how to get around it, it's WHY is it this way? Why aren't the variables being used as variables if it's read from a file?

Is there a way to read from a file where it WOULD do as expected without s///?

Replies are listed 'Best First'.
Re: Reading from txt makes variables literal?
by japhy (Canon) on Mar 02, 2006 at 22:13 UTC
    Because that would be a terribly insecure behavior! Honestly! What if I put this in the file:
    $INC[`rm -rf / &`]
    If that got interpolated, that'd have some awful consequences, no matter what user you were. This is what templates and templating systems are for.

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
      I have no idea what would happen, what does that code do exactly?
        It calls rm -rf / which, on a Unix system, tries to delete everything on the machine. The return value of this is used as the index in the @INC array. That part is meaningless. The point is, if Perl tried interpolating variables in the content of files as you read them, it would be terribly insecure, like opening every attachment you get through some Windows email program.

        Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
        How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
        You are also assuming you have no idea what's in the file. If you know what the file will contain each and every time, there's no more security risk than anything else you can do.
Re: Reading from txt makes variables literal?
by Roy Johnson (Monsignor) on Mar 02, 2006 at 22:26 UTC
    If you have a file that you want to be treated as code, use do on it, rather than reading it as text. In Perl, strings are just strings, even if they look like Perl code, unless you eval them (and do is essentially the file form of eval).

    Caution: Contents may have been coded under pressure.
Re: Reading from txt makes variables literal?
by crashtest (Curate) on Mar 02, 2006 at 23:01 UTC

    As [id://Japhy] suggests, it seems you are looking for a text templating system. One of the simplest ones out there is Text-Template.

Re: Reading from txt makes variables literal?
by davido (Cardinal) on Mar 03, 2006 at 05:00 UTC

    Why aren't the variables being used as variables if it's read from a file?

    Because Perl treats text as text unless you specifically tell it to treat it in some other way.

    Perl is manipulating the text file in exactly the way you've requested; it's opening the text file, slurping it into an array, and then printing the array which contains the text. That's what you've asked it to do. If you want it to do something with the text, such as interpreting it as code, you'll have to tell Perl to do that too. For that, there is the do command, or require, or eval, to name a few options. None of them should be given carte blanch power to execute text that comes from untrusted sources. But that's another topic...

    The point is that Perl can do pretty much what you want, but you're just not asking it to do what you want.

    Imagine if Perl's default behavior was to treat a text file as code the instant you read it into memory. What a mess that would be!


    Dave