From: ES Date: 2005-10-21T03:13:17+09:00 Subject: Re: namespaces implemented in ruby Paul Brannan wrote: > On Thu, Oct 20, 2005 at 11:11:43AM +0900, NBarnes wrote: > >>What would namespaces do for ruby that I, as a developer, shoud care >>about? My current experience of them in my C++ is that they're magic >>lines I put in my headers to allow access to classes of useful >>functions, and thus I have them lumped in my brain as much like a >>library, but different in a way that I understand less well than I >>should. > > > The goal behind namespaces is the same as David Alan Black's Ruby > Behaviors (http://www.wobblini.net/ruby/behaviors/). Unfortunately Ruby > Behaviors is not thread-safe, so we desire a better solution. At the > first RubyConf, David Simmons introduced us to the idea of selector > namespaces, and Matz wants to add them to Ruby 2.0. > > Namespaces as I have implemented them (which are not entirely unlike > selector namespaces) differ from C++ namespaces greatly. C++ does not > allow modifying a class once it has been defined; Ruby does. The result > is that in Ruby, two different libraries can both add the same method to > a builtin class. Using namespaces in Ruby, each version of the method > can be added to a different namespace, and user code can select which > version of the method it wants (C++ namespaces would not allow two > functions from the same class to reside in different namespaces; to get > equivalent behavior in C++, one would use function overloading). > > An example in Ruby: > > class String > namespace :GPM { > def %(*args) > # namespace GPM modifies String#% to add formatting for GPM > # integers and rationals > end > } > end > > class String > namespace :BigDecimal { > def %(*args) > # namespace BigDecimal modifies String#% to add formatting for > # BigDecimals > end > } > end > > bd = BigDecimal.new("10") ** 65536 > > puts "%06f" % bd # this outputs the wrong answer > > use :BigDecimal { > puts "%06f" % bd # this gives the right answer > } > > I don't think this is an ideal syntax for namespaces; I'm only working > with what Ruby gives me. Ideally constants could also be defined in a > namespace, so you could have the global String class or your own String > class in your own namespace. The granularity used for declarations above would typically not be necessary. # orig.rb class SomeClass def foo() puts 'foo' end end # ns.rb namespace NS class SomeClass def foo() puts 'bar' end end end # test1.rb require 'orig' require 'ns' SomeClass.new.foo # 'foo' SomeClass.new.NS:foo # 'bar' The alternative with more explicit invocation is just: with NS do SomeClass.new.foo end Of course, truly excellent would be just being able to do this with modules or Traits (some of the new proposals are definitely overlapping) so that an explicit class would not be required: # test2.rb require 'orig' module AdditionalBehaviour def foo() puts 'quux' end end with AdditionalBehaviour do SomeClass.new.foo end # 'quux' SomeClass.new.AdditionalBehaviour:foo # 'quux' SomeClass.new.foo # 'foo' This, then, definitely strides into the AOP territory. > On a side note, I used to be strongly against modifying classes. I have > since realized that Ruby only provides one mechanism for method > dispatch, and that mechanism dispatches based on the class of the > receiver. The user is then left with two options: to write his own > dispatch mechanism or make use of the builtin dispatch mechanism in > Ruby. The latter is far simpler. > > On another side note, you should NEVER put a using declaration inside a > C++ header unless it resides in its own scope. See Herb Sutter's > GOTW#53 (http://www.gotw.ca/gotw/053.htm) for a better explanation than > I can give. > > Paul > > > > > >