如何解决i18n的Hash#slice和ActiveSupport的Hash#slice之间的名称冲突

时间:2012-01-11 17:39:26

标签: ruby-on-rails ruby activesupport faker i18n-gem

我正在开发一个Rails 2.3.14项目,该项目使用0.6.0的i18n gem和2.3.14的ActiveSupport gem。这两个方法都定义了Hash#slice方法(i18n's; ActiveSupport's),但它们的功能不同:i18n版本使用Hash#fetch,因此会引发i18n/core_ext/hash.rb:4:in 'fetch': key not found (IndexError)异常如果缺少任何请求的密钥,而ActiveSupport版本很乐意忽略丢失的密钥,而ActiveSupport的其余部分则依赖于那个快乐的忽略。

在我的应用程序中,i18n版本首先加载(因为,顺便说一句,faker正在加载它作为依赖项),因此当ActiveSupport尝试依赖ignore-missing-keys行为时,我得到了异常。

有没有办法告诉Rails在faker和i18n之前加载ActiveSupport?

4 个答案:

答案 0 :(得分:1)

您还可以在需要宝石后对Hash类进行修补。您可以将ActiveSupport的hash / slice.rb的内容粘贴到您的应用程序中。 URL可以在这里找到:

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

那会覆盖宝石的定义,所以YMMV。

答案 1 :(得分:1)

我使用@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

答案 2 :(得分:0)

如果您无法控制加载顺序,可以尝试使用此博文中的方法http://banisterfiend.wordpress.com/2010/11/04/baking-module-methods-into-classes-with-alias_method/

我已经习惯了,它对我有用,但那是我自己编写的模块。

答案 3 :(得分:0)

我在i18n项目上打开了一个问题,让切片更加安全,并创建了一个PR来实现它。您可以在https://github.com/svenfuchs/i18n/pull/292找到问题/公关。

要手动修补自己,您只需在获取后添加if has_key?(key)