From: Trans Date: 2007-03-07T21:32:19+09:00 Subject: Re: object_* and instance_* methods On Mar 7, 5:56 am, Pit Capitain wrote: > Brian Candler schrieb: > > > > > On Wed, Mar 07, 2007 at 06:40:20PM +0900, Brian Candler wrote: > >> Final point. If the requirement is that 'meta-programming' methods should be > >> available always on all objects, then I can offer a completely different > >> solution: > > >> # was: foo.class > >> Object.class_of(foo) > > >> # was: foo.send(meth,*args) > >> Object.send_to(foo, meth, *args) > > >> # was: foo.method(:bar) > >> Object.method_of(foo, :bar) > > >> That is, by making all these operations singleton methods of a module, > >> instead of (or as well as) instance methods which are present on all > >> objects, then there is never any chance of them being overriden by the > >> object itself. It's not very OO-like, but it *is* immune from this problem. > > > And this is straightforward to implement: > > > ----- 8< ------------------------------------------------------- > > module Meta > > def self.send(obj, meth, *args) > > Object.instance_method(:send).bind(obj).call(meth, *args) > > end > > > def self.class(obj) > > Object.instance_method(:class).bind(obj).call > > end > > > # etc > > end > > > class Foo > > def send(*args) > > "whoo!" > > end > > def class > > "stupid!" > > end > > end > > > f = Foo.new > > > puts f.class # stupid! > > puts Meta.class(f).inspect # Foo > > > puts f.send(:object_id) # whoo! > > puts Meta.send(f, :object_id) # -605608944 > > ----- 8< ------------------------------------------------------- > > > Implement all the methods you consider to be "metaprogramming" with whatever > > names you think are appropriate. Stick it up as a module on rubyforge, in > > case anyone comes across the same need as you. Job done, and no need to > > change the core language :-) > > Brian, this looks a lot like the concept of "mirrors" in the language > Self. See for examplehttp://bracha.org/mirrors.pdffor a discussion. I > like this approach. This suggestion has been around a long time, Ara reintroduced it recentaly as "Pervasives". And yes, it is the easiest to implement and doesn't require any change to Ruby's core. However it suffers from a few issues. 1) In very rare cases you might actually have a good reason to "trick" a caller. So still being able to override, say #object_class for instance, while very dangerous, may nonetheless be desirable --and it may be as simple as an AOP-like monitor which would have no real effect on functionality. 2) Having two ways to get the same information isn't as helpful. People will still use the old way b/c it's easier and they know it. You still won't be able to use common terms like #class or #send in your modules. (Of course we could get rid of the old methods altogether, but I got a feeling that won't go over well). 3) Using external functions has a very detering inertia of being long winded. Metaprogramming tends to use a lot of these calls in tight loc. If one has to type Meta.send(obj, meth) intsead of obj.send(meth) more than a few times, the code qucikly starts to become much less readable. That may seem silly, but in the end people just won't use it b/c of this (assuming they still have the other option). 4) It's a lot slower. It would need implementation in Ruby core anyway to fix this issue. T.