我即将完成 Code Academy 的 Ruby 课程,我对一件奇怪的事情感到好奇:我的印象是类是常量、方法等的存储库......并且为了访问大多数情况下,您首先需要创建该类的实例,或者在某些情况下可以调用它们自己的方法(因为它们在技术上都是全局对象的一部分)。然后我看到了这样的事情:
#Worked
Time.now
Run Code Online (Sandbox Code Playgroud)
我将其理解为调用类 [Time] 实例的方法 [now]。然后我尝试单独调用该方法:
#Failed
now
Run Code Online (Sandbox Code Playgroud)
那失败了,我假设虽然可以在一般范围内创建一个方法[作为全局对象的一部分],但如果它依赖于“父”类的初始化变量,则不能单独调用它,因为它会不知道要在哪个对象中搜索那些已初始化的变量。接下来我创建了一个测试类:
class Clock
def initialize
@hours = 1
@minutes = 30
end
def showTime
puts "The time is: #{@hours}:#{@minutes}"
end
end
#this worked
watch = Clock.new
watch.showTime
#this failed
showTime
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个基本方法(假设它在全局级别)
def mymethod
puts "The mighty METHOD!"
end
#Works
mymethod
Run Code Online (Sandbox Code Playgroud)
并按照我的方式调用此方法,而不引用全局对象。所以...我的问题如下:
首先,你的直觉是正确的。
\n\n每个方法都必须是某个接收者的实例方法。
\n\n全局方法被定义为Object类上的私有实例方法,因此似乎是全局可用的。为什么?从任何上下文Object总是在类层次结构中self,因此私有方法Object总是可以在没有接收者的情况下调用。
def fuuuuuuuuuuun\nend\n\nObject.private_methods.include?(:fuuuuuuuuuuun)\n# => true\nRun Code Online (Sandbox Code Playgroud)\n\n类方法被定义为其类实例的“单例类”上的实例方法。Ruby 中的每个对象都有两个类,一个“单例类”,其实例方法仅适用于该单个对象;另一个“普通类”,其方法适用于该类的所有对象。类没有什么不同,它们是Class类的对象,并且可能具有单例方法。
class A\n class << self # the singleton class\n def example\n end\n end\nend\n\nA.singleton_class.instance_methods.include?(:example)\n# => true\nRun Code Online (Sandbox Code Playgroud)\n\n定义类方法的替代方法是
\n\nclass A\n def self.example\n end\nend\n\n# or \n\ndef A.example\nend\nRun Code Online (Sandbox Code Playgroud)\n\n有趣的是,您可以使用相同的语法在任何对象(不仅仅是类对象)上定义单例方法,def (receiver).(method name)如下所示
str = "hello"\n\ndef str.square_size\n size * size\nend\n\nstr.square_size\n# => 25\n\n"any other string".square_size\n# => raises NoMethodError\nRun Code Online (Sandbox Code Playgroud)\n\n一些编程语言历史 \xe2\x80\x94 Singleton 类取自 Smalltalk 语言,在那里它们被称为“元类”。基本上,Ruby 中的所有面向对象功能(以及 上的函数式枚举器Enumerable)都取自 Smalltalk 语言。Smalltalk 是一种早期的基于类的面向对象语言,创建于 70 年代。它也是发明图形用户界面(例如重叠窗口和菜单等)的语言。如果你喜欢 Ruby,也许也看看 Smalltalk,你可能会再次爱上它。