它们被称为单例方法,可以定义如下:
class Person
def favorite_meal
"Big Mac"
end
end
Fred, Joe = 2.times.map { Person.new }
def Fred.favorite_meal
"Le Big Mac"
end
Joe.favorite_meal #=> Big Mac
Fred.favorite_meal #=> Le Big Mac
定义相同单例方法的其他方法是:
Fred.define_singleton_method :favorite_meal do "Le Big Mac" end
和:
class << Fred
def favorite_meal
"Le Big Mac"
end
end
愿原力与你同在。
更新:回答评论中的两个问题。
让我从第二个开始。使用常量还是变量取决于您。写起来完全没问题fred = Person.new
。但:
具有不同属性的对象通常应该得到正确的名称,并正确大写。
我写了一个有用的 gem y_support/name_magic
,它通过分配给常量来工作。
通过 安装它gem install y_support
,然后尝试:
require 'y_support/name_magic'
class Dog
include NameMagic
def speak; puts "Bow wow!" end
end
Spot, Rover = 2.times.map { Dog.new }
现在Dog
类知道它的实例,实例也知道它们的名字。
Dog.instances.map { |dog| dog.name } #=> :Spot, :Rover
Dog.instances.names # the simpler way to say the same
这在这个特定示例中没有用(在其他地方非常有用),但无论如何,它让我养成了给具有个性的对象以大写专有名称的习惯。
至于第一个问题,def Fred.foobar
是最基本的,一次性的单例方法定义。如果要定义多个单例方法或别名,或在单例类中包含一个模块,请使用class << Fred
:
module Foo
def bar; "Fretbar!" end
end
class << Fred
include Foo
alias le_favorite favorite_meal
end
Fred.bar #=> Fretbar!
Fred.le_favorite #=> "Le Big Mac"
最高级的事情可以通过Fred.define_singleton_method
语法和第 4 种方式实现,我之前没有提到:
local_var = 42
Fred.singleton_class.class_exec do
define_method :baz do local_var + 1 end
end
Fred.baz #=> 43
这种方式使用闭包,它保留对变量的绑定local_var
。试试看
local_var = 32
Fred.baz #=> 33
所以这就是闭包语法的特别之处,它通常是神奇地解决令人讨厌的编程问题的天赐之物。