LoginSignup
0
0

More than 5 years have passed since last update.

メタプログラミングRuby第2版 まとめ

Last updated at Posted at 2018-10-20

memo

ほぼ個人的なまとめ、memoです。
+αの知見があったらコメントでください。
随時更新していきます。

第1章 頭文字M

obj#instance_varibles

  • そのオブジェクトに定義されているインスタンス変数を取得
class Test
  def initialize
    @instance_variable = 'test'
test.instance_variables #引数の期待無し
=> [:@instance_variable]

attrメソッド

  • attr_writer => インスタンス変数のsetterを用意
  • attr_reader => インスタンス変数のgetterを用意
  • attr_accessor => インスタンス変数のgetter,setterを用意

第2章 オブジェクトモデル

オープンクラス

  • 既存のクラスを拡張する実装方法
  • メソッドの衝突に注意!!
#Classに同名のMethodが無いか確認する。下記メソッドの後に#grep/hoge/で探索
Class.methods #クラスのメソッド一覧
instance.instance_methods #クラスのインスタンスメソッド一覧
instance.public_methods #publicなメソッド一覧
instance.instance_public_methods #publicなインスタンスメソッド一覧
instance.methods(false) 

Module#nesting

class Outer
  p Module.nesting
  module Inner
    p Module.nesting
  end
end

p Module.nesting

[Outer]
[Outer::Inner, Outer]
[]

メソッド探索

  • レシーバ
    • 呼び出すメソッドが属するオブジェクトのこと。ex my_string.reverseのmy_string
  • 継承チェーン
    • クラスからスーパークラスへ、さらにそのスーパークラスからスーパークラスへ、その道筋が継承チェーン
  • 探索を一言でまとめると「Rubyがレシーバのクラスに入り、メソッドを見つけるまで継承チェーンをたどること」
  • この動きを「右へ一歩、それから上へ(one step to the right,then up)」ルールと呼ばれる
  • 継承チェーン一覧#ancestors rb MySubclass.ancestors # => [MySubclass, MyClass, Object, Kernel, BasicObject]
  • 継承にはモジュールも含まれる
    • include => そのクラスの真上
    • prepend => そのクラスの真下
  • モジュールがすでにチェーンに存在している場合、二回目の挿入を無視
  • Object include Kernel
    • Kernelをオープンクラスしてメソッドをつけたらどこでも使えるようになる。gemとかでは多い。けど危ない
  • self => 現在のレシーバ => current_object
  • private
    • class内でself.private_mathodの呼び出しは出来ない。
    • private内ではレシーバがそのclassであるから(selfだと呼び出し先のobjectになってしまう。)

Refinements

  • オープンクラスがモンキーパッチにならないような対策
  • moduleの中で定義
  • usingを使用した箇所からソースファイル終わりまで使えるようになる
  • 限定的にパッチを当てることが出来る
  module StringExtentions
    refine String do
      def hoge
        p ''hoge
      end
    end
  end

  'page'.hoge => nomethod_error
  using StringExtentions
  'page'.hoge => hoge
  • まだ定着していないかも

第3章 メソッド

動的メソッド

  • define_methodで定義 ### 動的ディスパッチ
  • sendを使ってメソッドを呼び出す。 rb obj.my_method(3) obj.send(:my_method,3)
  • コードの実行時に呼び出すメソッドを決められる
  • privateなメソッドも呼び出すことが出来る
  • あまり理解できてない気がする

grepにブロックを渡す

  • matchにした要素に対してブロックを実行してくれる

method_missing

  • ゴーストメソッド
    • method_missingで定義されるrespond_toに反応しないメソッド
  • respond_to_missing
    • respond_toで呼び出しているメソッド
    • method_missingをorverrideする場合respond_to_missingも上書きしてrespond_toが正しく反応するようにすること
  • バグ対策
    • method_missingできちんと定義時に分岐をさせて必要のないときにはsuperを呼ぶ

ブランクスレート

  • ゴーストメソッドを使った時既存の予期しないメソッドとぶつかってしまう事がある。
  • そのようなバグに備え最低限のメソッドしか定義していない状態のこと
  • そもそも継承元をBasicObject等にするといいかも
  • undef_method 引数のメソッドを未定義にする

第四章 ブロック

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