Method_missing_response

class Apa
  def koko
  end
end

apa = Apa.new
p apa.methods - Class.methods # => [:koko]
p apa.respond_to?(:koko) # => true

All is great and well. But…

class Apa
  def koko
  end

  def method_missing(name, *args)
    %i(schwab frances).include(name) ? (p args) : super
  end
end

apa = Apa.new
p apa.methods - Class.methods # => [:koko, :method_missing]

p apa.respond_to?(:koko) # => true
p apa.respond_to?(:schwab) # => false

Enter ‘respond_to_missing’

class Apa
  def koko
  end

  def method_missing(name, *args)
    %i(schwab frances).include?(name) ? (p args) : super
  end

  def respond_to_missing?(name, include_private = false)
    %i(schwab frances).include?(name)
  end
end

apa = Apa.new
p apa.methods - Class.methods # => [:koko, :method_missing]

p apa.respond_to?(:koko) # => true
p apa.respond_to?(:schwab) # => true

Now respond_to? return true for the method-names that method_missing is handling. The methods will still not appear in the .methods Array, but that can be solved by actually create the methods.


class Apa
  def koko
  end
end

p Apa.respond_to?(:koko) # => false

apa = Apa.new
p apa.respond_to?(:koko) # => true

class Kaka
  def self.koko
  end

  class << self
    def anka
    end
  end
end

p Kaka.respond_to?(:koko) # => true
p Kaka.respond_to?(:anka) # => true

# -----------------------------------------------------------------------------

class Fika
  def initialize
    @methods = %i(abra kadabra)
  end
  
  private
  def method_missing(name, *args)
    @methods.include?(name) ?
      (puts 'Missing: %s' % name) : super
  end
end

fika = Fika.new
p fika.methods - Object.methods # => []
# [:method_missing] would show up unless 'private'

fika.abra # => Missing: abra
# fika.filiokus # NoMethodError

p fika.respond_to?(:kadabra) # => false
# This can be corrected by adding a
# respond_to_missing? method

fika.define_singleton_method(:respond_to_missing?) {
  |name, include_private = false|
  @methods.include?(name)
}

# also, make it private
fika.singleton_class.class_eval { private :respond_to_missing? }



p fika.respond_to?(:kadabra) # => true

p fika.methods - Object.methods # => []