From: Yukihiro Matsumoto Date: 2010-09-08T18:00:01+09:00 Subject: [ruby-core:32133] Re: Ruby 2.0 Wiki/Wish-list? Hi, In message "Re: [ruby-core:32132] Re: Ruby 2.0 Wiki/Wish-list?" on Wed, 8 Sep 2010 17:40:28 +0900, Joshua Ballanco writes: |-- full access to subclass from metaclasses | |Essentially, I'd like to be able to do the following: | |>> a = 'hello, world' |=> "hello, world" |>> class<> def my_awesome_method |>> self.length ** 2 |>> end |>> end |=> nil |>> a.my_awesome_method |=> 144 |>> a.class |=> String |>> b = a.singleton_class.new |=> "" |>> b.class |=> String |>> b << 'test' |=> "test" |>> b.my_awesome_method |=> 16 | |As it is now, calling "a.singleton_class.new" raises an error. The idea of doing this would be to create a new object with all the same methods but without copying the properties. i.e. Prototype-based inheritance. The key, here, is that we can add methods to an instance of a class, and create new instances of that class without needing to create a subclass just to do so. I feel that, used properly, this feature might reduce some of the "polution" of core types that certain Ruby libraries suffer from, as people would be less tempted to open core classes just to add a few methods. Interesting. Right now, we provide prototyped OO can be emulated by using #clone method (following prototyping tradition). >> a = 'hello, world' => "hello, world" >> class<> def my_awesome_method >> self.length ** 2 >> end >> end => nil >> a.my_awesome_method => 144 >> a.class => String >> b = a.clone => "hello, world" >> b.class => String >> b.replace 'test' => "test" >> b.my_awesome_method => 16 I think using #clone is better than allowing instances from singleton_classes. |-- true (or, let's call it "lightweight") namespacing | |A very common idiom in Ruby today is to pull all of the classes/modules of a project inside an "umbrella" module like so: |---1 |> cat my_first_class.rb |module MyModule | class MyFirstClass | def a_method | ... | end | end |end | |> cat my_second_class.rb |module MyModule | class MySecondClass | def another_method | ... | end | end |end |--- |There are two problems I see with this approach. First, the programmer is creating *and* reopening a module, perhaps many times, just to gain a level of scope. This module is not intended to be used as a mix-in, so all of the internal datastructures and mechanisms that enable mixing-in need to be set-up, but they are never used. Second, in the results of Object#constants there will be an entry for MyModule, but again MyModule is only being used to add a layer of scope. So, what I would like is a "namespace" keyword which adds to the constant resolution chain, but does not actually create a module for mix-ins and does not appear as an independent constant. It is lightweight in that it is only affecting lookup. Also, when someone does not want to have to always type "MyModuleName::MyClassName", currently the only option is to do "include MyModuleName", but this is doing a mix-in when all the programmer wanted to do was to remove a layer of constant resolution. Being lightweight with the cost of complexity (both concept and implementation) may not be worth adding to the language, especially when considering the cost is minimal for both time-wise and space-wise. But avoiding "include MyModuleName" may be considerably worth. I am not sure yet. matz.