0

我已经加载了一个带有 #{variable} 引用的字符串。我将如何解决字符串中的这些变量puts呢?

name="jim"
str="Hi #{name}"
puts str        

我希望将结果作为参数传递或保存到变量中,而不是放置。

4

5 回答 5

1

puts不解决变量。Ruby 解析器在创建字符串时执行此操作。如果您传递str给任何其他方法,则与传递“Hi jim”相同,因为插值已经完成。

于 2013-01-28T16:49:24.237 回答
1

你可以评估它

name = "Patrick"

s = 'hello, #{name}'
s # => "hello, \#{name}"

# wrap the string in double quotes, making it a valid interpolatable ruby string
eval "\"#{s}\"" # => "hello, Patrick"
于 2013-01-28T16:49:49.340 回答
1

String 有一个格式选项,显示为%. 它可用于将参数传递到预定义的字符串中,就像插值一样。

message = "Hello, %s"
for_patrick = message % "Patrick" #=> "Hello, Patrick"
for_jessie  = message % "Jessie"  #=> "Hello, Jessie"

messages = "Hello, %s and %s"
for_p_and_j = messages % ["Patrick", "Jessie"] #=> "Hello, Patrick and Jessie"

它可能看起来不像“Rubyish”,但我相信它是您正在寻找的功能。

因此,如果您有一个来自某个地方的字符串包含这些占位符,那么您可以将值作为参数传递,如下所示:

method_that_gets_hello_message % "Patrick"

这也将允许您只接受您期望的值。

message = "I can count to %d"
message % "eleven" #=> ArgumentError: invalid value for Integer()

维基百科上有一个可能的占位符列表printf(),它也应该在 Ruby 中工作。

于 2013-01-28T18:04:09.137 回答
0

听起来您需要模板系统的基础,如果您使用字符串gsubsub方法,Ruby 很容易做到这一点。

replacements = { '%greeting%' => 'Hello', '%name%' => 'Jim' }
pattern = Regexp.union(replacements.keys)
'%greeting% %name%!'.gsub(pattern, replacements)
=> "Hello Jim!"

您可以轻松地将密钥定义为:

replacements = { '#{name}' => 'Jim' }

并使用 Ruby 的普通字符串插值#{...},但我建议不要重用它。而是使用独特的东西。

这样做的好处是目标 => 替换映射可以很容易地放入 YAML 文件或数据库表中,然后您可以将它们换成其他语言或不同的用户信息。天空才是极限。

这样做的好处也是,不涉及评估,它只是字符串替换。通过一些创造性的使用,您实际上可以实现宏:

macros = { '%salutation%' => '%greeting% %name%' }
replacements = { '%greeting%' => 'Hello', '%name%' => 'Jim' }
macro_pattern, replacement_pattern = [macros, replacements].map{ |h| Regexp.union(h.keys) }
'%salutation%!'.gsub(macro_pattern, macros).gsub(replacement_pattern, replacements)
=> "Hello Jim!"
于 2013-01-28T18:35:57.860 回答
0

eval似乎是这个特定任务的唯一解决方案。但是如果我们稍微修改一下任务,我们可以避免这种肮脏的不安全的耻辱 :我们可以不使用eval本地变量而是实例变量:evalinstance_variable_get

@name = "Patrick"
@id = 2 # Test that number is ok
@a_b = "oooo" # Test that our regex can eat underscores

s = 'hello, #{name} !!#{id} ??#{a_b}'

s.gsub(/#\{(\w+)\}/) { instance_variable_get '@'+$1 }
=> "hello, Patrick !!2 ??oooo"

在这种情况下,您甚至可以使用任何其他字符来代替#{}(例如%name%等),只需稍微修改一下正则表达式。

但是,当然,这一切都闻起来了。

于 2013-01-28T17:49:16.703 回答