Object Ruby 中的模块方法

Posted

技术标签:

【中文标题】Object Ruby 中的模块方法【英文标题】:Module methods in Object Ruby 【发布时间】:2021-10-08 14:29:06 【问题描述】:

我无法理解 Ruby 中的全局可见性区域,因此,我知道您不能在自己的类中使用 Module 方法,例如:

module Mod
   def self.meth
      “module method”
   end
end

class Klass
   include Mod
end

p Klass.meth

# Error

但是当我知道你可以做这样的事情时:

include Math

p sin 2
#0.909....

我很困惑,因为我认为你不能在任何类中使用模块方法而不调用方法名称。我也有一个假设,该模块 Math 具有实例方法,例如 Kernel,但不幸的是,没有。现在我怀疑,我是否正确理解了诸如扩展和包含之类的方法,所以,请您向我解释一下这件事以及如果我们将包含更改为扩展会发生什么

【问题讨论】:

【参考方案1】:

你遇到了module_function的怪事:https://apidock.com/ruby/Module/module_function/

module Foo
  def foo # this is (irb) 2
  end
end

Foo.singleton_methods #=> []
Foo.instance_methods #=> [:foo]
Foo.instance_method(:foo).source_location #=> ["(irb)", 2]

module Foo
  module_function :foo # this is (irb) 9
end

Foo.singleton_methods #=> [:foo]
Foo.singleton_method(:foo).source_location #=> ["(irb)", 2]
Foo.instance_methods #=> []
Foo.private_instance_methods #=> [:foo]
Foo.instance_method(:foo).source_location #=> ["(irb)", 2]

因此,module_function 采用模块的实例方法,将其设为私有并将其复制到单例类中。

module_function 也可以不带方法名使用,有点像private 方法,修改所有未来添加到这个模块的方法。

Math 是一个完整的 module_function 模块,这意味着这些方法既可以定义为单例方法,也可以定义为私有实例方法,这就是您可以两种方式使用它的原因。

【讨论】:

非常感谢。说说为什么 module#instance_methods 不显示 foo,这就是为什么 module_function 将方法 foo 定义为私有的。

以上是关于Object Ruby 中的模块方法的主要内容,如果未能解决你的问题,请参考以下文章

Ruby 中的私有模块方法

Ruby模块中的动态覆盖类方法

为 Ruby 模块中的每个方法调用执行代码

判断祖先是Ruby中的类还是模块的方法?

从 Ruby 中的模块/mixins 继承类方法

如何在 Ruby 中使用模块扩展浮点和数组类