From: zverok.offline@... Date: 2020-11-21T14:41:26+00:00 Subject: [ruby-core:101008] [Ruby master Feature#17336] using refined: do ... end Issue #17336 has been updated by zverok (Victor Shepelev). > It kind of seems nice to have the outer `using do ... end` which is saying "below are local monkey patches for this file". I'd say that one of the important usage of refinements (as for me) is _small_ adjustments to core/third-party classes, that make sense in the current context. And the whole point of this ticket, as well as #16241, is to make them as lightweight-feeling as possible. This is what feels "intuitively enough" to refine something: ```ruby refine Something do def foo #... ``` Everything that tries to be more formalistic, just raises the bar of "shouldn't I do a small refinement here?.." (well, somebody might argue that this bar should be high, but then what's the point of refinements?) So, for me "let's nest it in one more `using` for better organization" seems annoyingly redundant and un-Ruby-ish (like, there are many things that can be nested in more blocks for "better organization", like `attributes do ... end` or `private_methods do ... end`, or `constants do ... end`, but we don't do this, right? And if somebody wants to logically structure stuff, they do it with comments/order/non-code means) ---------------------------------------- Feature #17336: using refined: do ... end https://bugs.ruby-lang.org/issues/17336#change-88677 * Author: k0kubun (Takashi Kokubun) * Status: Closed * Priority: Normal ---------------------------------------- ## Problem When we need a monkey patch which is used only in a single file, we'd like to define a refinement and use it in the same place. The problem is that it needs deep indentation and `Module.new { ... }` which feels redundant. ```rb class Foo using Module.new { refine Array do def flat_map!(&block) replace(flat_map(&block)) end end } # ... end ``` @tagomoris proposed an idea to reduce indentation and remove `Module.new { ... }`. This looks pretty convenient, but I want to write `do ... end`, which would make it a block of `using` here, because we almost always use `... end` for defining methods or modules. ```rb module Kernel def refined(mod, &block) Module.new do refine(mod, &block) end end end class Foo using refined(Array) { def flat_map!(&block) replace(flat_map(&block)) end } # ... end ``` ## Proposal How about supporting this? Because `using` currently doesn't take a block, it doesn't conflict with the existing syntax. ```rb class Foo using refined: Array do def flat_map!(&block) replace(flat_map(&block)) end end # ... end ``` This syntax is based on ideas of @tagomoris and @znz . -- https://bugs.ruby-lang.org/ Unsubscribe: