# 7-3 method_missing
no_method()
NoMethodError: undefined method `no_method' for main:Object (pry):1:in `<main>' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:387:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:387:in `evaluate_ruby' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:355:in `handle_line' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:274:in `block (2 levels) in eval' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:273:in `catch' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:273:in `block in eval' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:272:in `catch' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:272:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/backend.rb:66:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/backend.rb:12:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/kernel.rb:87:in `execute_request' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/kernel.rb:47:in `dispatch' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/kernel.rb:37:in `run' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/command.rb:70:in `run_kernel' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/command.rb:34:in `run' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/bin/iruby:5:in `<top (required)>' /home/jovyan/.gem/ruby/2.6.0/bin/iruby:23:in `load' /home/jovyan/.gem/ruby/2.6.0/bin/iruby:23:in `<main>'
# BasicObject#method_missingのコードはうまく動かなかったのでスキップ
# Kernel.#caller の `.#` はモジュール関数?
# 7-3-2 method_missingの使い方
class DelegateArray
def initialize
@array = []
end
end
:initialize
delegate_array = DelegateArray.new
delegate_array << 1
NoMethodError: undefined method `<<' for #<DelegateArray:0x000055c214dff648 @array=[]> (pry):14:in `<main>' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:387:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:387:in `evaluate_ruby' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:355:in `handle_line' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:274:in `block (2 levels) in eval' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:273:in `catch' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:273:in `block in eval' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:272:in `catch' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:272:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/backend.rb:66:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/backend.rb:12:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/kernel.rb:87:in `execute_request' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/kernel.rb:47:in `dispatch' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/kernel.rb:37:in `run' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/command.rb:70:in `run_kernel' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/command.rb:34:in `run' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/bin/iruby:5:in `<top (required)>' /home/jovyan/.gem/ruby/2.6.0/bin/iruby:23:in `load' /home/jovyan/.gem/ruby/2.6.0/bin/iruby:23:in `<main>'
class DelegateArray
def method_missing(name, *args)
@array.__send__ name, *args
end
end
:method_missing
delegate_array << 1
[1]
delegate_array << 2
[1, 2]
# 7-3-3 注意点
class LoopMethodMissingClass
def method_missing(name, *args)
__send__(name)
end
end
# LoopMethodMissingClass.new.no_method # 無限ループ!
:method_missing
class OverrideMethodMissing
def method_missing(method_name, *args)
if method_name == :target_method
return 'target_method is called'
end
super
end
end
:method_missing
OverrideMethodMissing.new.no_method
NoMethodError: undefined method `no_method' for #<OverrideMethodMissing:0x000055c2147f9cd0> (pry):36:in `method_missing' (pry):39:in `<main>' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:387:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:387:in `evaluate_ruby' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:355:in `handle_line' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:274:in `block (2 levels) in eval' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:273:in `catch' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:273:in `block in eval' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:272:in `catch' /home/jovyan/.gem/ruby/2.6.0/gems/pry-0.12.2/lib/pry/pry_instance.rb:272:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/backend.rb:66:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/backend.rb:12:in `eval' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/kernel.rb:87:in `execute_request' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/kernel.rb:47:in `dispatch' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/kernel.rb:37:in `run' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/command.rb:70:in `run_kernel' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/lib/iruby/command.rb:34:in `run' /home/jovyan/.gem/ruby/2.6.0/gems/iruby-0.3/bin/iruby:5:in `<top (required)>' /home/jovyan/.gem/ruby/2.6.0/bin/iruby:23:in `load' /home/jovyan/.gem/ruby/2.6.0/bin/iruby:23:in `<main>'
OverrideMethodMissing.new.target_method
"target_method is called"
# railsでmethod_missingが使われているところ
# https://github.com/rails/rails/blob/607d77ab073581172a66b26e2807790cd723719e/activerecord/lib/active_record/relation/delegation.rb#L103-L110
# ActiveSupport#StringInquirer の method_missing
class StringInquirer < String
def method_missing(method_name, *arguments)
if method_name[-1] == "?"
self == method_name[0..-2]
else
super
end
end
end
:method_missing
string = StringInquirer.new("foo")
puts string.foo?
puts string.bar?
true false
# 次回は7-4 evalから