Ruby 在模块中讨论实例/类方法的约定

Ruby 在模块中讨论实例/类方法的约定,ruby,oop,Ruby,Oop,给定以下代码: module Foo class Bar def some_method end def self.another_method end end end 如果我想和一个Ruby专家谈谈实例方法some\u方法,我会说Foo::Bar\some\u方法 如果我想谈论class方法另一种方法,我会说Foo::Bar::另一种方法 但是如果Bar是一个模块怎么办 module Foo module Bar def some_meth

给定以下代码:

module Foo
  class Bar
    def some_method
    end
    def self.another_method
    end
  end
end
如果我想和一个Ruby专家谈谈实例方法
some\u方法
,我会说
Foo::Bar\some\u方法

如果我想谈论class方法
另一种方法
,我会说
Foo::Bar::另一种方法

但是如果
Bar
是一个模块怎么办

module Foo
  module Bar
    def some_method
    end
    def self.another_method
    end
  end
end
惯例是一样的吗?

是的

尽管术语不同,类有方法,但对于模块,它们有时被称为函数

我的资料来源是Matz的《简而言之的Ruby》一书。他将模块上定义的方法称为模块函数,因此也将
模块的名称称为module\u function
方法。同一本书有一章介绍内置函数,如
exit
等,这些函数是在
内核
模块上定义的

有趣的是,这些“函数”似乎是全局可用的,因为
对象
包含
内核
,因此其所有模块函数都成为任何对象的私有方法,因此可以从任何上下文调用。期待
BasicObject
,但这是另一个时代的另一个故事


或者像Eric建议的那样“问问Ruby”

[1] pry(main)> module B
[1] pry(main)*   def m
[1] pry(main)*   end  
[1] pry(main)*   def self.n
[1] pry(main)*   end  
[1] pry(main)*   module_function
[1] pry(main)*   def f
[1] pry(main)*   end  
[1] pry(main)* end  
=> nil
[2] pry(main)> B.instance_method(:m)
=> #<UnboundMethod: B#m>
[3] pry(main)> B.method(:n)
=> #<Method: B.n>
[4] pry(main)> B.method(:f)
=> #<Method: B.f>
撬(主)>模块B [1] 撬(主)*def m [1] 撬(主)*端 [1] 撬(主)*定义自身n [1] 撬(主)*端 [1] 撬(主)*模块功能 [1] 撬(主)*def f [1] 撬(主)*端 [1] 撬(主)*端 =>零 [2] 撬(主)>B.实例法(:m) => # [3] 撬(主)>B.方法(:n) => # [4] 撬(主)>B.方法(:f) => # 三个观察结果

  • 模块函数与模块上的“类方法”相同
  • 模块上的“类方法”打印为
    module.fun
  • 模块上的“实例方法”实际上是未绑定的

当谈论这段代码时,some#u方法将被称为实例方法
some_方法
<代码>Foo::Bar。另一种方法我会调用class方法
另一种方法


在一个模块的上下文中,我将调用
Foo::Bar。另一个方法是模块方法。然而,像实例方法这样的东西在模块的上下文中是没有意义的。您可能希望调用该函数。

是的,这是完全相同的约定,原因很简单:

  • 继承自
  • 方法在中定义

可以肯定,如果你查看源代码,所有方法都以
为前缀,我会说:不。符号
表示类的实例方法,
表示在接收器上定义的方法,在本例中是类方法。我相信
#
只是来自国际扶轮。我记不起在嵌套的名称空间Foo::Bar中引用某种方法的任何符号。但是,当你与rubyist交谈时,你不需要任何符号来描述它。记录“类方法”的技术语法是
class::method
,“实例方法”是
class#method
@7stud:只要看一看文档
到处都在使用:在线文档、ruby方法对象、irb、,ri…没有人会同意我的看法,这是这样做的模块可以有公共的“类方法”请注意
Module::constants
Module::nesting
与所有的实例方法如
Module#include
相比,你颠倒了我陈述中的顺序实际上
Module_函数
在模块上创建“类方法”,这将使
Foo::Bar。另一个
方法成为一个模块函数。@akuhn,1)这不是模块函数所做的唯一事情,所以这有点不正确。2) Dave Thomas使用该术语来描述在模块内部定义的方法,其方法名称前面是模块名称。谈到模块方法,
:instance_method
被定义为
模块#instance_method
,并由
继承。因此,
instance\u method
在模块的上下文中应该是有意义的。@7stud Ruby core似乎支持模块方法的术语,以指无需封装、可实例化对象即可调用的方法。这个术语在模块本身的文档中使用。谢谢你对“实例方法”的引用,因为从技术上讲,所有方法都是实例方法,因为所有对象都是实例。我不相信。调用
include
检查方法被认为是作弊,但是
module\u函数
应该可以吗
module_function
基本上类似于
extend self
,因此您只是将实例方法转换为类方法。如果你愿意,可以称它们为“函数”,它们仍然都是方法。我们可以同意内核方法被称为函数,不过。@EricDuminil我不同意。这些是
内核
模块的实例方法,通过继承该模块的
对象
类来传播
BasicObject
不包括
内核
,并且无法访问其中包含的任何方法。作为对答案的说明,这清楚地表明它们不是“全球性的”。Ruby只有关键字和方法。@engineersmnky:谢谢。我实际上是想说内核方法有时被称为函数,因为它们看起来像其他语言的函数(“put/print/test/system”)。尽管如此,它们都是方法,称它们为方法从来没有错。