Как я могу создать глобальные КОНСТАНТЫ пространства имен во время инициализации Rails в Tomcat?

Сначала немного предыстории: у меня есть приложение Rails 2.2.2 со всеми видами зависимостей и настроек, которые не позволяют мне обновиться до 2.2.2. Текущий план состоит в том, чтобы перенести это приложение в JRuby (1.6.5), развернув его как войну в Tomcat (6.0.23 - еще не привязанную к этой конкретной версии FWIW), используя warbler (1.3.2) для его упаковки.

Я хочу, чтобы ветка JRuby приложения существенно не отличалась от приложения vanilla, поскольку я не знаю, сколько времени потребуется, чтобы выявить и устранить все проблемы, вызванные несоответствиями в средах выполнения. Так что я хочу иметь возможность продолжать чистое и легкое объединение в текущей работе из приложения vanilla.

Ряд настраиваемых поведений в приложении можно настроить с помощью глобальных констант пространства имен, установленных в environments/*.rb файлы. Но эти значения могут быть переопределены с помощью файла конфигурации yaml или установки переменной среды оболочки; это прежде всего для гибкости в процессе разработки, где разные разработчики иногда должны настраивать различные параметры. До сих пор эта система работала хорошо, оставляя environments/development.rb файл относительно стабилен и не перегружен, но все же дает нам большой контроль над настройкой во время взлома.

Я хотел бы сохранить эту систему настройки при переходе на JRuby. Пока я использую настроенный config/web.xml.erb который преобразует соответствующие переменные окружения и настройки из файла yaml в <env-entry> фрагменты, что делает их доступными во время инициализации через java:comp/env JNDI контекст. В более ограниченных средах (таких как подготовка или производство) многие из этих настроек могут быть заблокированы путем включения соответствующих <Environment> настройки в контейнере context.xml файл с override атрибут установлен в false,

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

конфигурации / среда /developer.rb:

...
envset "FOO", "baz"
FOO="fail" unless defined? FOO
printf "FOO is now '%s'\n", FOO
 ...

Библиотека / config_helper.rb:

1  include Java
2  import javax.naming.InitialContext
3  import javax.naming.NameNotFoundException
4  
5  ctx = InitialContext.new
6  
7  def envset(value_name, default_value)
8      value = nil
9      begin
10         value = ctx.lookup("java:comp/env/#{value_name}")
11     rescue NameNotFoundException => e
12         value = default_value
13     end
14     printf "setting %s to '%s'\n", value_name, value
15     eval("%Q[ #{value_name} = '#{value}' ]")
16 end

web.xml:

...
<env-entry>
    <env-entry-name>FOO</env-entry-name>
    <env-entry-value>bar</env-entry-value>
    <env-entry-type>java.lang.String</env-entry-type>
</env-entry>
...

catalina.out:

setting FOO to 'bar'
FOO is now 'fail'

Там, где я ожидаю, что эта последняя строка будет "FOO теперь" бар "", конечно. Линия 14 из lib/config_helper.rb Кажется, там все идет не так. Подобный код отлично работал в vanilla ruby, но здесь он не работает во время инициализации в Tomcat.

Итак, как я могу создать глобальные КОНСТАНТЫ пространства имен из записей среды JNDI во время инициализации Rails в Tomcat?

1 ответ

Решение

Хорошее эмпирическое правило заключается в том, что всегда есть лучший ответ, чем eval(), Замена строки 15 следующей строкой корректно создает константы в глобальном пространстве имен:

Object.const_set(value_name, value)

Я до сих пор не уверен, в каком пространстве имен исходные константы создавались, но Object кажется "глобальным".

Другие вопросы по тегам