in reply to eval problem

I don't know why you used sprintf in any of the examples. 
You do realize that

'...'

is just as much an expression as

sprintf('%s', '...')

right? 

I tried evaling a string first, but it didn't work, so to be absolutely certain about what was happening I used sprintf. Now I understand that q{} is an operator that returns a string.


Not true. eval EXPR doesn't spit out errors. It places them in $@ and you didn't even check $@.

Jesus Christ, all these $ variables--I didn't even know there was such a thing. Now, I see that $@ is like a 'catch' to an eval BLOCK's 'try'.

What you're missing is that Perl programs are compiled and executed in their own scope, usually called "file scope".

Well, I would hope so. What else is there?
$ perl -E'use strict; my $x = 10; eval q{ my $y = $x; }; say $y' Global symbol "$y" requires explicit package name at -e line 1. Execution of -e aborted due to compilation errors.

But the docs say:

The value of the expression (which is itself determined within scalar context) is first parsed, and if there weren’t any errors, executed in the lexical context of the current Perl program, so that any variable settings or subroutine and format definitions remain afterwards.

In my opinion, your examples prove that the bolded part is false. In actuality, eval EXPR acts like EXPR is evaluated inside a block, and the block is nested inside the main program. Therefore my variables do not survive the end of the block.

Don't try to apply the docs for eval EXPR to eval BLOCK at all.

I wasn't. I was trying to apply the eval BLOCK docs to eval BLOCK.

eval BLOCK is a completely different operator. In Java, C++ and Perl6, it's known as try.

Well, that explains the baffling behavior of eval BLOCK.
I missed this question of yours originally

Or, is it that eval() only does one pass of interpolation over "$temp"

eval EXPR doesn't interpolate. It parses and executes the Perl code it is provided.

As for Perl, it doesn't interpolate recursively. Nothing I know does. (Perl, bash, Template-Toolkit, ...) 
quotemeta would become the most used function if it did.

Yes, instead of this:

And when "$temp" is eval()'ed wouldn't the qq{} operator around $temp return a string with the $variables interpolated? Or, is it that eval() only does one pass of interpolation over "$temp"...

I should have said:

And when "$temp" is eval()'ed wouldn't the qq{} operator around $temp return a string with the $variables interpolated? Or, is it that the qq{} operator only does one pass of interpolation over "$temp" when "$temp" is eval()'ed.

=================

I'm sure you've gotten all the info you needed about eval, but if you use lookaheads, you could make this work without needing to specify captures (with parentheses) in your $pattern.

Very clever. Thanks.

============

ikegami's replies have pretty well covered this question, but for further discussion of template evaluation in a substitution replacement (which is what I take the OP to be about), see nodes printig with variables in text and simple regular expression and, with a bit of redundancy, s/// treat rhs as regex.

Thanks. The Template solution looks like a good alternative too.

Replies are listed 'Best First'.
Re^2: eval problem
by ikegami (Patriarch) on Dec 04, 2009 at 07:27 UTC

    Now I understand that q{} is an operator that returns a string.

    q{} (aka single quotes) can be viewed that way, yes. It can also be viewed as a string literal. Is it a constant, the single quote operator or the const operator? It makes no difference.

    >perl -MO=Concise,-exec -e"$_ = q{abc};" 1 <0> enter 2 <;> nextstate(main 1 -e:1) v:{ 3 <$> const[PV "abc"] s 4 <#> gvsv[*_] s 5 <2> sassign vKS/2 6 <@> leave[1 ref] vKP/REFC -e syntax OK

    Jesus Christ, all these $ variables--I didn't even know there was such a thing.

    I made a point of mentioning it in my earlier post.

    But the docs say: [...] any variable settings or subroutine and format definitions remain afterwards.

    Which of those do you think my $y is?

    eval EXPR acts like EXPR is evaluated inside a block [...] Therefore my variables do not survive the end of the block.

    Yes. Lexicals created in the file scope of the program passed to eval EXPR cease to exist at the end of the scope.

    and the block is nested inside the main program.

    Specifically, nested where the eval is located ("executed in the lexical context of the current Perl program"). That means the evaluated code can see the surrounding variables.

    I should have said: And when "$temp" is eval()'ed wouldn't the qq{} operator around $temp return a string with the $variables interpolated? Or, is it that the qq{} operator only does one pass of interpolation over "$temp" when "$temp" is eval()'ed.

    I'm confused. The example (my $temp = 'xxx$1'; my $repl = eval q{"$temp"};) didn't have a qq{}. I thought you were referring to the double quotes when you said qq{}, but now you're talking about a qq{} in addition to the quotes.