From: Yusuke ENDOH Date: 2010-12-03T12:42:38+09:00 Subject: [ruby-core:33535] Re: [Ruby 1.9-Feature#4085][Open] Refinements and nested methods Hi, 2010/11/30 Charles Oliver Nutter : > The global serial number approach in 1.9 means that any change that > flip that serial number cause all caches everywhere to invalidate. > Normally this only happens on method definition or module inclusion, > which is why defining methods or including modules at runtime is > strongly discouraged for performance reasons. Sorry I'm not sure that I could follow your argument about performance, so I may miss your point. I guess that casual users will execute all refinements immediately after program is started, like class definition and method definition. Thus, the global serial number approach will work well for refinement in main use cases, I think. In the sense, nested function by using refinements may be a problem. > And one last case that's a problem: author's intent. If I write a > block of code that does "1 + 1", I intend for that code to do normal > Fixnum#+, and I intend for the result to be 2. It should not be > possible for a caller to change the intent of my code just because I > passed it in a bock. This has been my argument against using blocks as > bindings, and it's another argument against instance_eval being able > to force refinments into "someone else's code". This is not a problem, but rather improvement. There is already open class which so often breaks your intent. Refinements may also break your intent, but it is less often and more controllable than open class. > Now, some positive reinforcement for "using" being a keyword and > instance_eval not propagating refinements. I'm not against your proposal, but I wonder if it does not make sense because we can still write: eval("using FooExt") To address your concern, `using' keyword should have a block: using FooExt # FooExt enabled end # FooExt disabled I don't like this syntax because of more indentation, though. > I can try to come up with a concrete example of the problems with the > current proposal and implementation, but the concurrency cases would > be difficult to show. I might find serious concurrency problem of Shugo's patch, though I'm not sure that this is what you mean. Indeed, we may have to give up propagating refinements via block. class C def test; p :test; end end module FooExt refine(C) { def test; p :foo; end } end module BarExt refine(C) { def test; p :bar; end } end f = proc do sleep 1 C.new.test end FooExt.class_eval(&f) #=> :foo (expected) BarExt.class_eval(&f) #=> :bar (expected) [ Thread.new { FooExt.class_eval(&f) }, #=> :foo (expected) Thread.new { BarExt.class_eval(&f) } #=> :foo (not expected) ].each {|t| t.join } -- Yusuke Endoh