Ruby 有没有办法对类方法和实例方法使用相同的代码?
有没有办法对类方法和实例方法使用相同的代码 例如,我想做以下工作:Ruby 有没有办法对类方法和实例方法使用相同的代码?,ruby,Ruby,有没有办法对类方法和实例方法使用相同的代码 例如,我想做以下工作: Module MyModule def method_in_module puts "hello" end class SomeClass def some_method method_in_module end end end 然后我希望能够做到这一点: SomeClass.method_in_module 还是这个 a = SomeClass.new
Module MyModule
def method_in_module
puts "hello"
end
class SomeClass
def some_method
method_in_module
end
end
end
然后我希望能够做到这一点:
SomeClass.method_in_module
还是这个
a = SomeClass.new
a.method_in_module
我想我可以有两个方法,一个是self.class\u method\u in_模块,一个是instance\u method\u in_模块,然后将它们包含在类中,在我的实例类中,但是代码是相同的。您可以使用module.included钩子用模块扩展类
module MyModule
def self.included(base)
base.extend MyModule
end
def method_in_module
puts "foo"
end
end
class SomeClass
include MyModule
end
SomeClass.new.method_in_module
# => foo
SomeClass.method_in_module
# => foo
必须记住,类和实例具有不同的作用域。因此,在类范围内工作良好的方法可能在类范围内工作不太好
理想情况下,我建议在类级别定义方法,并从实例级别调用类级别的方法
一般来说,我看不出在类级和实例级创建相同方法的模式有什么意义。它有时是有意义的,但要避免生成大量重复的方法。有多种方法可以实现这一点。一种方法是将类从模块中拉出,然后将模块包括/扩展到类中
module MyModule
def method_in_module
puts "hello"
end
end
class SomeClass
include MyModule # adds the methods to class instances
extend MyModule # Adds the methods to the class
end
或者,您也可以使用Ruby中的模块,该模块允许您将方法转发给其他对象
require 'forwardable'
module MyModule
def self.method_in_module
puts "hello"
end
class SomeClass
extend Forwardable
def_delegator :MyModule, :method_in_module
def self.method_in_module(*args, &block)
MyModule.method_in_module(*args, &block)
end
def some_method
method_in_module
end
end
end
如果您处于Rails上下文中,即使用ActiveSupport,那么您还可以使用与上面的Forwardable变体类似的方法
请注意,这两个变体仅可用于创建实例方法。对于类方法,您仍然需要自己定义方法,如上面的可转发示例所示。几乎相同是一个重要的关键字。区别是什么?代码是相同的。有时,在实例上也可以使用类方法是有意义的。例如,当您可以在singleton类上设置全局配置设置,然后希望使其在实例上更容易使用时,即为了避免self.class.my_class_方法模式。@Holger我同意,这就是为什么我偶尔编写它是有意义的;但重要的是不要滥用它。当then方法实际上只是一个函数,您不想污染内核使其假装是一个函数时,这是有意义的。我将使用它作为委托/方法重命名方案的一部分。因此,真正的方法将采用目标方法名称和一些参数,执行一点逻辑,然后调用目标方法。我一直在寻找Forwardable,但我喜欢使用rdoc来记录类的想法,我的理解是,这是行不通的。我将尝试这个解决方案-Thanksimone,这意味着包含MyModule的每个类都希望扩展该类。为什么您建议这样做,而不仅仅是将extend MyModule添加到类定义中?RE 1,使MyModule的方法仅可用于SomeClass的单个实例,a=SomeClass.new;a、 扩展MyModule。也许值得注意的是,include和extend可以在def类之外调用:Someclass.extend-MyModule;Someclass.include MyModule。@CarySwoveland include是一个私有方法,只能通过将普通作用域重写为Someclass从外部调用。send:include,MyModule。感谢您的帮助。我知道这是可以延长,所以没有麻烦检查包括。这是一个教训。