1

我正在开发一个 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

4 回答 4

1

您还可以在需要 gem 之后对 Hash 类进行修补。您可以将 ActiveSupport 的 hash/slice.rb 的内容粘贴到您的应用程序的某个位置。网址可以在这里找到:

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

但是,这将覆盖 gems 中的定义,所以 YMMV。

于 2012-01-11T17:53:26.790 回答
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
于 2012-01-11T19:49:49.937 回答
0

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

我已经使用它并且它对我有用,但那是我自己编写的模块。

于 2012-01-11T17:46:39.553 回答
0

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

要手动修补自己,您可以if has_key?(key)在 fetch 之后添加。

于 2014-10-01T10:39:48.400 回答