From: GGarramuno@... (GGarramuno) Date: 2004-01-13T18:06:50+09:00 Subject: Re: faster integer arithmetics & arbitrary precision floating number Florian Gross wrote in message news:<40036A7A.6000804@ccan.de>... > GGarramuno wrote: > > > Can extensions to base classes be kept within a specific namespace > > only? > > This is possible in current Ruby with libraries (See > http://uweb.superlink.net/~dblack/ruby/behaviors/ for a great library > David A. Black wrote to do exactly this.) and will be in the next bigger > revision of the core language. (Rite, or maybe even in Ruby 1.9) > > Regards, > Florian Gross Okay, how can I say this nicely...? No, I really can't. YUCK! I really hope that NEVER gets put into the language as a standard. Horrible syntax, TONS of work on the part of the developer to make it work, not thread safe, and it really does not address the issue to avoid namespace/function stomping unless you place everything into huge blocks. It is pretty powerful but it is also even more rope to hang yourself. Ugh! If you want to pursue something like, it should be simpler, something along the lines of: module Behavior @@bind = nil @@lastBehavior = nil @@cache = {} [ CLASS = 0, INSTANCE = 1, MODULE = 2 ] def Behavior.get_object_list() all = {} ObjectSpace.each_object(Object) { |i| case i when Class all[i] = {} # Class methods for m in i.methods begin all[i][m] = [ CLASS, i.method(m) ] rescue end end # Instance methods for m in i.instance_methods begin all[i][m] = [ INSTANCE, i.instance_method(m) ] rescue end end when Module all[i] = {} # Module methods for m in methods(i) all[i][m] = [ MODULE, method(m) ] end else #all[i] = i end } return all end # orig, new => returns y - x def Behavior.intersect(x,y) ret = {} for i in y.keys() if x.has_key?(i) fy = y[i] fx = x[i] for f in fy.keys() next if fx.has_key?(f) && fx[f][1] == fy[f][1] ret[i] = [fy[f][0], f] end else ret[i] = y[i] end end return ret end def Behavior.new(x,b) if @@cache.has_key?(x) raise RuntimeError," Behavior #{x} already defined!" end @@bind = b @@lastBehavior = x @@cache[x] = get_object_list() end def Behavior.end(x = @@lastBehavior) if !@@cache.has_key?(x) raise RuntimeError," Behavior #{x} was not defined!" end current = get_object_list() @@cache[x] = intersect( @@cache[x], current ) end def Behavior.drop(x) if !@@cache.has_key?(x) raise RuntimeError," Behavior #{x} was not defined!" end classes = @@cache[x] text = '' for cl in classes.keys() type = classes[cl][0] func = classes[cl][1] case type when CLASS text << "class #{cl}; undef #{cl}.#{func}; end;\n" when INSTANCE text << "class #{cl}; undef #{func}; end;\n" when MODULE text << "module #{cl}; undef #{func}; end;\n" end end eval text, @@bind @@cache.delete(x) end end ############################ Test Behavior::new(:myString,binding) class String def add() puts "AA" end end Behavior::end(:myString) "".add() Behavior::drop(:myString) "".add() =========================== cut This suffers from the same issues but it is at least a more automatic process and more directed to keeping modifications of built-in classes local to some file or files. But you know, even with that, it is still too much typing and in the above code, it does not handle alias or overloads automatically. Doing all that in plain ruby is just too slow. This comment of mine is probably sacrilege but I am getting more and more convinced that this pure OO is the devil in desguise and it is way more trouble than it's worth.