CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner: Re: [FishMonger] single to double quote conversion: Edit Log



7stud
Enthusiast

Jan 28, 2010, 1:07 AM


Views: 2473
Re: [FishMonger] single to double quote conversion


Code
my $w = 'world'; 
my $str = 'hello $w';

my $result = eval qq{"$str"};
say $result;

--output:--
hello world



That is equivalent to:


Code
my $w = 'world'; 
my $str = 'hello $w';

my $result = eval "\"$str\"";
say $result;


1) Both of perl's quote marks, ('') and ("") as well as q{} and qq{}, are actually operators; they do something to a series of characters, then return a result. The double quote operator does variable interpolations into the specified series of characters. The single quote operator does not, but it does do some other things.

In both cases, the operator has a return value: what I would call an 'internal' string; and the 'internal' string does not have any quote marks around it--it is just a series of characters. If you do this:

my $str = 'hello';
say $str;

The output does not have any quote marks in it. On the contrary, programmers use quote marks in their code to signal perl to do some transformations to a series of characters--but perl doesn't save the quote marks; perl just saves the return value of the quote mark operator.


2) Analyzing this line:


Code
my $result = eval "\"$str\"";


there is a double quoted string(the outer quotes), with some literal quotes inside the string, and a variable. Because perl interpolates variables into a double quoted string(the outer quotes), $str is replaced by the 'internal' string' which is stored in $str (note that replacement would happen whether the literal quotes(\") were present or not).

The outer double quotes are, once again, an operator; and the operator returns a series of characters, which creates another 'internal string', namely the series of characters: "hello $w". The quote marks are part of this 'internal' string because the original string contained literal quote marks, which happened to be the first and last characters of the string. As a result, you are essentially left with something like:

eval <"hello $w">.

3) The literal quotes(\") are necessary because they are the double quote operator, and you want eval() to execute the double quote operator to perform another interpolation into the string.

4) Another way to think about what's happening in the original line:


Code
my $result = eval "\"$str\"";


is that the double quote operator(the outer double quotes) does one pass of interpolation. That creates the internal string:

"hello $w"

where the quote marks are actually the first and last characters of the 'internal' string. Then eval causes the double quote operator to execute, which does another pass of interpolation, and 'world' is substituted in place of $w.

5) You might think that because the double quote operator does a single pass of interpolation, you could just apply the double quote operator twice and forget about eval(). However, I don't think there is a way to do that. If you write:

my $result = ""$str"";

then perl sees two strings: "" and "" with a variable name in the middle (and that will produce an error). You might try this:

qq{qq{$str}}

and that does a little better, in that it doesn't produce an error, but it doesn't succeed in doing two interpolations. Only one interpolation gets performed leaving you with the string:

qq{hello $w}

To get a second pass of interpolation, you need to use eval(). To set things up correctly for eval(), you first need the double quote operator surrounding your original string. Then the double quote operator will do the first pass of interpolation. Secondly, you need some literal quotes inside the string:

"\"$str\""

perl will save that string as:

"$str"

That is, the first and last character of the 'internal' string are quote marks.

Then eval() will execute the double quote operator that it sees, which will cause the double quote operator to perform the second pass of interpolation. The clearest way to write that is:

qq{"$str"}

5) If all that is too confusing, and you don't want to have to think about all that, you can let the Template module do the thinking for you. You do have to learn about the Template interface:


Code
use strict; 
use warnings;
use 5.010;

use Template;

my $w = 'world';
my $str = 'hello $w';

my $vars = {
w => 'world',
};

my $t = Template->new({INTERPOLATE => 1});

my $result;
$t->process(\$str, $vars, \$result) or die $t->error();

say $result;

--output:--
hello world





6) Your problem has nothing to do with CGI, and posting lots of confusing, irrelevant code does nothing to encourage people to help you. In the future, construct a short example that demonstrates your problem and post that. Yes, it takes some time and effort to put your real program aside and come up with an example program that models the problem, but you will learn a lot more doing that--often times solving the problem yourself, and it will make it a lot easier for people to help you if they don't have to wade through a bunch of confusing code.


(This post was edited by 7stud on Jan 29, 2010, 12:17 AM)


Edit Log:
Post edited by 7stud (Enthusiast) on Jan 28, 2010, 1:08 AM
Post edited by 7stud (Enthusiast) on Jan 28, 2010, 1:14 AM
Post edited by 7stud (Enthusiast) on Jan 28, 2010, 1:16 AM
Post edited by 7stud (Enthusiast) on Jan 28, 2010, 1:17 AM
Post edited by 7stud (Enthusiast) on Jan 28, 2010, 1:23 AM
Post edited by 7stud (Enthusiast) on Jan 28, 2010, 1:56 AM
Post edited by 7stud (Enthusiast) on Jan 28, 2010, 10:35 AM
Post edited by 7stud (Enthusiast) on Jan 29, 2010, 12:17 AM


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives