Project

General

Profile

Actions

Feature #22474

closed

Kernel#using (or BasicObject#using)

Feature #22474: Kernel#using (or BasicObject#using)

Added by UlyssesZhan (Ulysses Zhan) about 10 hours ago. Updated about 9 hours ago.

Status:
Feedback
Assignee:
-
Target version:
-
[ruby-core:127240]

Description

Currently there is Module#using. The scope where using is effective is the lexical scope of the module eval block (blocks for module keyword, Module::new, module_eval, and module_exec). However, since any block is a lexical scope, why not allow using in any block? Example:

module R
  refine(Enumerable) { def f = 1 }
end

proc { using R; [].f }.() # => 1
[].f                      # => ! NoMethodError

Note that we can already achieve a similar effect in pure Ruby: it is possible to define a function while_using.

module Kernel
  private def while_using mod, binding, code
    old = Thread.current[:using_mod]
    Thread.current[:using_mod] = mod
    args = binding.local_variables.map { binding.local_variable_get _1 }
    result = TOPLEVEL_BINDING.eval(<<~RUBY).bind_call binding.receiver, *args
      Module.new do
        using Thread.current[:using_mod]
        def run #{binding.local_variables.join ', '}
          #{code}
        end
      end.instance_method :run
    RUBY
    Thread.current[:using_mod] = old
    result
  end
end

module R
  refine(Enumerable) { def f = 1 }
end

class C
  def g x
    @y = 1
    while_using R, binding, 'x + @y + [].f'
  end
end
C.new.g 1 # => 3

Related issues 1 (0 open — 1 closed)

Is duplicate of Ruby - Feature #22097: Add Proc#with_refinementsClosedshugo (Shugo Maeda)Actions
Actions

Also available in: PDF Atom