ruby – 在实例方法中使用mixin方法
为什么这不起作用:
class Myclass include HTTParty def dosomething base_uri("some_url") end end base_uri方法是HTTParty的类方法.如果我从我的类,任何实例方法之外或类方法中调用它,它工作正常,但是当尝试从实例方法调用它时,我得到“NoMethodError:undefined方法`base_uri’用于#” 为什么?不应该有一些方法从我的实例方法中引用HTTParty类,所以我可以调用那个HTTParty类方法? 我可以将它更改为类方法,但是我的类的每个实例都将具有相同的base_uri值. 解决方法
为什么不起作用?因为这不是Ruby的工作方式.同样,这不起作用:
class Foo def self.utility_method; ...; end def inst_method utility_method # Error! This instance has no method named "utility_method" end end 您可以通过以下方式解决此问题: class MyClass include HTTParty def dosomething HTTParty.base_uri("some_url") end end 让我们更深入地了解方法查找如何与模块一起工作.首先,一些代码: module M def self.m1; end def m2; end end class Foo include M end p Foo.methods - Object.methods #=> [] p Foo.new.methods - Object.methods #=> [:m2] class Bar extend M end p Bar.methods - Object.methods #=> [:m2] p Bar.new.methods - Object.methods #=> [] class Jim; end j = Jim.new j.extend M p j.methods - Object.methods #=> [:m2] 如我们所见,您可以使用extend来使对象(类或实例)使用模块的“实例”方法来处理对象本身(而不是实例),但是您不能使模块的“类方法”被任何东西继承.你能得到的最接近的是这个成语: module M2 module ClassMethods def m1; end # Define as an instance method of this sub-module! end extend ClassMethods # Make all methods on the submodule also my own def self.included(k) k.extend(ClassMethods) # When included in a class,extend that class with end # my special class methods def m2; end end class Foo include M2 end p Foo.methods - Object.methods #=> [:m1] p Foo.new.methods - Object.methods #=> [:m2] 如果HTTParty模块使用了上面的模式,所以在你的MyClass上使base_uri方法可用,那么你可以这样做: class MyClass include HTTParty def dosomething self.class.base_uri("some_url") end end …但这比直接引用拥有该方法的模块更有用. 最后,因为这可能对你有帮助,这是我几年前制作的图表. (它缺少Ruby 1.9中的一些核心对象,比如BasicObject,但是仍然适用.点击查看PDF版本.图中的注释#3特别适用.) Ruby Method Lookup Flow http://phrogz.net/RubyLibs/RubyMethodLookupFlow.png (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |