看来,在(双引号)heredoc中使用gsub
不会评估gsub
的结果,如下所示:
class Test
def self.define_phone
class_eval <<-EOS
def _phone=(val)
puts val
puts val.gsub(/\D/,'')
end
EOS
end
end
Test.define_phone
test = Test.new
test._phone = '123-456-7890'
# >> 123-456-7890
# >> 123-456-7890
第二个puts
应该已经打印1234567890
,就像在这种情况下一样:
'123-456-7890'.gsub(/\D/,'')
# => "1234567890"
heredoc里面发生了什么事?
答案 0 :(得分:5)
问题出在正则表达式中的\D
上。将Heredoc评估为字符串时,将对其进行评估,结果为D
:
"\D" # => "D"
eval("/\D/") #=> /D/
另一方面,单引号内的\D
不会被评估为D
:
'\D' # => "\\D"
eval('/\D/') # => /\D/
因此,将Heredoc终止符EOS
括在单引号中以实现所需的内容:
class Test
def self.define_phone
class_eval <<-'EOS'
def _phone=(val)
puts val
puts val.gsub(/\D/,'')
end
EOS
end
end
Test.define_phone
test = Test.new
test._phone = '123-456-7890'
# >> 123-456-7890
# >> 1234567890
如果运行上面的代码时没有包装EOS
,gsub
将尝试在val
中替换“ D”(字面上)。看到这个:
test._phone = '123-D456-D7890DD'
# >> 123-D456-D7890DD
# >> 123-456-7890