如何从 Ruby 中的实例方法访问模块?
How do I access a module from an instance method in Ruby?
假设我有一个模块:
module M
def self.foo
...
end
def bar
...
end
end
模块 M
包含在 class 中。
class A
include M
end
我想从 bar
调用 foo
,它最终将在 A
的实例上调用。在 bar
中执行此操作的最佳方法是什么?
当然我可以直接说M.foo
,但这是模块名称的重复,感觉没有必要。
不是很优雅,但是
def bar
Module.nesting.last.foo
end
应该这样做。
请注意,Module#nesting
returns 一个数组,因为一个模块可能嵌套到另一个模块中。在一般情况下,您需要应用正确的数组索引来选择您想要的模块。
通常,在 module
中,将 class 方法和实例方法分开是一个很好的做法,如下所示:
module M
def bar
puts "BAR"
self.class.foo
end
module ClassMethods
def foo
puts "FOO"
end
end
end
现在,在 class 中,我希望 include
这个模块 M
的方式是 A.foo
作为 class 方法和 A.new.bar
作为实例方法。诀窍是 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
引用 class 方法,它会自动起作用。
希望对您有所帮助。
我认为使用 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
假设我有一个模块:
module M
def self.foo
...
end
def bar
...
end
end
模块 M
包含在 class 中。
class A
include M
end
我想从 bar
调用 foo
,它最终将在 A
的实例上调用。在 bar
中执行此操作的最佳方法是什么?
当然我可以直接说M.foo
,但这是模块名称的重复,感觉没有必要。
不是很优雅,但是
def bar
Module.nesting.last.foo
end
应该这样做。
请注意,Module#nesting
returns 一个数组,因为一个模块可能嵌套到另一个模块中。在一般情况下,您需要应用正确的数组索引来选择您想要的模块。
通常,在 module
中,将 class 方法和实例方法分开是一个很好的做法,如下所示:
module M
def bar
puts "BAR"
self.class.foo
end
module ClassMethods
def foo
puts "FOO"
end
end
end
现在,在 class 中,我希望 include
这个模块 M
的方式是 A.foo
作为 class 方法和 A.new.bar
作为实例方法。诀窍是 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
引用 class 方法,它会自动起作用。
希望对您有所帮助。
我认为使用 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