Skip to content

Instantly share code, notes, and snippets.

@apeiros
Last active August 29, 2015 14:22
Show Gist options
  • Save apeiros/357452f493a6b566098a to your computer and use it in GitHub Desktop.
Save apeiros/357452f493a6b566098a to your computer and use it in GitHub Desktop.
class Demo
def self.a_class_method
puts "Running a class method, self is: #{self.inspect}"
end
def an_instance_method
puts "Running an instance method, self is: #{self.inspect}"
end
end
Demo.a_class_method # class methods can be run on the class directly
demo_instance = Demo.new # .new creates an instance of Demo
demo_instance.an_instance_method # instance methods are run on instances of the class
# Expanding on the above code
class Demo
class << self
def another_class_method
puts "Running a class method, self is: #{self.inspect}"
end
end
end
Demo.another_class_method
# The class method was defined as an instance method - so how is it that it can be called on the Demo class?
# The explanation is that class << self opens a class, like class Demo does. The class which is opened is
# Demo.singleton_class. Demo is an instance of Demo.singleton_class
class Demo
class << self
puts "self in the context of the singleton class: #{self}"
puts "Demo.singleton_class == self # => #{Demo.singleton_class == self}"
end
end
# Even thous Demo.class returns Class, the singleton_class technically sits in front of that in the inheritance chain:
puts "Demo.is_a?(Demo.singleton_class) # => #{Demo.is_a?(Demo.singleton_class)}"
# So class methods are really still instance methods - instance methods on the singleton_class of the class they're called on
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment