字符串插值不适用于Ruby heredoc常量

时间:2014-11-23 15:15:36

标签: ruby-on-rails ruby interpolation heredoc

我有一个很长的常量定义,需要插值(实际的更长):

const = "This::Is::ThePath::To::MyModule::#{a_variable}".constantize

现在,为了使其更具可读性,我尝试使用heredocs创建多行字符串:

const = <<-EOT.constantize
  This::Is::ThePath::
  To::MyModule::#{a_variable}
EOT

但是当我执行它时,我得到一个NameError: wrong constant name。由于第一个例子正在工作,我认为它与字符串插值有关吗?

关于这出错的问题?

2 个答案:

答案 0 :(得分:2)

从Here-Document

中删除所有空格和换行符

在调用#constantize之前,您需要从插值的here-document中删除所有空格,制表符和换行符。以下自包含示例将起作用:

require 'active_support/inflector'

module This
  module Is
    module ThePath
      module To
        module MyModule
          module Foo
          end
        end
      end
    end
  end
end

a_variable = 'Foo'
const = <<EOT.gsub(/\s+/, '').constantize
  This::Is::ThePath::
  To::MyModule::#{a_variable}
EOT

#=> This::Is::ThePath::To::MyModule::Foo

答案 1 :(得分:1)

代替:

const = <<-EOT.constantize
  This::Is::ThePath::
  To::MyModule::#{a_variable}
EOT

使用:

const = <<-EOT.gsub(/\n/, '').constantize
  This::Is::ThePath::
  To::MyModule::#{a_variable}
EOT

这个创建字符串<<-EOF ... EOF的方法将\n放在行尾,然后constantize无法正常工作。删除了不受欢迎的字符\n, \t, \s,一切都应该有用。

看看我的测试用例:

conts = <<-EOF.constantize
=> ActionDispatch::Integration::Session
=> EOF

#> NameError: wrong constant name "Session\n"

conts = <<-EOF.chomp.constantize
=> ActionDispatch::Integration::Session
=> EOF
#> ActionDispatch::Integration::Session

对于很多行:

conts = <<-EOF
=> ActionDispatch::
=> Integration::
=> Session
=> EOF
=> "ActionDispatch::\nIntegration::\nSession\n"

修复它:

conts = <<-EOF.gsub(/\n/, '').constantize
=> ActionDispatch::
=> Integration::
=> Session
=> EOF
=> ActionDispatch::Integration::Session