In Ruby you can reference variables inside strings and they are interpolated at runtime.
For example if you declare a variable foo
equals \"Ted\
Using daniel-lucraft's answer as my base (as he seems to be the only one that answered the question) I decided to solve this problem in a robust manner. Below you will find the code for this solution.
# encoding: utf-8
class String
INTERPOLATE_DELIMETER_LIST = [ '"', "'", "\x02", "\x03", "\x7F", '|', '+', '-' ]
def interpolate(data = {})
binding = Kernel.binding
data.each do |k, v|
binding.local_variable_set(k, v)
end
delemeter = nil
INTERPOLATE_DELIMETER_LIST.each do |k|
next if self.include? k
delemeter = k
break
end
raise ArgumentError, "String contains all the reserved characters" unless delemeter
e = s = delemeter
string = "%Q#{s}" + self + "#{e}"
binding.eval string
end
end
output =
begin
File.read("data.txt").interpolate(foo: 3)
rescue NameError => error
puts error
rescue ArgumentError => error
puts error
end
p output
for the input
he #{foo} he
you get the output
"he 3 he"
The input
"he #{bad} he\n"
will raise a NameError exception. And the input
"\"'\u0002\u0003\u007F|+-"
will raise and ArgumentError exception complaining that the input contained all available delimiter characters.
Well, I second stesch's answer of using erb in this situation. But you can use eval like this. If data.txt has contents:
he #{foo} he
Then you can load and interpolate like this:
str = File.read("data.txt")
foo = 3
result = eval("\"" + str + "\"")
And result
will be:
"he 3 he"