> What's going on here is that we're adding the speak method to matz's metaclass, and the matz object inherits from its metaclass and then Object.
Ruby uses the word "metaclass" for something completely different from the familiar OOP concept that a class is itself an instance of something, and that something is a metaclass.
It looks like a Ruby metaclass is actually a hidden class that is instantiated for each object instance. An object inherits from its purported class, plus also its hidden metaclass. When you customize an object instance with a new method, it goes into that metaclass, and so other objects that are instances of the visible class are unaffected.
It seems like a pointless complication over (in the context of a single dispatch OOP) just representing methods as slots of an object. Normally, methods are class slots, but if an instance slot is used for a method, then that is specific to an object.
A lot of people prefer the term eigenclass, but yes, it's poorly named.
You're absolutely right, a Ruby metaclass is nothing more than a hidden class that acts as if it exists on each object in the inheritance chain before the class you specify that you want to inherit from.
In practice it is dynamically inserted first if you define a method on it, and so the vast majority of objects do not have a meta class.
In terms of being a pointless complication, consider that if you add a field to the object, then it complicates the method call logic, because now at every call site, in addition to considering the inheritance chain, where each element is identical, you now first need to rule out whether a given method name has been overridden by a given object. (this applies to MRI; there's no inherent reason why a Ruby implementation needs to follow a chain like this - e.g. my half-finished, buggy work-in progress Ruby compiler uses C++-like tables, and instead propagates updates downwards, and so will only ever do a single indirection function pointer call, at the cost of larger class objects)
The metaclass solves that by just inserting a pointer in the inheritance chain if you're defining a method on a meta class and the object does not currently inherit from one. Then all other logic is the same other than the `class` method, which skips over classes that are meta classes.
Ruby uses the word "metaclass" for something completely different from the familiar OOP concept that a class is itself an instance of something, and that something is a metaclass.
It looks like a Ruby metaclass is actually a hidden class that is instantiated for each object instance. An object inherits from its purported class, plus also its hidden metaclass. When you customize an object instance with a new method, it goes into that metaclass, and so other objects that are instances of the visible class are unaffected.
It seems like a pointless complication over (in the context of a single dispatch OOP) just representing methods as slots of an object. Normally, methods are class slots, but if an instance slot is used for a method, then that is specific to an object.
Hash tag #ICantBelieveTheyCalledThatMetaclass