Строковая интерполяция, когда не используется строковый литерал - PullRequest
14 голосов
/ 14 марта 2009

У меня есть скрипт Ruby, который использовал интерполяцию строк для создания сообщений об ошибках.

p "#{vName} is not a defined variable"  => 'xxx is not a defined variable'

Другой программист попытался перенести строковые литералы в отдельный файл конфигурации. Конечно, он не получает замену.

p err_string_from_config  => '#{vName} is not a defined variable'

Я оглянулся, но не смог придумать ничего лучше, чем преобразование в строки sprintf и использование printf.

Кто-нибудь знает, как заставить подстановку # {} работать со строками, которые не являются литералами в двойных кавычках в скрипте Ruby?

Ответы [ 3 ]

21 голосов
/ 14 марта 2009

На самом деле Ruby обладает функциональностью, очень похожей на пример с Python Джона:

$ irb
>> greeting = 'hello %s, my name is %s!'
>> interpolated = greeting % ['Mike', 'John']
=> "hello Mike, my name is John!"
>>

Это также полезно, если ваш аргумент является константой массива. Если вы должны использовать интерполяцию в стиле {{}, вы можете использовать eval:

>> greeting = 'hi #{name}'    # notice name is not defined yet
>> name = "mike"
>> eval '"' + greeting + '"'

Подход eval будет намного медленнее, чем использование интерполяции в стиле%, так что это компромисс.

2 голосов
/ 14 марта 2009

Я предлагаю вам взглянуть на Жидкий шаблонизатор , который предоставляет более мощные функции (например, вы можете ссылаться на параметры по имени). Предыдущий пример будет выглядеть так:

greeting = Liquid::Template.parse("hello {{your_name}}, my name is {{my_name}}!")
interpolated = greeting.render('your_name' => 'Mike', 'my_name' => 'John')
# => "hello Mike, my name is John!"
1 голос
/ 14 марта 2009

Вот как я это делаю, просто для записи. Немного понятнее, имо.

gief = '#{later} please'
later = "later"

puts eval(%Q["#{gief}"])
# => later please

Но, честно говоря, это такой хак. Если у вас нет действительно веской причины использовать строку, используйте вместо нее процедуру. Я всегда стараюсь использовать простой рубин вместо проверки строк.

gief = Proc.new {|l| "#{l} please" }
later = "later"

puts gief.call(later)
# => later please
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...