From: Charles Oliver Nutter Date: 2010-12-06T21:13:23+09:00 Subject: [ruby-core:33594] Re: [Ruby 1.9-Feature#4085][Open] Refinements and nested methods On Sun, Dec 5, 2010 at 11:41 PM, Yehuda Katz wrote: > I think that, for this same reason, `using` should normally not apply > outside of the immediate lexical scope. I actually believed that this was > the default behavior, and explained why I thought it was a good idea on my > blog (http://yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice/). ... > I can understand the utility of offering the inherited style when desired, > but I don't think it should be the default. By default, the principle of > this feature requires that refinements modify zero code outside its lexical > scope. > Perhaps a special form of using that would also affect subclasses (for > example, for the case where Rails wants to expose ActiveSupport into its > subclasses): > class ActionController::Base > ����using ActiveSupport, inherited: true > end Im not sure inheritance is possible to support at all, since classes don't know about their child classes (officially) and reopening a class could not easily walk its children and make refinements apply to them after the fact. Perhaps I missed the discussion about this feature. "using" should be applied similar to "public/private/protected/module_function". In a sense, it's a "refined" flag on the current scope that specifies that subsequent scope creations should be "refined" in some way. There's no room for leaking "private" and friends to definitions outside the lexical scope, and the same should apply to "using". By a similar token, "using" isn't impossible to apply after the fact (i.e. adding a refinement "later" to some scope), but it is *infeasible*. Because ideally we'd want to be able to flip a bit on all calls about to be affected by the refinement, we'd need to guarantee across all implementations that call sites are mutable at runtime, where they aren't mutable now (or at least aren't consistently and equivalently mutable). And just as mutating global state would be bad (like flipping methods "private" in one thread while they're being used in a another), so would having "using" change the way a particular call site does its invocation after that site has been constructed and released into the wild. I suggest we drop the "pseudo" from "pseduolexical" in the Refinements specification, and see where that takes us. Anything "pseudo" lexical is dynamic scoping, which fails multiple performance, concurrency, and obviousness tests for me. - Charlie