Tuesday, June 7, 2011

Ruby: Class vs Instance methods

Today I was trying to call a method in the rails console, but it kept giving me the "NoMethodError: Undefined" error. I was confused because I could see the method right there in the model, but it wasn't seeing it in the console for some reason.

Eventually I discovered that the method was defined in the model as a class method (self.method) and I was trying to call it using an instance of the class. Here's what I learned:

A class method is one that is called by the class itself, not by an instance.

MyClass.method
==>true


Suppose you had an instance of MyClass:

mc = MyClass.new
mc.method

==>#NoMethodError: Undefined


An instance of a class cannot call a class method. An instance can call an instance method.

Examples:

Ways to define an instance method:

1)
class MyClass
def method
puts doStuff
end
end

mc = MyClass.new
mc.method
==>doStuff

2)
class MyClass
attr_accessor: :method
end

mc = MyClass.new
mc.method = "doStuff"
puts mc.method
==>doStuff
If the attr_accessor: throws you off, learn about it here.


3)
class MyClass; end

mc = MyClass.new
def mc.method
puts "doStuff"
end

mc.method
==>doStuff

Ways to define a class method:

1)
class MyClass
def self.method
puts "doStuff"
end
end

MyClass.method
==>doStuff

Notice that you are calling the method using the class (MyClass.method), not an instance.

2)
class MyClass
class << self
#anything in this block is a class method
def method
puts "doStuff"
end
end
end

MyClass.method
==>doStuff

mc = MyClass.new #this is now an instance of MyClass; cannot call method
mc.method
==>NoMethodError: Undefined

3)
class MyClass; end
def MyClass.method
puts "doStuff"
end

MyClass.method
==>doStuff

In this last example, notice that you are defining the method for MyClass, making it a class method.

For more examples/explanation:
http://railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/

No comments:

Post a Comment