Ruby 全局符号上下文中的类与实例方法

Ruby 全局符号上下文中的类与实例方法,ruby,class,oop,global,symbols,Ruby,Class,Oop,Global,Symbols,我在读一篇关于的博客文章时,遇到了以下几行: Ruby中的类是全局符号,这意味着类方法是全局符号。向globals编码是我们不再使用PHP的原因 我想进一步理解这句话,并提出一些问题 类方法和实例方法在符号上下文中有什么不同 例如,以以下irb会话为例: irb(main):001:0> Symbol.all_symbols.grep /Foo/ => [] irb(main):002:0> Symbol.all_symbols.grep /some.*method/ =&

我在读一篇关于的博客文章时,遇到了以下几行:

Ruby中的类是全局符号,这意味着类方法是全局符号。向globals编码是我们不再使用PHP的原因

我想进一步理解这句话,并提出一些问题

  • 类方法和实例方法在符号上下文中有什么不同
例如,以以下irb会话为例:

irb(main):001:0> Symbol.all_symbols.grep /Foo/
=> []
irb(main):002:0> Symbol.all_symbols.grep /some.*method/
=> []
irb(main):003:0> class Foo
irb(main):004:1> def some_instance_method; end
irb(main):005:1> def self.some_class_method; end
irb(main):006:1> end
=> :some_class_method
irb(main):007:0> Symbol.all_symbols.grep /Foo/
=> [:Foo]
irb(main):008:0> Symbol.all_symbols.grep /some.*method/
=> [:some_instance_method, :some_class_method]
  • #某些#u实例_方法
    :某些#u类_方法
    在符号上下文中有何不同
  • 当我检查符号时我在做什么。所有符号都与查看“全局符号”相同吗
  • 为什么同时显示了
    #一些(实例)方法
    ::一些(类)方法
    ?阅读上述引文后,我预计
    008
    的结果为:

    irb(main):008:0>Symbol.all_symbols.grep/some.*方法/ =>[:某些\u实例\u方法]


我认为Dave的措辞有点不清楚,但他在你摘录后的段落中解释了影响:

Resque就是一个很好的例子,说明了作为全局符号的服务存在问题。所有Resque方法都可以通过Resque获得,这意味着任何Ruby虚拟机都只有一个Resque可以使用

[……]

另一方面,如果Resque是作为一个对象实现的,而不是作为一个全局对象实现的,那么任何需要访问不同Resque实例的代码都不必更改它,只需给它一个不同的对象即可

不同之处在于界面:使用Resque,工具的用户“依赖”特定类,并与特定类进行接口——它们是对象,但它们是被降级为全局对象的对象。这与对象上的实例方法接口相反,在对象上,任何其他对象都可以被子化,而不依赖于对象的类


因此,Dave认为,在全局上使用类方法(如未定义范围的类定义)类似于使用全局方法,是一种类似于PHP的方法。

我看到了这篇文章的几个问题:

首先,使用“”一词可能会令人困惑。事实上,虽然这个词确实完美地描述了作者的意思,但有些读者可能会将其与Ruby中的数据类型混淆。因此,虽然没有错,但在Ruby的上下文中,词语的选择是不幸的。“名字”可能是更好的选择

其次,他人为地区分了类方法和实例方法,但Ruby中没有类方法。Ruby只有一种方法:实例方法。我们所谓的“单例方法”实际上只是单例类的常规实例方法,而我们所谓的“类方法”实际上只是碰巧是类实例的对象的单例类的常规实例方法

第三,他人为地区分了类和对象,但在Ruby中类是对象

似乎他真正反对的是常量(因为它们是全局名称)、单例(通常是类)和静态。虽然所有这些都是不好的,但他应该这么说,如果这是他的意思的话。(这也不完全是一个新发现;整个编程语言都是基于避免静态而设计的,例如…)

tl;dr summary:这篇文章反对全局名称、单例和静态,但表述和措辞不当。

问题1
:some_instance_method
:some_class_method
符号仅存在于Ruby的符号表中。它们在符号的上下文中没有区别。
符号。所有的\u符号
结果都不会声明任何有关被引用对象的信息。如果你有:

class Aaa
  def kick_it
    logger.debug { "You kicked an Aaa object" }
  end
end
module Bbb
  def self.kick_it
    logger.debug { "You kicked Bbb" }
  end
end
您将只看到1个
:kick\u it
符号报告。所有的
符号,即使其中一个是模块级方法,另一个是实例方法

问题2 文章中使用“符号”一词可能会让人感到困惑。此处的“全局符号”可能表示集合
对象.constants
的成员的名称,或定义的常量子树中可访问的任何其他常量

所以
Symbol。在这种情况下,所有的\u符号都不同于“全局符号”。但是,内存中常量树中的所有名称都将是
符号的子集。请记住,所有的作用域信息都将丢失

问题3
我认为上面的问题1的答案也解释了为什么这两个符号都显示在
符号中。所有的符号都是
结果。

那么上面的内容是否应该重写为
,这意味着类方法类似于全局符号?我仍然不明白是什么让类与实例方法从符号的角度有所不同。类名在全局命名空间中,因此不能重用,这对我来说很有意义,但我不确定这与symbols@mbigras它与符号的概念无关,只是Ruby为常量创建符号。更多信息请参见此问题:@mbigras:“Symbol”是一个非常普通的英语单词。它在本文中的用法与Ruby中的
符号
类无关。“静态”的概念是否与“无状态”的概念相关?因为你说他反对“静态”,但他似乎支持“无状态”对象;但“静态”似乎类似于“无状态”。另外,文章中没有提到“静态”(我想你的观点是它应该是什么?),所以我对你所说的“静态”感到困惑。@mbigras Ruby(和其他一些人)所说的“类方法”也被其他语言称为静态方法。无国籍与Jörg的answ无关