Change the symbol in an interpolated string value?

PROBLEM:
I would like to be able to change the symbol in an interpolated string
value.
For example:

before

whoever = “World”;
message = “Hello #{whoever}”;
puts message;

after

whoever = “World”;

message = “Hello @{whoever}”; ## one arbitrary example

message = “Hello ${whoever}”; ## another example

message = “Hello ???{whoever}”; ## yet another

message = “Hello whoever”; ## or even yet another, no

braces this time
puts message;

I would like to be able to make it so any of the commented-out
versions could work, just as the “before” version works.

What’s the ruby-way of doing this?

On Jan 2, 9:23 pm, [email protected] wrote:

after

What’s the ruby-way of doing this?

You can do it with regular expressions or a parser, but you
shouldn’t…it will be much slower (and I mean like a gabazillion
times slower), and almost certainly less robust (e.g., handling nested
symbols), than the built-in interpolation syntax. Why do you need a
different syntax?

Regards,
Jordan

whoever = “World”;
message = “Hello #{whoever}”;

#1 You could use evil eval:

whoever = "World"
eval '"Hello #{whoever}"'

Because of the single quotes the string doesn’t get expanded.

#2 Use erb (http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/)

#1 You could use evil eval:
#2 Use erb (http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/)

Sorry, it seems I totally misunderstood your question … which I
don’t quite understand now after reading it again. You could use gsub
(maybe in conjunction with a block to look up variable values) but
why …

Why do you need a
different syntax?

Regards,
Jordan

It’s not a dire need, but it would definitely be useful. For example,
suppose you are constructing a string that generates ruby code. You
will need a way to tell the parser that #{foobar} is no longer
intended as a variable placeholder.

You could, of course, change the entire string into an uninterpolated
string, but that eliminates the ability to specify variables entirely.

Just to let you know this is not an original idea that I cooked up out
of thin air, see how Python supports this feature in:

http://www.python.org/dev/peps/pep-0292/

and search for the text:

define a delimiter character other than '$'

ALTERNATIVE QUESTION:

I’ve used ERB before, does it enable you to specify alternate syntaxes
for the variable placeholders? Template::Toolkit (as an example) does
allow this, if you want more details on what I am asking about, take a
look at:

http://template-toolkit.org/docs/manual/Syntax.html

Thanks for your responses so far.

On Jan 2, 2008 7:25 PM, [email protected] wrote:

after

What’s the ruby-way of doing this?

Well, the ruby way would be to simply use the #{} for interpolation.
but
if you’re looking to do arbitrary token replacements…

delim = Regexp.quote(‘???’)
replacements = { … }
string.gsub(/#{delim}{([^}]+)}/){ replacements[$1] }

would work by replacing ???{yargh} with replacements[‘yargh’]

I’ve used ERB before, does it enable you to specify alternate syntaxes
for the variable placeholders? Template::Toolkit (as an example) does
allow this, if you want more details on what I am asking about, take a
look at:

Short answer: No.

On Jan 3, 7:15 am, [email protected] wrote:

define a delimiter character other than '$'

Thanks for your responses so far.
Hmm…what about using %q{} or escaping “#”? You can emulate the
python Template class (which I have never actually used in live python
code, since % has always worked for my needs); but since it will be
slower (benchmark Template.substitute against % in python), and you
can do the same thing in different ways, it seems pointless to me.
But, for completeness, here is an example:

class Template < String
def substitute(context=nil)
if /@{(.+?)}/ =~ self
self.gsub("@{#{$1}}", eval($1, context))
else
self
end
end
end

blah = “foo”
t = Template.new(“Hello @{blah}”).substitute(binding)
p t # => “Hello foo”
t = Template.new(“Hello world”).substitute
p t # => “Hello world”

Regards,
Jordan

(maybe in conjunction with a block to look up variable values) but
why …

I think you understood, take a look at my reply to Monkee for more
details.

Thanks

Some years ago amrita or so was “more” actively developed. IIRC misen
was an effort to create a template engine that provides the kind of
flexibility you’re looking for. Or maybe not. Both projects seem
rather moribund now though.

If you use a gsub-based solution (as proposed by Scytrin), you might
also want to think about how to escape the markers.

On Jan 5, 5:27 am, MonkeeSage [email protected] wrote:

It’s not a dire need, but it would definitely be useful. For example,
PEP 292 – Simpler String Substitutions | peps.python.org
look at:
But, for completeness, here is an example:

blah = “foo”
t = Template.new(“Hello @{blah}”).substitute(binding)
p t # => “Hello foo”
t = Template.new(“Hello world”).substitute
p t # => “Hello world”

Regards,
Jordan

Yes, PEP292 Template strings are probably rarely ever used in
production, or even at all,
(that’s speculation here, but doubtless accurate) and the performance
issue
and other points you mentioned are of course well stated. There
are ,however,
instances where this specific feature is actually very useful and a
huge
time-saver.

Nevertheless, thanks for the responses and overview.