2

我正在尝试编写一个简单的函数来对 ruby​​ 中的任意文本执行字符串插值。我还希望该函数不评估转义的插值块,以便将“\#{foo}”转换为“#{foo}”而不是评估。

当我传递带有转义块的表达式时,在我使用该puts方法时该值显示正确,但在我使用p. 我不明白为什么。

这是我的代码:

def evil_mark text
  part = text.partition(/[^\\]\#{.*?}/)
  return_string = part[0]
  until part[1] == ""
     return_string << eval("\"" + part[1] + "\"")
     part = evil_mark(part[2]).partition(/[^\\]\#{.*?}/)
     return_string << part[0]
  end
  return_string.gsub!(/\\\#{.*?}/){|s| s[1..-1]}
  return return_string
end

$foo = 'faz'
$bar = 'baz'

s = 'This is some \#{$foo} bar and some #{$bar} bat'

puts evil_mark s
#~> This is some #{$foo} bar and some baz bat

p evil_mark s
#~> "This is some \#{$foo} bar and some baz bat"

顺便说一句,我知道使用这种eval方法可能很危险。

4

2 回答 2

2

退货没什么问题。使用 #p 时它仍然出现转义的唯一原因是 p 打印字符串的方式基本上可以直接用作该字符串的 ruby​​ 代码。- 也就是说,#p 故意添加了转义。

于 2013-05-01T20:42:44.597 回答
1

请参阅Ruby 中的 p 与 puts,它说这p foo实际上不是 的简写,puts foo而是puts foo.inspect. 的值some_object.inspect将向您展示对象的内部结构,这些内部结构通常与对象的字符串表示不同。例如:

irb(main):004:0> "hello".inspect
=> "\"hello\""
irb(main):006:0> p "hello"
"hello"
=> "hello"
irb(main):005:0> puts "hello"
hello
=> nil

请注意如何p以与包含引号相同的方式包含引号inspect(尽管inspect显示它们已适当转义),而puts没有?

主要区别在于,inspect它将始终显示对象的内部结构,而puts将调用to_s(如果存在,则使用默认值to_s)。

于 2013-05-01T20:51:03.880 回答