Posted August 14, 2013on:
I read “Metaprogramming Ruby” asking myself why Rubyists didn’t have a debugger like we have. What was different about our object model that allowed us to have our debugger?
It’s not just a deeper object model. It’s a more rigorous implementation of the language. Ruby has a “create as needed” philosophy. Smalltalk has a “consistency of implementation” philosophy.
The things that stand out to me about Ruby are instance variables and eigenclasses. Chapter 5 of the Bluebook says metaclasses were created to give classes customizable initialization. That appears to me to be what Ruby doesn’t have – constructor methods. It has :new and :new() (OK, ActiveRecord has :create for automatic generation of setters and getters). You cannot initialize an object and set the values of instance variables in one message.
If I read this rightly, you need to initialize instance variables. i.e.:
class MyClass def my_method @v = 1 end end obj = MyClass new obj.my_method
On page 35 of “Metaprogramming Ruby” it says:
“If Bill, hadn’t called obj.my_method(), then obj would have no instance variable at all.”
Initialization for ivars. That’s interesting.
Constructor methods in Smalltalk are class side methods. You can add class side methods in Ruby. Each time you do so, an object called an eigenclass is created. This follows the “create as needed” philosophy that I see as Matz’s attitude to language design. As opposed to the “consistency of implementation” that I see as Kay’s.
And that’s why we have a debugger as we do an nobody else does. We have a deep – perhaps four tier deep – object model that is quite rigorously implemented. These two things seem to me to provide a greater objective reality against which a specific program can be judged. I think that is a definition of reflection. A layer of abstraction provides a basis of comparison.
“No object in a class-based system can be self sufficient; another object (its class) is needed to express its structure and behaviour. This leads to a conceptually infinite meta-regress: a point is an instance of class Point, which is an instance of metaclass Point, which is an instance of metametaclass Point, ad infinitum. On the other hand, in prototype-based systems an object can include its own behaviour; no other object is needed to breathe life into it. Prototypes eliminate meta-regress.” (page 5)