2013-05-01 82 views
1

我正在嘗試編寫一個簡單的函數來對ruby中的任意文本執行字符串插值。我還希望函數不要評估轉義的插值塊,以便將「\#{foo}」轉換爲「#{foo}」而不是評估。使用Ruby的p方法打印字符串時出現額外的轉義字符

當我使用轉義塊傳遞表達式時,當我使用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

回答

1

p vs puts in Ruby,它說,p foo實際上不是簡寫puts fooputs foo.inspectsome_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時使用)。

+0

謝謝,Moshe。很好的解釋。在這個「問題」出現之前,我還沒有理解這種區別。 – 2013-05-01 20:54:58

2

回報沒有問題。使用#p時,它仍然出現轉義的唯一原因是p打印字符串的方式可以直接用作該字符串的ruby代碼。 - 也就是說#p爲故意添加了逃跑。

+0

啊!我懂了!現在似乎很明顯。謝謝! – 2013-05-01 20:50:01