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_方法
<代码>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”)。尽管如此,它们都是方法,称它们为方法从来没有错。