使用“自我”,mixin方法和暴露方法

时间:2014-10-23 21:46:28

标签: ruby module self

这是我在名为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"没有?

1 个答案:

答案 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始终指向执行该方法的类。