Интерполяция строк не работает для константы Ruby 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. Поскольку первый пример работает, я предполагаю, что это связано с интерполяцией строк?

Любые мысли о том, где это происходит не так?


person Severin    schedule 23.11.2014    source источник


Ответы (2)


Удалите все пробелы и новые строки из документа Here-Document

Вам нужно удалить все пробелы, табуляции и новые строки из интерполированного здесь-документа, прежде чем вызывать #constantize. Будет работать следующий автономный пример:

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
person Todd A. Jacobs    schedule 23.11.2014

вместо:

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
person Зелёный    schedule 23.11.2014
comment
Не имеет значения, что я могу сказать по сообщению об ошибке? - person Severin; 23.11.2014
comment
Необходимо удалить не только последнюю новую строку, но и новую строку между двумя строками и начальные пробелы. - person matt; 23.11.2014
comment
для нескольких строк используйте .gsub(/\n/, '') вместо chomp - person Зелёный; 23.11.2014