有没有办法为Class方法和实例方法使用相同的代码?
例如,我想做以下事情:
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_method_in_module
和instance_method_in_module
,然后将它们包含在类中(在我的实际示例类中),但代码是相同的。
答案 0 :(得分:3)
您可以使用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
重要的是要记住,类和实例具有不同的范围。因此,在类范围内运行良好的方法在类范围内可能效果不佳。
理想情况下,我建议在类级别定义方法,并从实例级别调用类级别方法。
一般来说,我没有看到在类级别和实例级别创建相同方法的模式在哪里是有意义的。它偶尔会有意义,但避免产生大量重复的方法。
答案 1 :(得分:0)
有多种方法可以实现这一点。一种方法是将类拉出模块,然后将/ extend模块包含到类
中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中的Forwardable模块,它允许您将方法转发给其他对象。
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),您还可以使用与上述可转发变体类似的delegate
方法。
请注意,这两种变体仅可用于创建实例方法。对于类方法,您仍然需要自己定义方法,如上面的Forwardable
示例所示。