Posted about 5 years ago. Visible to the public.

Singleton Class

We’ll start with a cow named cletus. Cows are ruminant animals. And ruminants are all part of the broader family of ungulates . Today’s topic isn’t actually about mammal taxonomy, though. Our real focus is on how objects find their methods. So we’re going to write a special method to help us with this task. We call it where, and it will take an object and a method name as arguments. Inside, it looks through the object’s class ancestors until it finds the nearest ancestor to defined the given method. With our tools defined, let’s put Cletus through his paces. Cletus can speak, and when he does, he moos. Cletus get this behavior from the fact that he is a Cow. When Cletus rests, he chews his cud. That’s because cows are Ruminant mammals. And when he eats, he grazes. This is fairly typical of ungulates, a group that also includes horses, deer, and giraffes.

Copy
class Ungulate def eat "graze graze graze" end end class Ruminant < Ungulate def rest "chew chew chew" end end class Cow < Ruminant def speak "moo" end end require "./classes" def where(obj, method) obj.singleton_class.ancestors.detect do |klass| klass.instance_methods(false).include?(method) end end cletus = Cow.new cletus.speak # => "moo" where(cletus, :speak) # => Cow cletus.rest # => "chew chew chew" where(cletus, :rest) # => Ruminant cletus.eat # => "graze graze graze" where(cletus, :eat) # => Ungulate def cletus.dance "tappety tappety tap" end cletus.dance # => "tappety tappety tap" where(cletus, :dance) # => #<Class:#<Cow:0x0055c1fb9c05c8>> Cow.new.singleton_class.ancestors # => [#<Class:#<Cow:0x0055978f993a78>>, # Cow, # Ruminant, # Ungulate, # Object, # PP::ObjectMixin, # Kernel, # BasicObject]

In Ruby, method lookup follows a simple and consistent rule. An object’s method definitions are found via its class inheritance chain. Always. In order for objects to be able to have individual method definitions, they have a singleton class that’s unique to them, and that singleton class is the first place Ruby looks for a method definition.

Owner of this card:

Avatar
Alexander M
Last edit:
about 5 years ago
by Alexander M
Posted by Alexander M to Ruby and RoR knowledge base
This website uses short-lived cookies to improve usability.
Accept or learn more