module GraphQL::Define::InstanceDefinable

@api deprecated

Public Class Methods

included(base) click to toggle source
# File lib/graphql/define/instance_definable.rb, line 23
def self.included(base)
  base.extend(ClassMethods)
  base.ensure_defined(:metadata)
end

Public Instance Methods

define(**kwargs, &block) click to toggle source

@api deprecated

# File lib/graphql/define/instance_definable.rb, line 43
def define(**kwargs, &block)
  deprecated_define(**kwargs, &block)
end
deprecated_define(**kwargs, &block) click to toggle source

@api deprecated

# File lib/graphql/define/instance_definable.rb, line 34
def deprecated_define(**kwargs, &block)
  # make sure the previous definition_proc was executed:
  ensure_defined
  stash_dependent_methods
  @pending_definition = Definition.new(kwargs, block)
  nil
end
initialize_copy(other) click to toggle source
Calls superclass method
# File lib/graphql/define/instance_definable.rb, line 55
def initialize_copy(other)
  super
  @metadata = other.metadata.dup
end
metadata() click to toggle source

@api deprecated

# File lib/graphql/define/instance_definable.rb, line 29
def metadata
  @metadata ||= {}
end
redefine(**kwargs, &block) click to toggle source

@api deprecated

# File lib/graphql/define/instance_definable.rb, line 48
def redefine(**kwargs, &block)
  ensure_defined
  new_inst = self.dup
  new_inst.deprecated_define(**kwargs, &block)
  new_inst
end

Private Instance Methods

ensure_defined() click to toggle source

Run the definition block if it hasn't been run yet. This can only be run once: the block is deleted after it's used. You have to call this before using any value which could come from the definition block. @return [void]

# File lib/graphql/define/instance_definable.rb, line 67
def ensure_defined
  if @pending_definition
    defn = @pending_definition
    @pending_definition = nil

    revive_dependent_methods

    begin
      defn_proxy = DefinedObjectProxy.new(self)
      # Apply definition from `define(...)` kwargs
      defn.define_keywords.each do |keyword, value|
        # Don't splat string hashes, which blows up on Rubies before 2.7
        if value.is_a?(Hash) && !value.empty? && value.each_key.all? { |k| k.is_a?(Symbol) }
          defn_proxy.public_send(keyword, **value)
        else
          defn_proxy.public_send(keyword, value)
        end
      end
      # and/or apply definition from `define { ... }` block
      if defn.define_proc
        defn_proxy.instance_eval(&defn.define_proc)
      end
    rescue StandardError
      # The definition block failed to run, so make this object pending again:
      stash_dependent_methods
      @pending_definition = defn
      raise
    end
  end
  nil
end
revive_dependent_methods() click to toggle source

Take the pending methods and put them back on this object's singleton class. This reverts the process done by {#stash_dependent_methods} @return [void]

# File lib/graphql/define/instance_definable.rb, line 102
def revive_dependent_methods
  pending_methods = @pending_methods
  self.singleton_class.class_eval {
    pending_methods.each do |method|
      undef_method(method.name) if method_defined?(method.name)
      define_method(method.name, method)
    end
  }
  @pending_methods = nil
end
stash_dependent_methods() click to toggle source

Find the method names which were declared as definition-dependent, then grab the method definitions off of this object's class and store them for later.

Then make a dummy method for each of those method names which:

  • Triggers the pending definition, if there is one

  • Calls the same method again.

It's assumed that {#ensure_defined} will put the original method definitions back in place with {#revive_dependent_methods}. @return [void]

# File lib/graphql/define/instance_definable.rb, line 125
def stash_dependent_methods
  method_names = self.class.ensure_defined_method_names
  @pending_methods = method_names.map { |n| self.class.instance_method(n) }
  self.singleton_class.class_eval do
    method_names.each do |method_name|
      undef_method(method_name) if method_defined?(method_name)
      define_method(method_name) { |*args, &block|
        ensure_defined
        self.send(method_name, *args, &block)
      }
    end
  end
end