From: Yusuke ENDOH Date: 2010-11-25T20:06:58+09:00 Subject: [ruby-core:33375] Re: [Ruby 1.9-Feature#4085][Open] Refinements and nested methods Hi, Thank you for your reply! 2010/11/25 Shugo Maeda : > However, I'm afraid that there are too many patches, some of which > have been already reverted. Please fair them :-) >> - Your patch adds `klass' to stack frame, which may cause >> big performance degradation. We should check benchmark >> result (though I'm not so concerned). > > I have run "make benchmark" 5 times, and it shows that the modified > version is slower than average 2.5% than the original version. Sounds good! >> - API design. > Because I'd like to allow multiple refinements in one module, for > example, in the following case: > > module MyXmlFormat > refine Integer do > def to_xml; ...; end > end > > refine String do > def to_xml; ...; end > end > > refine Hash do > def to_xml; ...; end > end > ... > end After my short trial of this feature, I'd like an API to do `refine' and `using' at once without explicit module, such as: using_refine(Fixnum) do def /(other) quo(other) end end (equivalent to) using(Module.new do refine(Fixnum) do def /(other) quo(other) end end end) Note that we cannot define `using_define' by ourselves because of lexical scope limitation: def using_refine(klass, &blk) using(Module.new { refine(klass, &blk) }) end using_refine(Fixnum) do def /(other) quo(other) end end p 1 / 2 #=> 0 I guess that this `using_refine' is useful itself (though its name is arguable). In addition, it allows us to write MyXmlFormat as follows: module MyXmlFormat using_refine(Integer) do def to_xml; ...; end end using_refine(String) do def to_xml; ...; end end using_refine(Hash) do def to_xml; ...; end end end >> IMO, it will be more natural to provide this feature as new >> constract with new syntax, instead of Module's methods. > > First, I consider it, but I wouldn't like to introduce new keywords. I thought so, but I think that this feature deserves new keywords because it is big evolution of Ruby's OO paradigm (involving semantics change). However, we should discuss this topic (new keyword) towards 2.0. Module's methods are not bad, as a part of reflection features (such as Module#define_method for `def' keyword). >> - Is it intended to reject refining module methods? > It's limitation of the current implementation. If so, it may be good to raise a NotImplementedError. > However, I don't think it's critical, because If you'd like to refine > a module, you can refine a class which includes the module instead. Do you mean: include Math $toplevel = self module ComplexExt def sqrt(x) (x >= 0 ? 1 : Complex::I) * super(x.abs) end refine(class << Math; self; end) { include ComplexExt } refine(class << $toplevel; self; end) { include ComplexExt } end using ComplexExt p sqrt(-4) ? -- Yusuke Endoh