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