class RubyNext::Core::Patch

Patch contains the extension implementation and meta information (e.g., Ruby version).

Attributes

body[R]
core_ext[R]
location[R]
method_name[R]
mod[R]
name[R]
native[R]
native?[R]
refineables[R]
singleton[R]
singleton?[R]
supported[R]
supported?[R]
version[R]

Public Class Methods

new(mod = nil, method:, version:, name: nil, supported: nil, native: nil, location: nil, refineable: mod, core_ext: :patch, singleton: nil) { || ... } click to toggle source

Create a new patch for module/class (mod) with the specified uniq name

`core_ext` defines the strategy for core extensions:

- :patch — extend class directly
- :prepend — extend class by prepending a module (e.g., when needs `super`)
# File lib/ruby-next/core.rb, line 21
def initialize(mod = nil, method:, version:, name: nil, supported: nil, native: nil, location: nil, refineable: mod, core_ext: :patch, singleton: nil)
  @mod = mod
  @method_name = method
  @version = version
  if method_name && mod
    @supported = supported.nil? ? mod.method_defined?(method_name) : supported
    # define whether running Ruby has a native implementation for this method
    # for that, we check the source_location (which is nil for C defined methods)
    @native = native.nil? ? (supported? && native_location?(mod.instance_method(method_name).source_location)) : native
  end
  @singleton = singleton
  @refineables = Array(refineable)
  @body = yield
  @core_ext = core_ext
  @location = location || build_location(caller_locations(1, 5))
  @name = name || build_module_name
end

Public Instance Methods

core_ext?() click to toggle source
# File lib/ruby-next/core.rb, line 43
def core_ext?
  !mod.nil?
end
prepend?() click to toggle source
# File lib/ruby-next/core.rb, line 39
def prepend?
  core_ext == :prepend
end
to_module() click to toggle source
# File lib/ruby-next/core.rb, line 51
def to_module
  Module.new.tap do |ext|
    ext.module_eval(body, *location)

    RubyNext::Core.const_set(name, ext)
  end
end

Private Instance Methods

build_location(trace_locations) click to toggle source
# File lib/ruby-next/core.rb, line 68
def build_location(trace_locations)
  # The caller_locations behaviour depends on implementaion,
  # e.g. in JRuby https://github.com/jruby/jruby/issues/6055
  while trace_locations.first.label != "patch"
    trace_locations.shift
  end

  trace_location = trace_locations[1]

  [trace_location.absolute_path, trace_location.lineno + 2]
end
build_module_name() click to toggle source
# File lib/ruby-next/core.rb, line 61
def build_module_name
  mod_name = singleton? ? singleton.name : mod.name
  camelized_method_name = method_name.to_s.split("_").map(&:capitalize).join

  "#{mod_name}#{camelized_method_name}".gsub(/\W/, "")
end
native_location?(location) click to toggle source
# File lib/ruby-next/core.rb, line 80
def native_location?(location)
  location.nil? || location.first.match?(/(<internal:|resource:\/truffleruby\/core)/)
end