Comment puis-je émuler les paramètres printf nommés de Python en Ruby?
Question
En Python, vous pouvez faire ceci:
print "Hi! I'm %(name)s, and I'm %(age)d years old." % ({"name":"Brian","age":30})
Quel est l'idiome de Ruby le plus simple et le plus simple pour reproduire ce comportement? (Aucun monkeypatching la classe String, s'il vous plaît.)
MODIFIER: L'un des avantages vraiment remarquables est que vous pouvez stocker la chaîne pré-traitée dans une variable et l'utiliser comme "modèle", comme suit:
template = "Hi! I'm %(name)s, and I'm %(age)d years old."
def greet(template,name,age):
print template % ({"name":name,"age":age})
C’est évidemment un exemple trivial, mais il est très utile de pouvoir stocker une telle chaîne pour une utilisation ultérieure. Ruby " Bonjour! Ma convention # {name} "
est similaire, mais l'évaluation immédiate la rend moins polyvalente.
N'envoyez pas de réponses suggérant la technique # {var}
, car elles venaient d'avant cette modification. (Noyau d’idée aléatoire: les réponses devraient peut-être être protégées des votes si l’auteur de la question les marque comme "obsolètes" ...?)
La solution
Vous pouvez également utiliser
printf "1: %<key1>s 2: %<key2>s\n", {:key1 => "value1", :key2 => "value2"}
ou
data = {:key1 => "value1", :key2 => "value2"}
printf "1: %<key1>s 2: %<key2>s\n", data
ou (cela nécessite Ruby 1.9, pour les autres exemples, je ne suis pas sûr)
data = {key1: "value1", key2: "value2"}
printf "1: %<key1>s 2: %<key2>s\n", data
Ceci imprime
1: value1 2: value2
Restriction importante: les clés utilisées du hachage ( data ??em> dans mon exemple) doivent être des symboles.
Une remarque sur l'exemple ci-dessus:
printf
prend une chaîne de format et des paramètres facultatifs. Mais il existe également une méthode String #%
.
Les quatre appels suivants ont tous le même résultat:
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 deuxième version utilise d'abord la méthode String #%
et envoie le résultat à printf
.
Autres conseils
vous le faites comme ça:
values = {:hello => 'world', :world => 'hello'}
puts "%{world} %{hello}" % values
Lisez ceci pour plus d’informations: http://ruby.runpaint.org/strings#sprintf-hash
Si vous avez besoin de quelque chose de plus sophistiqué, consultez ERB et les moteurs de modèles Google. Si vous devez générer des pages Web, des e-mails, etc., vous constaterez que l'utilisation de moteurs de modèles est une solution plus robuste.
Ruby contient quelques astuces intéressantes:
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
Puis appelez-le avec
t=Template.new
t%({:name => "Peter", :age => 18})
Ce n’est pas exactement ce que vous avez demandé, mais pourrait vous donner un indice.
Dans une chaîne à double guillemet en Ruby, vous pouvez insérer le résultat d'une expression Ruby comme ceci:
puts "Hi! I'm #{name}, and I'm #{age} years old."
Il suffit de mettre une expression à l’intérieur des accolades. (Il peut également s'agir de quelque chose de plus complexe, tel que # {age + 5}, ou # {name + '' + last_name}, ou un appel de fonction.)
Ce qui fonctionne (entre-temps), cependant, ressemble à quelque chose comme:
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"]]
met " Bonjour! Je suis {{name}} et j'ai {{age} ans. "