Как мне эмулировать именованные параметры printf Python в Ruby?
Вопрос
В Python вы можете сделать это:
print "Hi! I'm %(name)s, and I'm %(age)d years old." % ({"name":"Brian","age":30})
Какая самая близкая и простая идиома Ruby повторяет это поведение?(Пожалуйста, не используйте monkeypatching для класса String.)
Редактировать: Одним из действительно отличных преимуществ этого является то, что вы можете сохранить предварительно обработанную строку в переменной и использовать ее как "шаблон", вот так:
template = "Hi! I'm %(name)s, and I'm %(age)d years old."
def greet(template,name,age):
print template % ({"name":name,"age":age})
Очевидно, что это тривиальный пример, но есть много полезного в возможности сохранить такую строку для последующего использования.Руби "Hi! I'm #{name}"
условные обозначения внешне схожи, но непосредственная оценка делает их менее универсальными.
Пожалуйста, не отклоняйте ответы, предполагающие #{var}
техника, из которой они исходили до этой правки.(Ядро случайной идеи:Возможно, ответы следует защитить от голосования, если автор вопроса пометит их как "устаревшие" ...?)
Решение
Вы также можете использовать
printf "1: %<key1>s 2: %<key2>s\n", {:key1 => "value1", :key2 => "value2"}
или
data = {:key1 => "value1", :key2 => "value2"}
printf "1: %<key1>s 2: %<key2>s\n", data
или (для этого нужен ruby 1.9, для других примеров я не уверен)
data = {key1: "value1", key2: "value2"}
printf "1: %<key1>s 2: %<key2>s\n", data
Это печатает
1: value1 2: value2
Важное ограничение:Используемые ключи хэша (данные в моем примере) должны быть символами.
Замечание к приведенному выше примеру:printf
принимает одну строку формата и необязательные параметры.Но есть также String#%
-метод.
Следующие четыре вызова приводят к одному и тому же результату:
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"}
Во второй версии сначала используется String#%
-метод и отправляет результат в printf
.
Другие советы
ты делаешь это вот так:
values = {:hello => 'world', :world => 'hello'}
puts "%{world} %{hello}" % values
Прочтите это для получения дополнительной информации:http://ruby.runpaint.org/strings#sprintf-hash
Если вам нужно что-то более сложное, почитайте о ERB и движках шаблонов Google.Если вам нужно сгенерировать веб-страницы, электронные письма и т.д.вы обнаружите, что использование шаблонизаторов является более надежным решением.
В 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
Затем вызовите его с помощью
t=Template.new
t%({:name => "Peter", :age => 18})
Это не совсем то, о чем вы просили, но могло бы дать вам подсказку.
В строку, заключенную в двойные кавычки в Ruby, вы можете вставить результат выражения Ruby следующим образом:
puts "Hi! I'm #{name}, and I'm #{age} years old."
Просто заключите выражение в фигурные скобки.(Это также может быть что-то более сложное, например #{возраст + 5}, или #{имя + ' ' + фамилия}, или вызов функции.)
Однако то, что работает (пока), - это что-то вроде:
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"]]
выкладывает "Привет!Меня зовут #{имя}, и мне #{возраст} лет ".