An addendum to my note from earlier today: the constructor problem is more annoying than I’d thought, because (as I just discovered!) the static constructor method is harder to carry out than I’d realized. After all, the static constructor method still has to create an object of the type in question, which means that it has to (indirectly) call that object’s initialize
method. (Well, it probably doesn’t have to, this being Ruby, but that’s another matter.) Which, in turn, means that the initialize
method has to allow you to set up the state in a sufficiently general way to make that easy for your static method. And that means that it probably has to expose your object’s internal state pretty directly. But that may not be the way that you want other users to construct your objects, putting you in a bit of a bind.
I’m pretty sure I don’t yet understand all the options and tradeoffs here. I’ll have to do a bit more reading and thinking, I guess. (And then probably ask on the newsgroup.)
Post Revisions:
There are no revisions for this post.
In Smalltalk, where the public/private status of a method is a matter of convention (all methods are public, all instance variables are protected), the convention is that you never call the “initialize” method of a class unless you are a constructor (class method) of that class. Furthermore, if you always want your clients to invoke one or more specialized constructors, then you write a “new” class method that throws an error, and always use “super new” in your constructors.
12/31/2006 @ 2:23 pm
I’m thinking of getting rid of the public/private/protected notion for methods myself; I’m not sure what that’s buying me any more.
I confess I don’t yet understand the details of the interactions between the class method
new
and the instance methodinitialize
in Ruby, and in particular how to write replacements for the former. It seems like it should be straightforward, but there’s one sentence in the relevant section of the book that’s confusing me. I’ll give it a try at some point…12/31/2006 @ 3:59 pm
It’s pretty straightforward: when you call the new method on a Class object, it allocates space for the object using the primitive allocate instance method of Class, then invokes the initialize instance method on the new object, passing along the arguments of new. That method can and usually should invoke the initialize method of its superclass .
If you want to override new, you can write your own new method, which may (for example) avoid calling superclass new when there is no need to actually construct a new object.
1/1/2007 @ 11:36 pm