0

This is some code that I use in a class called 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

It uses a line of code that references a module called GameTurn. Within GameTurn, I have a method called 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

I'm a little confused why we use "self" and the difference between exposed methods and mixin methods in modules. I asked this "instance methods of classes vs module methods"

Is take_turn really an exposed method? Even though we're feeding into the take_turn method an object from the player class, is this method still considered a module method that we're using directly? Is this not considered a mixin method? We are feeding into the take_turn method an object from another class, so isn't it mixing in with other classes?

Also, I am still trying to figure out when/why we use the term "self"? It just seems weird that we need to define the method take_turn within the GameTurn module using the term "self". It seems like it should be defined without "self" no?

Community
  • 1
  • 1
Jwan622
  • 11,015
  • 21
  • 88
  • 181
  • possible duplicate of [Why prefix a method with "self"](http://stackoverflow.com/questions/16217401/why-prefix-a-method-with-self) – infused Oct 23 '14 at 21:59
  • You've got too many questions. Please reduce them to one, or two at the very most if they're closely related. – the Tin Man Oct 23 '14 at 23:16

1 Answers1

2

Ok, from the start:

self always returns the object in which context it is executed. So here:

class A
  self     #=> A
end

In ruby, you can define methods on objects in flight, you can for example do:

o = Object.new

o.foo   #=> NameError 

def o.foo
  :foo
end

o.foo   #=> :foo

Classes and modules are just objects as everything else, hence you can define methods on them as well:

def A.method
  'class method'
end

A.method    #=> 'class_method'

However it is much easier and more convinient to define it within the class body - because of self, which always returns the class itself:

class A
  def self.foo
    :foo
  end
end

self returns A, so this can be read as:

class A
  def A.foo
    :foo
  end
end

The good thing about this is that if you decide to change class name, you only need to do it on top, next to class - self will take care of the rest.

Within the method self is always the receiver of the method. So:

o = Object.new
def o.method
  self
end
o.method == o       #=> true

It might be however pretty confusing from time to time. Common confusion come from the code:

class A
  def get_class
    self.class
  end
end

class B < A
end

b = B.new
b.get_class     #=> B

even though get_class is defined on class A, self refers to the receiver of a method, not the method owner. Hence it evaluates to:

b.class         #=> B

For the same reason self within class methods always points to the class the method is executed on.

BroiSatse
  • 44,031
  • 8
  • 61
  • 86
  • Super clear and I followed you. Hopefully this clears questions about self for me moving forward. Thanks! – Jwan622 Oct 24 '14 at 00:06