¿Cómo emulo los parámetros printf nombrados de Python en Ruby?
Pregunta
En Python, puede hacer esto:
print "Hi! I'm %(name)s, and I'm %(age)d years old." % ({"name":"Brian","age":30})
¿Cuál es el idioma de Ruby más cercano y simple para replicar este comportamiento? (No hay parches en la clase String, por favor).
EDITAR: Uno de los beneficios realmente excelentes de esto es que puede almacenar la cadena preprocesada en una variable y usarla como una "plantilla", así:
template = "Hi! I'm %(name)s, and I'm %(age)d years old."
def greet(template,name,age):
print template % ({"name":name,"age":age})
Obviamente, este es un ejemplo trivial, pero existe una gran utilidad para poder almacenar dicha cadena para su uso posterior. Ruby " ¡Hola! Mi convención # {name} "
es muy similar, pero la evaluación inmediata lo hace menos versátil.
Por favor, no rechace las respuestas que sugieran la técnica # {var}
, ya que provienen antes de esta edición. (Núcleo de idea aleatoria: tal vez las respuestas deberían protegerse de los votos si un autor de la pregunta las marca como "obsoletas" ...?)
Solución
También puedes usar
printf "1: %<key1>s 2: %<key2>s\n", {:key1 => "value1", :key2 => "value2"}
o
data = {:key1 => "value1", :key2 => "value2"}
printf "1: %<key1>s 2: %<key2>s\n", data
o (esto necesita ruby ??1.9, para los otros ejemplos no estoy seguro)
data = {key1: "value1", key2: "value2"}
printf "1: %<key1>s 2: %<key2>s\n", data
Esto imprime
1: value1 2: value2
Restricción importante: las claves usadas del hash ( datos en mi ejemplo) deben ser símbolos.
Una observación sobre el ejemplo anterior:
printf
toma una cadena de formato y parámetros opcionales. Pero también hay un String #%
-method.
Las siguientes cuatro llamadas tienen el mismo resultado:
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"}
La segunda versión usa primero el método String #%
y envía el resultado a printf
.
Otros consejos
lo haces así:
values = {:hello => 'world', :world => 'hello'}
puts "%{world} %{hello}" % values
Lea esto para más información: http://ruby.runpaint.org/strings#sprintf-hash
Si necesita algo más sofisticado, lea sobre ERB y los motores de plantillas de Google. Si necesita generar páginas web, correos electrónicos, etc., encontrará que usar motores de plantillas es una solución más sólida.
Hay un buen truco para esto en 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
Luego llámalo con
t=Template.new
t%({:name => "Peter", :age => 18})
Esto no es exactamente lo que pediste, pero podría darte una pista.
En una cadena entre comillas dobles en Ruby, puede insertar el resultado de una expresión Ruby como esta:
puts "Hi! I'm #{name}, and I'm #{age} years old."
Simplemente ponga una expresión dentro de las llaves. (También podría ser algo más complejo como # {age + 5}, o # {name + '' + last_name}, o una llamada de función).
Lo que funciona (mientras tanto), sin embargo, es algo similar a:
d = {"key1" => "value1", "key2" => "value2"}
s = "string to be magically induced with variables, which are \n * %s and \n * %s.\n"
print s%d.values()
# or
print s%[d["key1"], d["key2"]]
pone " ¡Hola! Tengo # {name} y tengo # {age} años. & Quot;