使用Ruby的p方法打印字符串时出现额外的转义字符

时间:2013-05-01 20:32:46

标签: ruby string

我正在尝试编写一个简单的函数来对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方法会很危险。

2 个答案:

答案 0 :(得分:2)

回归没有问题。使用#p时它仍然出现转义的唯一原因是p打印字符串的方式是它本质上可以直接用作该字符串的ruby代码。 - 也就是说#p故意将逃跑添加回来。

答案 1 :(得分:1)

请参阅p vs puts in Ruby,其中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用的)。