Blankman
Blankman

Reputation: 267010

When an instance method calls a class method, I have to use self.class_method?

I'm getting an error so I guess I have to reference a class method from inside of an instance method with self.class_method_name, but why is that?

Shouldn't it resolve this by itself? Confused.

def self.blah(string)
  ..
end

def some_method()
  some_thing = blah("hello")
end

Upvotes: 0

Views: 131

Answers (2)

Andrew Marshall
Andrew Marshall

Reputation: 96934

It may be easier to think of self as part of the method name, that way it's clear that you never defined a blah method, you defined only a self.blah method. (To clarify: the previous sentence shouldn't be thought of too much, so please don't read into it, as it's not how things are actually working, just a sort of "layman's terms" attempt at describing why it doesn't work.)

Also, what if you had defined a blah instance method in addition to the class method? If calling blah was enough to access the class method, how would you call the instance method?

Finally, there really isn't any such thing as a class method in Ruby, "class methods" are really methods of the singleton class.

Upvotes: 1

Andrew Grimm
Andrew Grimm

Reputation: 81510

If you have

# This won't work
class Foo
  def self.blah(string)
    puts "self.blah called with a string of #{string}"
  end

  def some_method
    # This won't work
    self.blah("hello")
  end
end

foo = Foo.new
foo.some_method

It won't work, because it'll look for the instance method Foo#blah. Instead, you're looking for Foo.bar.

To make some_method call Foo.bar, you have to make some_method refer to the Foo class, and then call blah on it.

class Foo
  def self.blah(string)
    puts "self.blah called with a string of #{string}"
  end

  def some_method
    # This will work
    self.class.blah("hello")
  end
end

foo = Foo.new
foo.some_method

The reason you have def self.blah to define the method, but self.class.blah to call the method, is that in the former, self refers to the Foo class, while in the latter, self refers to the foo object, so you need self.class to refer to the Foo class.

Upvotes: 3

Related Questions