Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I emulate Python's named printf parameters in Ruby?

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.

like image 850
Max Cantor Avatar asked Oct 13 '08 06:10

Max Cantor


5 Answers

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.

like image 170
knut Avatar answered Oct 18 '22 11:10

knut


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.

like image 36
Michael Kruglos Avatar answered Oct 18 '22 12:10

Michael Kruglos


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"
like image 45
Honza Avatar answered Oct 18 '22 11:10

Honza


 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.

like image 43
Jonke Avatar answered Oct 18 '22 12:10

Jonke


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.)

like image 42
Paige Ruten Avatar answered Oct 18 '22 11:10

Paige Ruten