简体   繁体   English

如何从gem扩展类?

[英]How can I extend a class from a gem?

I wrote a gem with some basic logic that I wanted to share. 我写了一个宝石,其中包含一些我想分享的基本逻辑。 I publish it, install it, use it. 我发布它,安装它,使用它。

There are additional functions which I think are case-specific to my project. 还有其他功能,我认为这些功能特定于我的项目。 I want to add additional methods using the same class name because it's familiar and everything is easy for me to keep track of mentally. 我想使用相同的类名添加其他方法,因为它很熟悉,并且我很容易记住心理状态。

How can I install a gem, then add methods to it without conflict? 如何安装gem,然后添加方法而不会发生冲突? I have in the past overwritten methods defined in gems (notably Devise methods), but never tripped upon needing to expand the class itself. 我过去曾在宝石中定义了覆盖的方法(特别是Devise方法),但在需要扩展类本身时从未绊倒过。

You just open the class and add methods . 您只需打开该类并添加方法即可 If you know the name of the class and where it is in the module hierarchy, then you just create another file that defines the same class and start adding methods. 如果您知道类的名称以及它在模块层次结构中的位置,那么您只需创建另一个定义相同类的文件并开始添加方法。 Since it's the same class name the methods will get added to the other class. 由于它是相同的类名,因此方法将被添加到另一个类中。

It's probably similar to what you did with Devise. 它可能类似于你对Devise所做的。

So if I have class Bar in a gem, and it's inside a module called Foo 所以,如果我在宝石中有类Bar ,它就在一个名为Foo的模块中

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

To add a method called baz to this class, without modifying the gem source code, then in your application just create a new file, declare the class inside its module again, and start adding stuff. 要向此类添加一个名为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!'

Since there can only be one copy of a class of a given name per module, then simply declaring the class again adds functionality to the existing class. 由于每个模块只能有一个给定名称类的副本,因此只需再次声明该类就可以为现有类添加功能。

If you want to instead give some new class the baz method without changing the functionality of all Bar object instances in your app, then extend Bar instead. 如果你想在不改变应用程序中所有Bar对象实例功能的情况下给baz方法提供一些新类,那么请改为扩展Bar This will have the effect that your new class will have all Bar functionality, plus the new functionality, without modifying the functionality of Bar instances you may be using elsewhere in your app. 这将使您的新类具有所有Bar功能新功能,而无需修改您可能在应用程序中的其他位置使用的Bar实例的功能。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在gem中扩展ApplicationController? - How can I extend ApplicationController in a gem? 如何在 Rails 6/Zeitwerk 中扩展 gem class 而不破坏代码重新加载? - How can I extend gem class in Rails 6/Zeitwerk without breaking code reloading? 如何从已安装的 Spree gem 的 controller 扩展我的 controller? - How can I extend my controller from installed Spree gem's controller? 如何区分我自己的 class 和 gem 的 class - How can I disambiguate my own class from a gem's class 如何防止 Ruby 瞄准 gem 的 class 而不是我的 class? - How can I prevent Ruby from targeting a gem's class instead of my class? 包含或扩展gem中的类/模块(例如,设计) - Include or extend a class/module from a gem (e.g. devise) 如何在不继承ActiveRecord :: Base的类中使用Paperclip gem for Rails? - How can I use Paperclip gem for Rails in a class that does not inherit from ActiveRecord::Base? Rails:如何扩展gem的ActiveRecord子类? - Rails: how to extend a gem's ActiveRecord child class? 在Ruby on Rails中,安装“ gem”后 <gem_name> ”,如何使其扩展Array,或使用其类方法? - In Ruby on Rails, after “gem install <gem_name>”, how to make it extend Array, or use its class method? 如何在我的gem中扩展ApplicationController? - How to extend ApplicationController in my gem?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM