You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by Gonzalo Diethelm <go...@aditiva.com> on 2004/02/23 23:15:43 UTC

Rationale behind reference escaping

I am trying to understand why reference escaping works the way it
does.  I come from a C/C++ background, and as far as I understand, the
way Java treats the backslash character is pretty similar to C/C++.
Therefore, I find it hard to follow the rationale for the way Velocity
works.  All the examples I'm showing are straight from the Velocity
Users' Guide, and "=>" is to be read as "renders as".

1. These examples work EXACTLY as I would expect them.

## The Velocity way, from the manual...
#set( $email = "foo" )

$email    => foo      ## evaluate $foo
\$email   => $email   ## print '$' followed by "email"
\\$email  => \foo     ## print '\' followed by contents of $email
\\\$email => \$email  ## print '\', '$' followed by "email"


2. These examples show that reference escaping is not done on a pure
   lexical basis; in C/C++, escaping is conceptually handled at the
   preprocessor level.  Why doesn't a '\' character in Velocity ALWAYS
   protect the following character? Why is "\\" a '\', but "\&" is NOT
   a '&', but a "\&"?  See comment after example...

## The Velocity way, from the manual...
## $email is NOT defined
$email    => $email
\$email   => \$email
\\$email  => \\$email
\\\$email => \\\$email

   To understand what I'm referring to as lexical: on the second
   example, it is necessary to know whether $email is or not defined in
   order to check whether the escaping should print a "$" or a "\$".
   This does not seem uniform behavior to me; I would expect "\$" to
   ALWAYS generate "$".  To be thorough, this is the behavior I would
   expect for this example:

## The lexical way...
## $email is NOT defined
$email    => $email    ## not defined, print reference
\$email   => \$email   ## print a '$' followed by "email"
\\$email  => \\$email  ## print a '\' and $email, which is not defined
\\\$email => \$email   ## print a '\', a '$' and "email"


3. Escaping silenced references does not seem very predictable as
   well:

## The Velocity way, from the manual...
#set( $foo = "bar" )
$\!foo    => $!foo
$\!{foo}  => $!{foo}
$\\!foo   => $\!foo
$\\\!foo  => $\\!foo

   What's the logic here? Why two backslashes are printed in the last
   line?  The manual only says " When a reference is silenced with the
   ! character and the ! character preceded by an \ escape character,
   the reference is handled in a special way."  This is not very
   clear, to say the least...  Is there any reason this could NOT be
   written and treated in the more predictable, pure lexical way?

## The lexical way...
#set( $foo = "bar" )
\$!foo    => $!foo
\$!{foo}  => $!{foo}
\$\!foo   => $!foo
\$\\!foo  => $\!foo


Could someone please explain the logic behind the way escaping works,
and why it makes sense the way it is implemented now?

Also, how do you explain this behavior to your template designer,
someone without much programming experience?  If things were done the
lexical way, I would tell them:

1. Whenever you write "\X" in your template, you will get a 'X'
   character in the output.
2. Whenever you put a reference to a value in your template, you will
   get the evaluated reference, or the exact same text you tried to
   evaluate, if the reference cannot be evaluated.

But for the life of me, I can't find an easy way to understand (much
less explain) why "$\\\!foo" will print "$\\!foo".

Best regards,


-- 
Gonzalo Diethelm
gonzalo.diethelm@aditiva.com


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: Rationale behind reference escaping

Posted by Daniel Dekany <dd...@freemail.hu>.
Monday, February 23, 2004, 11:15:43 PM, Gonzalo Diethelm wrote:

> I am trying to understand why reference escaping works the way it
> does.  I come from a C/C++ background, and as far as I understand, the
> way Java treats the backslash character is pretty similar to C/C++.
> Therefore, I find it hard to follow the rationale for the way Velocity
> works.
[snip]

I have disputed a lot about this (and other things) earlier here... The
conclusion was that (at least on my side...) that there is *no*
rationale behind these. It's plain ugly syntax design mistakes, that
can't be fixed now, because that would cause backward compatibility
issues. So you have just live with these... (well, as much as you have
to use Velocity ;)). If, in your application it's a real problem, there
are workarounds, for example putting a variable with name "D" into the
template context that stores a dollar sign, so "${D}foo" will surely
always print "$foo".

-- 
Best regards,
 Daniel Dekany



---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: Rationale behind reference escaping

Posted by Barbara Baughman <ba...@utdallas.edu>.
Remember that Velocity is a templating language, not a compiler
language.  Its goal is to keep everything in the template the same
unless there is a reference in the context.  As such, making special
interpretations for things like '\&' or '\$20.00' is outside the
mission of the language.

So the only escaping necessary in Velocity would concern an
un-Velocity interpretation of possible context references or
directives.

If your designers have problems with escaping, you can always use a
more direct brute-force approach, like
#set ($emailref='$email')
$emailref => $email
whether $email is in the context or not (the single quotes do the
trick of strict interpretation).

#set ($mark='#')
${mark}if => #if

So the escaping logic has to do with Velocity parsing only. The
question is, how to escape normal Velocity behavior to output
something special?  The leftmost '\' escapes the normal Velocity
behavior of the remaining expression.

#set ($email="foo")
How would you render "$email" instead of "foo"?
Answer: \$email
  Normal $email would be foo, escaped is $email
Now, how would you render "\foo" when $email is "foo"?
Answer: \\$email
  Normal \$email would be $email, escaped is \foo
Now, how would you render "\$email" when $email is "foo"?
Answer: \\\$email
  Normal \\$email is \foo, escaped is \$email
Note that I really don't know much about the program logic itself.

Barbara Baughman
X2157

On Mon, 23 Feb 2004, Gonzalo Diethelm wrote:

> I am trying to understand why reference escaping works the way it
> does.  I come from a C/C++ background, and as far as I understand, the
> way Java treats the backslash character is pretty similar to C/C++.
> Therefore, I find it hard to follow the rationale for the way Velocity
> works.  All the examples I'm showing are straight from the Velocity
> Users' Guide, and "=>" is to be read as "renders as".
>
> 1. These examples work EXACTLY as I would expect them.
>
> ## The Velocity way, from the manual...
> #set( $email = "foo" )
>
> $email    => foo      ## evaluate $foo
> \$email   => $email   ## print '$' followed by "email"
> \\$email  => \foo     ## print '\' followed by contents of $email
> \\\$email => \$email  ## print '\', '$' followed by "email"
>
>
> 2. These examples show that reference escaping is not done on a pure
>    lexical basis; in C/C++, escaping is conceptually handled at the
>    preprocessor level.  Why doesn't a '\' character in Velocity ALWAYS
>    protect the following character? Why is "\\" a '\', but "\&" is NOT
>    a '&', but a "\&"?  See comment after example...
>
> ## The Velocity way, from the manual...
> ## $email is NOT defined
> $email    => $email
> \$email   => \$email
> \\$email  => \\$email
> \\\$email => \\\$email
>
>    To understand what I'm referring to as lexical: on the second
>    example, it is necessary to know whether $email is or not defined in
>    order to check whether the escaping should print a "$" or a "\$".
>    This does not seem uniform behavior to me; I would expect "\$" to
>    ALWAYS generate "$".  To be thorough, this is the behavior I would
>    expect for this example:
>
> ## The lexical way...
> ## $email is NOT defined
> $email    => $email    ## not defined, print reference
> \$email   => \$email   ## print a '$' followed by "email"
> \\$email  => \\$email  ## print a '\' and $email, which is not defined
> \\\$email => \$email   ## print a '\', a '$' and "email"
>
>
> 3. Escaping silenced references does not seem very predictable as
>    well:
>
> ## The Velocity way, from the manual...
> #set( $foo = "bar" )
> $\!foo    => $!foo
> $\!{foo}  => $!{foo}
> $\\!foo   => $\!foo
> $\\\!foo  => $\\!foo
>
>    What's the logic here? Why two backslashes are printed in the last
>    line?  The manual only says " When a reference is silenced with the
>    ! character and the ! character preceded by an \ escape character,
>    the reference is handled in a special way."  This is not very
>    clear, to say the least...  Is there any reason this could NOT be
>    written and treated in the more predictable, pure lexical way?
>
> ## The lexical way...
> #set( $foo = "bar" )
> \$!foo    => $!foo
> \$!{foo}  => $!{foo}
> \$\!foo   => $!foo
> \$\\!foo  => $\!foo
>
>
> Could someone please explain the logic behind the way escaping works,
> and why it makes sense the way it is implemented now?
>
> Also, how do you explain this behavior to your template designer,
> someone without much programming experience?  If things were done the
> lexical way, I would tell them:
>
> 1. Whenever you write "\X" in your template, you will get a 'X'
>    character in the output.
> 2. Whenever you put a reference to a value in your template, you will
>    get the evaluated reference, or the exact same text you tried to
>    evaluate, if the reference cannot be evaluated.
>
> But for the life of me, I can't find an easy way to understand (much
> less explain) why "$\\\!foo" will print "$\\!foo".
>
> Best regards,
>
>
> --
> Gonzalo Diethelm
> gonzalo.diethelm@aditiva.com
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: velocity-user-help@jakarta.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org