假设我有一个模块:
module M
def self.foo
...
end
def bar
...
end
end
模块M
包括在类中。
class A
include M
end
我想从bar
调用foo
,最终将在A
实例上调用。在bar
内执行此操作的最佳方法是什么?
当然我只能说M.foo
,但这是该模块名称的重复,这感觉不需要。
通常,在module
中,最好将类方法和实例方法分开是一个好习惯:
module M
def bar
puts "BAR"
self.class.foo
end
module ClassMethods
def foo
puts "FOO"
end
end
end
现在,在一堂课中,我理想地希望以一种将A.foo
作为类方法和A.new.bar
作为实例方法的方式来 include
CC_8。诀窍是Module.included
。
module M
def bar
puts "BAR"
self.class.foo
end
module ClassMethods
def foo
puts "FOO"
end
end
# when module is included, extend the class with ClassMethods
def self.included(base)
base.extend ClassMethods
end
end
class A
include M
end
A.singleton_methods #=> [:foo]
A.new.foo
#=> BAR
#=> FOO
使用这种方法,您可以使用self.class
引用类方法,并且可以自动起作用。
希望它有帮助。
不是真正优雅,而是
def bar
Module.nesting.last.foo
end
应该这样做。
请注意,Module#nesting
返回数组,因为一个模块可能嵌套在另一个模块中。在一般情况下,您需要应用正确的数组索引来选择要拥有的模块。
我认为使用M.foo
是最好的,但是作为练习,可以更改M#bar
如下。
module M
def self.foo
puts "In self.foo"
end
def bar
puts "In bar"
method(__method__).owner.foo
end
end
class A
include M
end
a = A.new
a.bar
# In bar
# In self.foo