了解acts_as_anything的创建

时间:2011-01-26 21:55:08

标签: ruby-on-rails ruby metaprogramming dsl

我成功创建了一个有一些类和模块的gem,可以在Rails项目中的任何类中使用类似的东西:

class AnyRubyOrActiveModelClass
  acts_as_anything [:foo, :bar]

  def foo
    .. do some foo
  end

  def self.bar
    .. do some bar
  end
end

为此,我在我的宝石中创建了一个看起来像这样的模块:

module InstanceMagic
  class << self.class.superclass
  define_method(:acts_as_anything) do |methods|
    self.class_eval do
      include ClassMagic
      .. do some alias_method with given methods
    end
  end
end

这个模块成功地使我的方法别名:foo来自上面的例子,第二个模块ClassMagic对我的:bar类方法做了同样的事情(遵循here的建议)。

在测试项目中,该方法运行良好。在一个真实的项目中,它导致了对另一个宝石的干涉,采取了一种 - 也许是类似的 - 方法。这个宝石抱怨在类中缺少方法,即使我只将我的宝石集成到项目中 - 甚至没有集成acts_as_anything到类中。

所以我把我的代码分解为:

module InstanceMagic
  class << self.class.superclass
  define_method(:acts_as_anything) do |methods|
    #really empty here
  end
end

结果,其他宝石仍然破裂。

我使用了类&lt;&lt; self.class.superclass显式扩展Object,因此即使非ActiveSomething类也会影响所有类,并且我的acts_as_anything可用。所以我还有三个问题。

为什么最后5行代码会破坏另一个gem并让它抱怨它试图动态创建缺少的方法?我想了解。

有没有更好的方法来实现我的目标?

当我使用method_added和singleton_method_added(我在模块中实际执行的操作)时,我应该查找这些方法是否已经存在,别名为“原始”方法,插入我的方法并在完成后调用原始方法工作

知道这很多我仍然希望有人能指出我正确的方向。

谢谢。 菲利克斯

1 个答案:

答案 0 :(得分:0)

我唯一能想到的是某种顺序依赖(远射)。尝试将您的代码放在rails应用程序的初始化程序中,看看它是否仍会导致同样的问题。

相关问题