class RSpec::Mocks::MethodReference

@private
any object.
The method may be an instance method on a module or a method on
Represents a method on an object that may or may not be defined.

def self.instance_method_visibility_for(klass, method_name)

def self.instance_method_visibility_for(klass, method_name)
  if klass.public_method_defined?(method_name)
    :public
  elsif klass.private_method_defined?(method_name)
    :private
  elsif klass.protected_method_defined?(method_name)
    :protected
  end
end

def self.method_visibility_for(object, method_name)

def self.method_visibility_for(object, method_name)
  instance_method_visibility_for(class << object; self; end, method_name).tap do |vis|
    # If the method is not defined on the class, `instance_method_visibility_for`
    # returns `nil`. However, it may be handled dynamically by `method_missing`,
    # so here we check `respond_to` (passing false to not check private methods).
    #
    # This only considers the public case, but I don't think it's possible to
    # write `method_missing` in such a way that it handles a dynamic message
    # with private or protected visibility. Ruby doesn't provide you with
    # the caller info.
    return :public if vis.nil? && object.respond_to?(method_name, false)
  end
end

def defined?

In that case, we can assert against metadata like the arity.
A method is defined if we are able to get a `Method` object for it.
def defined?
  @object_reference.when_loaded do |m|
    method_defined?(m)
  end
end

def implemented?

`method_missing`.
a `NoMethodError`. It might be dynamically implemented by
A method is implemented if sending the message does not result in
def implemented?
  @object_reference.when_loaded do |m|
    method_implemented?(m)
  end
end

def initialize(object_reference, method_name)

def initialize(object_reference, method_name)
  @object_reference = object_reference
  @method_name = method_name
end

def original_method

def original_method
  @object_reference.when_loaded do |m|
    self.defined? && find_method(m)
  end
end

def unimplemented?

both `implemented?` and `unimplemented?` will return false.
cases when we don't know if a method is implemented and
This is not simply the inverse of `implemented?`: there are

will result in a `NoMethodError`.
Returns true if we definitively know that sending the method
def unimplemented?
  @object_reference.when_loaded do |m|
    return !implemented?
  end
  # If it's not loaded, then it may be implemented but we can't check.
  false
end

def visibility

def visibility
  @object_reference.when_loaded do |m|
    return visibility_from(m)
  end
  # When it's not loaded, assume it's public. We don't want to
  # wrongly treat the method as private.
  :public
end

def with_signature

def with_signature
  if original = original_method
    yield Support::MethodSignature.new(original)
  end
end