Issue #17336 has been updated by Eregon (Benoit Daloze).


k0kubun (Takashi Kokubun) wrote in #note-7:
> It might be helpful anyway, but a part of the ticket's motivation was to eliminate the deep indentation.

Is it annoying in practice?
It kind of seems nice to have the outer `using do ... end` which is saying "below are local monkey patches for this file".
Instead of having to check if there are further `using refined: Array/refining` calls one after another.

And if those refinements are not trivial and the implementation needs quite some indentation, maybe the refinements should be defined in their own file under some module, that also solves the indentation.

I guess an example of real code where the deep indentation is problematic might help to convince me and maybe others.

----------------------------------------
Feature #17336: using refined: do ... end
https://bugs.ruby-lang.org/issues/17336#change-88656

* 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: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>