如何从gem扩展类?

时间:2014-05-08 22:11:05

标签: ruby-on-rails ruby ruby-on-rails-3 gem

我写了一个宝石,其中包含一些我想分享的基本逻辑。我发布它,安装它,使用它。

我认为还有一些其他功能是针对我的项目特定于案例的。我想使用相同的类名添加其他方法,因为它很熟悉,并且我很容易记住所有方法。

如何安装gem,然后添加方法而不会发生冲突?我过去曾在宝石中定义了覆盖的方法(特别是Devise方法),但在需要扩展类本身时从未绊倒过。

1 个答案:

答案 0 :(得分:7)

你只是open the class and add methods。如果您知道类的名称以及它在模块层次结构中的位置,那么您只需创建另一个定义相同类的文件并开始添加方法。由于它是相同的类名,因此方法将被添加到另一个类中。

这可能与您对Devise所做的相似。

因此,如果我在gem中有类Bar,并且它位于名为Foo的模块中

# in the gem
module Foo
  class Bar
    def foobar
      'foobar!'
    end
  end
end

要向此类添加一个名为baz的方法,而不修改gem源代码,那么在您的应用程序中只需创建一个新文件,再次在其模块中声明该类,然后开始添加内容。

# in some other file in your app
module Foo
  class Bar
    def baz
      'foobar baz!'
    end
  end
end

 > f = Bar.new
 > f.foobar
=> 'foobar!'
 > f.baz
=> 'foobar baz!'

由于每个模块只能有一个给定名称类的副本,因此只需再次声明该类就可以为现有类添加功能。

如果您希望在不更改应用中所有baz对象实例的功能的情况下为Bar方法提供一些新类,请改为扩展Bar。这将使您的新课程具有所有Bar功能,新功能,而无需修改您在应用中其他地方使用的Bar个实例的功能

class NewClass < Foo::Bar
  def baz
    'foobar baz!'
  end
end

 > nc = NewClass.new
 > nc.foobar
=> 'foobar!'
 > nc.baz
=> 'foobar baz!'