On 16 Jul 2005, at 01:23, Navindra Umanee wrote:

> Hi,
>
> I would like to partially expand a string and then further expand it
> later on when more information is available.  I am currently using
> string interpolation with a reeval method suggested by Bill Kelly.

is sprintf (aka %) unable to fulfill your requirements?

> class String
>   def reeval(b = TOPLEVEL_BINDING)
>     eval("<<END_REEVAL\n" + self + "\nEND_REEVAL\n", b).chomp!
>   end
> end
>
> This lets me do stuff like this:
>
> expanded = "one"
> delayed = "two"
>
> s = "#{expanded} \#{delayed}"       # => "one #{delayed}"
> s = s.reeval(binding)               # => "one two"

s = "#{expanded} %s"
s = s % delayed

> As a more complex example, this is a string I wish to partially  
> expand:
>
> options = [ 10,  20,  30,  40,  50 ]
>
> combobox =<<"END"
> ...
> #{options.map {|n|
> %{<option value="#{n}"\#{thread_threshold == n ?  ' SELECTED' : ''} 
> >#{n} comments</option>}
> }.join("\n")
> }
> ...
> END

combobox = <<END
...
%s
...
END

opts = options.map { |n| "<option value=\"#{n}\"%s>#{n} comments</ 
option>" }.join "\n"

combobox = combobox % opts

> and later when I reeval the string:
>
> thread_threshold = 50
> combobox.reeval(binding)
>
> the result should be:
>
> <option value="10">10 comments</option>
> <option value="20">20 comments</option>
> <option value="30">30 comments</option>
> <option value="40">40 comments</option>
> <option value="50" SELECTED>50 comments</option>

Hrm, maybe not...

How about:

opts = options.map { |n| "<option value=\"#{n}\"SEL_#{n}>#{n}  
comments</option>" }.join "\n"

combobox = combobox % opts

combobox.gsub!(/SEL_(\d+)/) do
   thread_threshold == $1.to_i ?  ' SELECTED' : ''
end

> Anyone have any ideas for how I can get a correct partial expansion?
>
> I have a lambda/closure feeling about how this should work, but I
> can't quite see the solution in the context of strings.

I think the reeval thing is the wrong way to go about it.  I find it  
much more useful to use a library that generates HTML programatically  
or from a template than to try fancy substitution tricks (unless its  
really small).  Eventually you end up with either a template language  
or programatic HTML generation in the end.

-- 
Eric Hodel - drbrain / segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E  7C11 332A 551C 796C 9F04