From: Kevin Ballard Date: 2005-10-19T02:46:58+09:00 Subject: Re: Expression Interpolation from input "template string"? Peter Fitzgibbons wrote: > On 10/18/05, Warren Brown 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.