From: The 8472 Date: 2012-11-22T08:02:17+09:00 Subject: [ruby-core:49836] Re: [ruby-trunk - Feature #4085] Refinements and nested methods On 21.11.2012 07:15, shugo (Shugo Maeda) wrote: > I'll remove it if permission granted by Matz. > >> For now people can use Module.extended/.included if they really want to >> add refinement inheritance themselves. > > Currently this wouldn't work because you cannot get the caller context in these hooks. What about the following? module RefinementInheritor def extended(base) base.send(:using, FooExt) # or base.module_eval "using FooExt" end end >> Probably the safest approach for now would be to use the source >> refinement scope (which is quasi-static) for module_eval by default and >> add a way to use the target scope (or an explicit scope) later on as >> needed. If there is any performance impact it would restricted to the >> target-scoped procs. > > Do you mean that a new option of module_eval should be introduced? > For example, > > Foo.module_eval { # use refinements in the current context } > Foo.module_eval(using_refinements: true) { # use refinements in the receiver } I was thinking about Proc.new.rebind_refinements(TargetClass) since this would only allow a single scope per proc at any given time which might make optimizations easier. But maybe your way would work too. > Originally, String#bar was not visible in the Proc created by Symbol#to_proc. > But I've changed it because Matz asked to do. I think the current behavior > is not consistent, but useful. > > If Symbol#to_proc were written in Ruby, it would be impossible, but > Symbol#to_proc is written in C. There are some such special methods. > For example, Module.nesting returns the module nesting information in the > caller context. Module#using also affects the caller context. So we need to special-case .to_proc. What happens when I alias-method-chain to_proc? Would it use the wrong scope? Would things break? .__send__ and .method obviously suffer from the same issues of shifting stack frames and aliasing. Other metaprogramming things might be expected to do the "right thing(tm)" too and thus would have to rely on stack inspection which is an absolute minefield in Ruby. Should the anonymous refinement module be mutable? E.g. by adding some respond_to_missing to it? Has anyone even defined how metaprogramming should work with refinements?