这是我在名为Game的类中使用的一些代码:
def play
puts "There are #{@players.length} players in #{@title}."
@players.each do |n|
puts n
end
@players.each do |o|
GameTurn.take_turn(o)
puts o
end
end
它使用一行代码引用名为GameTurn的模块。在GameTurn中,我有一个名为self.take_turn
的方法:
require_relative "die"
require_relative "Player"
module GameTurn
def self.take_turn(o)
die = Die.new
case die.roll
when 1..2
o.blam
puts "#{o.name} was blammed homie."
when 3..4
puts "#{o.name} was skipped."
else
o.w00t
end
end
end
我有点困惑为什么我们使用" self"以及模块中的公开方法和mixin方法之间的区别。我问了这个" instance methods of classes vs module methods"
take_turn
真的是暴露的方法吗?即使我们从播放器类中提取了take_turn
方法的对象,这种方法仍然被认为是我们直接使用的模块方法吗?这不被认为是mixin方法吗?我们正在将take_turn
方法作为另一个类中的对象,因此它是否与其他类混合?
另外,我还在试图弄清楚我们何时/为什么使用“自我”这个词?我们需要使用术语" self"在GameTurn模块中定义方法take_turn
,这似乎很奇怪。它似乎应该在没有" self"没有?
答案 0 :(得分:2)
好的,从一开始:
self
始终返回执行上下文的对象。所以这里:
class A
self #=> A
end
在ruby中,您可以在飞行中定义对象的方法,例如:
o = Object.new
o.foo #=> NameError
def o.foo
:foo
end
o.foo #=> :foo
类和模块只是对象,因此您也可以在它们上定义方法:
def A.method
'class method'
end
A.method #=> 'class_method'
然而,在类体中定义它更容易,更方便 - 因为self,它总是返回类本身:
class A
def self.foo
:foo
end
end
self
返回A,因此可以理解为:
class A
def A.foo
:foo
end
end
关于这一点的好处是,如果你决定更改课程名称,你只需要在class
旁边进行,自我将负责其余部分。
在方法self
内始终是方法的接收者。所以:
o = Object.new
def o.method
self
end
o.method == o #=> true
然而,它可能会不时混淆。常见的混淆来自代码:
class A
def get_class
self.class
end
end
class B < A
end
b = B.new
b.get_class #=> B
即使在类A上定义了get_class,self也指的是方法的接收者,而不是方法所有者。因此,它评估为:
b.class #=> B
出于同样的原因,类方法中的self始终指向执行该方法的类。