Как разрешить конфликт имен между Hash#slice i18n и Hash#slice ActiveSupport

Я работаю над проектом Rails 2.3.14, в котором используется 0.6.0 гема i18n и 2.3. .14 ​​драгоценного камня ActiveSupport. Оба они определяют метод Hash#slice (i18n). ; ActiveSupport), но они функционируют по-разному: версия i18n использует Hash#fetch и поэтому вызывает исключение i18n/core_ext/hash.rb:4:in 'fetch': key not found (IndexError), если какой-либо запрошенный ключ отсутствует, в то время как версия ActiveSupport счастливо игнорирует отсутствующие ключи, а остальная часть ActiveSupport зависит от этого счастливого игнорирования.

В моем приложении версия i18n загружается первой (потому что, кстати, фейкер загружает ее как зависимость), поэтому, когда ActiveSupport пытается зависеть от поведения игнорирования отсутствующих ключей, я получаю исключение.

Есть ли способ указать Rails загружать ActiveSupport перед подделкой и i18n?


person TALlama    schedule 11.01.2012    source источник


Ответы (4)


Вы также можете исправить класс Hash после того, как драгоценные камни потребуются. Вы можете просто вставить содержимое файла hash/slice.rb ActiveSupport куда-нибудь в свое приложение. URL-адрес можно найти здесь:

https://github.com/lifo/docrails/blob/master/activesupport/lib/active_support/core_ext/hash/slice.rb

Однако это переопределит определения из драгоценных камней, поэтому YMMV.

person Eugene    schedule 11.01.2012

Я использовал идею @Eugene вернуться к методу ActiveSupport (и поэтому он получает счастливую зеленую галочку), но сделал это таким образом, чтобы избежать дублирования кода. Сначала мы проверяем, используем ли мы версию i18n, и если да, то используем remove_method, чтобы стереть ее (она была добавлена ​​при открытии класса) и позволить модулю ActiveSupport 2.3.14 заполниться (обратите внимание, что я этого не делал). используйте undef, что также стирает переопределение модуля).

Итак, в инициализатор входит код:

begin
    {}.slice(:a) # ActiveSupport's slice is fine with this; i18n's is not
rescue IndexError
    class Hash
        remove_method :slice #kill i18n's implementation, allow the ActiveSupport module to work
    end
end
person TALlama    schedule 11.01.2012
comment
Гораздо чище, чем мой путь. Слава! - person Eugene; 12.01.2012

Если вы не можете контролировать порядок загрузки, вы можете попробовать метод, описанный в этом сообщении в блоге http://banisterfiend.wordpress.com/2010/11/04/baking-module-methods-into-classes.-with-alias_method/

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

person iain    schedule 11.01.2012
comment
Вы также можете попробовать поместить Faker в тестовую группу, используя упаковщик. - person iain; 11.01.2012
comment
К сожалению, мы все еще на 1.8.7; обновит вопрос, чтобы отразить это. И с фейкером в тестовой группе он по-прежнему не соответствует требованиям. - person TALlama; 11.01.2012

Я открыл вопрос по проекту i18n, чтобы сделать слайс более безопасным, и создал PR для его реализации. Вы можете найти проблему / PR на https://github.com/svenfuchs/i18n/pull/292. .

Чтобы вручную исправить себя, вы можете просто добавить if has_key?(key) после выборки.

person Brett    schedule 01.10.2014