18

I know that self is the instance inside of an instance method. So, then, is self the class inside of a class method? E.g., Will the following work in Rails?

class Post < ActiveRecord::Base
  def self.cool_post
    self.find_by_name("cool")
  end
end
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • 5
    And to add to the below answers, since ruby will always evaluate the receiver as self unless specified, your above code can just call `find_by_name` without the self :) – brad Dec 03 '10 at 20:18
  • Thank you, are there cases when it's a good idea to specify `self`? Is `self.find_by_name` the first place Ruby would look for `find_by_name`? Does it look anywhere else? What about in a globally defined method (a method defined in the file outside of a class)? – ma11hew28 Dec 03 '10 at 20:27
  • I tested it out. It seems that the order of precedence is the class method and then the globally defined method if no class method is found. – ma11hew28 Dec 03 '10 at 20:32
  • I have created a diagram showing [the method lookup order in Ruby](http://phrogz.net/RubyLibs/RubyMethodLookupFlow.png). You may find it useful. – Phrogz Dec 03 '10 at 20:42
  • At least in Ruby 1.9.2, ‘globally defined’ methods are actually private methods on `Object`. Try, for example: `def foo; end; Object.private_methods.include?(:foo) # => true`. This means that they basically end up at the top of the inheritance chain, and are last in order to be found. – Stéphan Kochen Dec 03 '10 at 20:43

4 Answers4

23

That is correct. self inside a class method is the class itself. (And also inside the class definition, such as the self in def self.coolpost.)

You can easily test these tidbits with irb:

class Foo
  def self.bar
    puts self.inspect
  end
end

Foo.bar  # => Foo
Stéphan Kochen
  • 19,513
  • 9
  • 61
  • 50
5
class Test
    def self.who_is_self
        p self
    end
end

Test.who_is_self

output:

Test

Now if you want a Rails specific solution, it's called named_scopes:

class Post < ActiveRecord::Base
   named_scope :cool, :conditions => { :name => 'cool' }
end

Used like this:

Post.cool
krusty.ar
  • 4,015
  • 1
  • 25
  • 28
5

A lot of answers already, but here is why self is the class:

The dot changes self to whatever is before the dot. So, when you do foo.bar then for the bar-method, self is foo. There is no difference with class methods. When calling Post.cool_post, you'll change self to Post.

The important thing to note here is that it's not how the method is defined that determines self, but how it's called. This is why this works:

class Foo
  def self.bar
    self
  end
end

class Baz < Foo
end

Baz.bar # => Baz

Or this:

module Foo
  def bar
    self
  end
end

class Baz
  extend Foo
end

Baz.bar # => Baz
iain
  • 16,204
  • 4
  • 37
  • 41
4

Short answer: yes

What I like to do with these questions is just fire up an irb or ./script/console session

and then you can do the following to see the magic:

ruby-1.8.7-p174 > class TestTest
ruby-1.8.7-p174 ?>  def self.who_am_i
ruby-1.8.7-p174 ?>    return self
ruby-1.8.7-p174 ?>    end
ruby-1.8.7-p174 ?>  end
 => nil 
ruby-1.8.7-p174 > TestTest.who_am_i
 => TestTest

Happy fishing!

Jonathan
  • 16,077
  • 12
  • 67
  • 106