在内部使用“ gsub”(双引号)heredoc不起作用

时间:2018-11-26 03:18:44

标签: ruby literals heredoc

看来,在(双引号)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里面发生了什么事?

1 个答案:

答案 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

Reference

如果运行上面的代码时没有包装EOSgsub将尝试在val中替换“ D”(字面上)。看到这个:

test._phone = '123-D456-D7890DD'
# >> 123-D456-D7890DD
# >> 123-456-7890