Expression Interpolation from input "template string"?

Peter,

What I don't know is how to get the interpolation to
work when the string is read from teh database as if :

x = 'Hello, today is #{msgDate}'

    The easiest way to do this is to #eval() the string with quotes
around it:

irb(main):001:0* s = 'This is #{a} test.'
=> "This is \#{a} test."
irb(main):002:0> a = 'one'
=> "one"
irb(main):003:0> eval("\"#{s}\"")
=> "This is one test."

    If you're like me, you'll want to use a quoting method prettier than
\" inside the string:

irb(main):004:0> eval("%{#{s}}")
=> "This is one test."

    I hope this helps.

    - Warren Brown

That's stinkin amazing!

How/Where did you reference the knowledge for using %{} and how to
embed interpolation (Is this nested interpolation?)

Thanks for the info!

Peter Fitzgibbons

···

On 10/18/05, Warren Brown <warrenbrown@aquire.com> wrote:

Peter,

> What I don't know is how to get the interpolation to
> work when the string is read from teh database as if :
>
> x = 'Hello, today is #{msgDate}'

   The easiest way to do this is to #eval() the string with quotes
around it:

irb(main):001:0* s = 'This is #{a} test.'
=> "This is \#{a} test."
irb(main):002:0> a = 'one'
=> "one"
irb(main):003:0> eval("\"#{s}\"")
=> "This is one test."

   If you're like me, you'll want to use a quoting method prettier than
\" inside the string:

irb(main):004:0> eval("%{#{s}}")
=> "This is one test."

   I hope this helps.

   - Warren Brown

Peter Fitzgibbons wrote:

> Peter,
>
> > What I don't know is how to get the interpolation to
> > work when the string is read from teh database as if :
> >
> > x = 'Hello, today is #{msgDate}'
>
> The easiest way to do this is to #eval() the string with quotes
> around it:
>
> irb(main):001:0* s = 'This is #{a} test.'
> => "This is \#{a} test."
> irb(main):002:0> a = 'one'
> => "one"
> irb(main):003:0> eval("\"#{s}\"")
> => "This is one test."
>
> If you're like me, you'll want to use a quoting method prettier than
> \" inside the string:
>
> irb(main):004:0> eval("%{#{s}}")
> => "This is one test."
>
> I hope this helps.
>
> - Warren Brown
>
>
>
That's stinkin amazing!

How/Where did you reference the knowledge for using %{} and how to
embed interpolation (Is this nested interpolation?)

%{} is the same as "", it's just a different form. And you can use
other delimiters, like %<> or %^^. The problem with Warren's code is
it's assuming that the stored string doesn't contain any }'s in it. And
it's not nested interpolation (although that's perfectly legal) - it's
a string with the symbols %{ (which mean nothing in a string), then
interpolation of #{s}, then the symbol }. This evaluates to "%{Hello,
today is #{msgDate}", which is evaluated to give you "Hello, today is
some-date-here".

However, if you choose to go this route, you have to be aware not only
of the issue I mentioned above (of an embedded } causing issues), but
also security. eval() is dangerous, especially on strings that come
from outside the script. Make sure you trust your database absolutely,
and read up on $SAFE (you may want to set a high $SAFE level when
evaluating this string).

IIRC, the proper way to set $SAFE for a block of code is

Thread.new do
  $SAFE = x # where x is the desired level
  # execute code here
end.value

The reason is because, IIRC, you cannot set $SAFE to a level lower than
it currently is, so if you did that in the main thread then the rest of
your program would be restricted. Doing it in a thread only restricts
that thread, and calling #value causes the main thread to wait for it
to end and returns its value.

Perhaps you should simply try using eRB to evalute your templates, so
you could store "Hello, today is <%= msgDate %>"? Alternately, there's
probably some other templating code out there, or you could write your
own.

···

On 10/18/05, Warren Brown <warrenbrown@aquire.com> wrote:

I agree - there are too many gotchas with a roll-your-own string
interpolation hack.
Also, Rails uses erb as one of its template options so you would be
compatible with that too. Here's some code to get you going:

require 'erb'

def erb(str, erb_binding)
  trim_mode = 1
  erb = ERB.new(str, $SAFE, trim_mode)
  erb.result(erb_binding)
end

src = "Hello, today is <%= msg_date %>"
msg_date = Time.now.strftime("%Y-%m-%d")
puts erb(src, binding)

#=> Hello, today is 2005-10-18

Regards,

Sean

···

On 10/18/05, Kevin Ballard <kballard@gmail.com> wrote:

Perhaps you should simply try using eRB to evalute your templates, so
you could store "Hello, today is <%= msgDate %>"? Alternately, there's
probably some other templating code out there, or you could write your
own.