From: transfire@... Date: 2006-06-18T10:37:23+09:00 Subject: Proper fowlsome noises [was: Why the lack of mixing-in support for Class methods?] why the lucky stiff wrote: > On Sat, Jun 17, 2006 at 01:28:12AM +0900, Christian Neukirchen wrote: > > Instead of further pythonizing the language (sorry, couldn't resist), > > I'd rather prefer a non-OO way for the tricky cases: > > > > Object.object_id_of myobj > > Object.class_of myobj > > Object.send_to myobj, :foo > > So, it quacks like a dog, but if we really press it, we can get a proper > fowlsome noise? > > >> duck.quack > >> # > # .. uh.. let's try this again, that was a bit noisey > >> Animal.come_on_gimme_the_real_duck_quack duck > => # > > I'm not saying it's a totally bad idea. I just don't think I'd be able to spot > when Object.object_id_of is necessary. I mean when in advance do you know > you're getting nasty mangled objects that don't behave? I generally try to use > __send__ right now. I figure if __send__ is overridden, then someone has > figured out a better way to dispatch methods. Hey, let's let them try. I was looking over the Kernel methods, thinking about which one's are vital and and/or meta in nature. And really it seems like almost all of them are, which probably accounts for why they are in Kernel to begin with. They are (v1.8.4): ["==", "===", "=~", "__id__", "__send__", "class", "clone", "display", "dup", "eql?", "equal?", "extend", "freeze", "frozen?", "hash", "id", "inspect", "instance_eval", "instance_of?", "instance_variable_get", "instance_variable_set", "instance_variables", "is_a?", "kind_of?", "method", "methods", "nil?", "object_id", "private_methods", "protected_methods", "public_methods", "respond_to?", "send", "singleton_methods", "taint", "tainted?", "to_a", "to_s", "type", "untaint"] Looking through these, it really becomes hard to say what should stay and what should go in forming a near empty class. And given their nature one might be inclined to think that most of these should be external to the object anyway. I mean, should the class really have the "right" to override #object_id? After thinking about this further. I started to wonder if maybe the __foo__ notation could be a special syntax Ruby would always take as a method call bound to Kernel, analogous to: def method_missing( meth, *args, &blk ) if md = /^__(.*)__$/.match( meth.to_s ) Kernel.instance_method( md[1] ).bind(self).call(*args, &blk) end super end This example implmentation still allows them to be overridden. Whether that should be so is debatible, though _why makes a good point. If you think you can make a better quack than go for it. Also interesting, If you look as Ruby 1.9 specs you'll see there is now a BasicObject that lies behind Object and Kernel. These are the methods it isolates: [ "__send__", "funcall", "__id__", "==", "send", "respond_to?", "equal?", "object_id"] I'm all for the idea of a BasicObject b/c it will make OpenStruct and classes of that ilk more standardized and robust. But I was wondering what if you wanted to make a subclass of BasicObject but there were one or perhaps a few other Kernel methods you needed to include. Say for instance you needed #instance_variables. How would you be able to include that since Kernel is not even in the class hiearchy? Maybe it isn't that important, but it doesn't seem like it should be out the question. Of course, we take another step back we see that all of this crops up b/c the OpenStruct pattern is just too damn nice not use, even though Hash will usually work just as well. But who wants to do foo[:a][:b][:c] when they can do foo.a.b.c? Moreover an OpenStruct can quack like any duck; a hash can't. But then the little edge problems arise, b/c an OpenStruct pattern is generally used for something that can have completely arbitarty keys. And that's when the Kernel methods can get in the way, not to mention any other internal methods you might would like the class to have. So you clear out most of then methods with BasicObject or BlankSlate or what have you and then some one elses lib croaks b/c it can't #dup you object or whatever. Yeah, it can get nasty. Okay, I'm starting to rattle on, but one last thought occurs to me: might the whole issue go away if private and public methods could have their own separate namespaces? The public method would still be available privately, but if a specifcally private method of the same name were defined it would be used when called without a receiver, rather than the public one. The even for an OpenStruct one could generally ensure the proper response from vital methods by using #__funcall__. T.