mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 12:14:51 +00:00
[ruby/forwardable] Simpler and faster check for the delegation fastpath
Fix: https://github.com/ruby/forwardable/issues/35 [Bug #21708] Trying to compile code to check if a method can use the delegation fastpath is a bit wasteful and cause `RUPYOPT=-d` to be full of misleading errors. It's simpler and faster to use a simple regexp to do the same check. https://github.com/ruby/forwardable/commit/de1fbd182e
This commit is contained in:
parent
375025a386
commit
14ff851185
@ -109,8 +109,6 @@
|
||||
# +delegate.rb+.
|
||||
#
|
||||
module Forwardable
|
||||
require 'forwardable/impl'
|
||||
|
||||
# Version of +forwardable.rb+
|
||||
VERSION = "1.3.3"
|
||||
VERSION.freeze
|
||||
@ -206,37 +204,33 @@ module Forwardable
|
||||
if Module === obj ?
|
||||
obj.method_defined?(accessor) || obj.private_method_defined?(accessor) :
|
||||
obj.respond_to?(accessor, true)
|
||||
accessor = "#{accessor}()"
|
||||
accessor = "(#{accessor}())"
|
||||
end
|
||||
|
||||
args = RUBY_VERSION >= '2.7' ? '...' : '*args, &block'
|
||||
method_call = ".__send__(:#{method}, #{args})"
|
||||
if _valid_method?(method)
|
||||
if method.match?(/\A[_a-zA-Z]\w*[?!]?\z/)
|
||||
loc, = caller_locations(2,1)
|
||||
pre = "_ ="
|
||||
mesg = "#{Module === obj ? obj : obj.class}\##{ali} at #{loc.path}:#{loc.lineno} forwarding to private method "
|
||||
method_call = "#{<<-"begin;"}\n#{<<-"end;".chomp}"
|
||||
begin;
|
||||
unless defined? _.#{method}
|
||||
::Kernel.warn #{mesg.dump}"\#{_.class}"'##{method}', uplevel: 1
|
||||
_#{method_call}
|
||||
else
|
||||
_.#{method}(#{args})
|
||||
end
|
||||
end;
|
||||
method_call = <<~RUBY.chomp
|
||||
if defined?(_.#{method})
|
||||
_.#{method}(#{args})
|
||||
else
|
||||
::Kernel.warn #{mesg.dump}"\#{_.class}"'##{method}', uplevel: 1
|
||||
_#{method_call}
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
_compile_method("#{<<-"begin;"}\n#{<<-"end;"}", __FILE__, __LINE__+1)
|
||||
begin;
|
||||
eval(<<~RUBY, nil, __FILE__, __LINE__ + 1)
|
||||
proc do
|
||||
def #{ali}(#{args})
|
||||
#{pre}
|
||||
begin
|
||||
#{accessor}
|
||||
end#{method_call}
|
||||
#{pre}#{accessor}
|
||||
#{method_call}
|
||||
end
|
||||
end
|
||||
end;
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
||||
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
||||
|
||||
spec.required_ruby_version = '>= 2.4.0'
|
||||
spec.files = ["forwardable.gemspec", "lib/forwardable.rb", "lib/forwardable/impl.rb"]
|
||||
spec.files = ["forwardable.gemspec", "lib/forwardable.rb"]
|
||||
spec.bindir = "exe"
|
||||
spec.executables = []
|
||||
spec.require_paths = ["lib"]
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
module Forwardable
|
||||
# :stopdoc:
|
||||
|
||||
def self._valid_method?(method)
|
||||
catch {|tag|
|
||||
eval("BEGIN{throw tag}; ().#{method}", binding, __FILE__, __LINE__)
|
||||
}
|
||||
rescue SyntaxError
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
|
||||
def self._compile_method(src, file, line)
|
||||
eval(src, nil, file, line)
|
||||
end
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user