LoginSignup
0
0

More than 3 years have passed since last update.

読書ログ『メタプログラミング Ruby 第2版』3章

Posted at

3章 火曜日: メソッド

動的メソッド

  • メソッドを呼び出すというのは、オブジェクトにメッセージを送ること

Object#send

  • メソッドを呼び出すには、ドット記法Object#sendがある
    • obj.send(:my_method, 3)
  • Object#sendを使うと、どんなメソッドでも呼び出せてしまう
    • privateメソッドを呼び出せるからこそ、sendを使う

動的ディスパッチ

  • sendメソッドを使って、呼び出したいメソッド名を引数として、コードの実行時に呼び出すメソッドを決めること

メソッドを動的に定義する

Module#define_method

  • 実行時にメソッド名を定義できる
  • メソッド名とブロックを渡すことで、ブロックがメソッドの本体となる
class MyClass
    define_method :my_method do |my_arg|
        my_arg * 3
    end
end

obj = MyClass.new
obj.my_method(2) #=> 6

手順1: 動的ディスパッチを追加する

手順2: メソッドを動的に生成する

手順3: コードにイントロスペクションをふりかける

method_missing

  • BasicObjectクラスの、privateインスタンスメソッド

    • NoMethodErrorを返すのが役割
  • 指定したメソッドが継承チェーンを遡っても見つからない場合、Rubyは、method_missingを呼び出して負けを認める。

  • method_missingが呼び出されると

  hoge.send :method_missing, :my_method
  => NoMethodError: undefined method 'my_method' for <...>
  • method_missingをオーバーライドすると、実際には存在しないメソッドを呼び出せる
class Lawyer
  def method_missing(method, *args)
    puts "呼び出した: #{method}(#{args.join(',')})"
    puts "(ブロックも渡した)" if block_given?
  end
end

bob = Lawyer.new
bob.talk_simple('a', 'b') do
    # ブロック
end

=> 呼び出した: talk_simple(a,b)
(ブロックも渡した)

ゴーストメソッド

  • method_missingを呼び出す際、通常と同様に見えるが、レシーバ側に対応するメソッドが見当たらないこと。
    • 「君が理解できないことを頼まれたら、これをやっておいてね」という感じ

動的プロキシ

  • ゴーストメソッドを補足して、他のオブジェクトに転送するオブジェクトのこと。

respond_to_missing?

  • Rubyが、respond_to?にゴーストメソッドを認識させる仕組み
  • method_missingをオーバーライドしたときには、respond_to_missing?もオーバーライドすること。

const_missing

  • 存在しない定数を参照すると、Rubyは定数の名前をconst_missingにシンボルとして渡す。
  • クラス名は単なる定数なので、不明な参照はModule#const_missingに渡される

ブランクスレート

  • 最小限のメソッドしかない状態のクラスのこと
  • ブランクスレートが必要であれば、BasicObjectを直接継承する

まとめ

可能であれば動的メソッドを使い、仕方がなければゴーストメソッドを使う

感想

Object#sendを使って、動的にメソッドを呼び出すこと、Module#define_methodを使って、動的にメソッドを定義する、という動的メソッドの存在を知る。

また、BasicObject#method_missingを上書きし、存在しないメソッドをゴーストメソッドとして生成する方法を知る。

一旦は見た際に気づけるかな、という感覚。実際に自分で使うとなると、もう少し慣れや自信が必要かな、という肌感。:sweat:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0