In Python, you can do this:
print "Hi!  I'm %(name)s, and I'm %(age)d years old." % ({"name":"Brian","age":30})
What's the closest, simplest Ruby idiom to replicate this behavior? (No monkeypatching the String class, please.)
One of the really excellent benefits of this is that you can store the pre-processed string in a variable and use it as a "template", like so:
template = "Hi!  I'm %(name)s, and I'm %(age)d years old."
def greet(template,name,age):
    print template % ({"name":name,"age":age})
This is obviously a trivial example, but there is a lot of utility in being able to store such a string for later use.  Ruby's "Hi!  I'm #{name}" convention is cursorily similar, but the immediate evaluation makes it less versatile.
You can also use
printf "1: %<key1>s 2: %<key2>s\n", {:key1 => "value1", :key2 => "value2"}
or
data = {:key1 => "value1", :key2 => "value2"}
printf "1: %<key1>s 2: %<key2>s\n",  data
or (this needs ruby 1.9, for the other examples I'm not sure)
data = {key1: "value1", key2: "value2"}
printf "1: %<key1>s 2: %<key2>s\n", data
This prints
1: value1 2: value2
Important restriction: The used keys of the hash (data in my example) must be symbols.
A remark on the example above:
printf takes one format string and optional parameters. But there is also a String#%-method.
The following four calls have all the same result:
printf "1: %<key1>s 2: %<key2>s\n" , {:key1 => "value1", :key2 => "value2"}
printf "1: %<key1>s 2: %<key2>s\n" % {:key1 => "value1", :key2 => "value2"}
print  "1: %<key1>s 2: %<key2>s\n" % {:key1 => "value1", :key2 => "value2"}
puts   "1: %<key1>s 2: %<key2>s"   % {:key1 => "value1", :key2 => "value2"}
The second version uses first the String#%-method and sends the result to printf.
you do it like this:
values = {:hello => 'world', :world => 'hello'}
puts "%{world} %{hello}" % values
Read this for more info: http://ruby.runpaint.org/strings#sprintf-hash
If you need something more sophisticated, read about ERB, and google template engines. If you need to generate web pages, emails etc. you'll find that using template engines is a more robust solution.
There are some nice trick to this in Ruby:
name = "Peter"
@age = 15 # instance variable
puts "Hi, you are #{name} and your age is #@age"
                         class Template
  def %(h)
    "Hi!  I'm #{h[:name]}s, and I'm #{h[:age]}d years old."
  end
end
Then call it with
t=Template.new
t%({:name => "Peter", :age => 18})
This is not exactly what you asked for but could give you a hint.
In a double-quoted string in Ruby, you can insert the result of a Ruby expression like this:
puts "Hi!  I'm #{name}, and I'm #{age} years old."
Just put an expression inside the curly braces. (It could also be something more complex like #{age + 5}, or #{name + ' ' + last_name}, or a function call.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With