ナスカブログ

未来の自分へのドキュメント

Ruby Goldへの道 day6

以下のサイトでruby gold取得に向けて毎日一回Goldチャレンジを行い間違えた問題を簡単にまとめる。 rex.libertyfish.co.jp

6日目 得点 66点/100点中

停滞期に入ったな〜 70点の壁が厚い

今日から間違えた問題の深堀に方向転換

  • class_eval
    • ブロックを渡した場合は、ブロック内のネストはモジュールMになる
    • 文字列を渡した場合のネストの状態はクラスCです。
# ブロックを渡した例
# ブロックはモジュールになるからMモジュールないのCONSTを探索
class C
end

module M
  CONST = "Hello, world"

  C.class_eval do
    def awesome_method
      CONST
    end
  end
end

p C.new.awesome_method #=> "Hello, world"


# 文字列を渡した例
# ネストの中はクラスなのでCクラスのCONSTを探索
class C
  CONST = "Hello, world"
end

module M
  C.class_eval(<<-CODE)
    def awesome_method
      CONST
    end
  CODE
end

p C.new.awesome_method #=> "Hello, world"
  • 特異クラス
    • class << Hoge
    • class << self
    • def クラス.メソッド

の三パターンある 呼び出しはクラスメソッドと同じ クラス.メソッドで呼び出せる

class Hoge
  class << Hoge
    def hoge
      p '<< Hoge'
    end
  end
  
  class << self
    def hoge
      p '<< self'
    end
  end

  def Hoge.hoge
    p 'C.hoge'
  end
end
# 全てクラス.メソッドで呼び出せる
Hoge.hoge #=> "C.hoge"
# def Hoge.hoge..をコメントアウトすると
Hoge.hoge #=> "<< self"
# さらに<< self..をコメントアウトすると
Hoge.hoge #=> "<< Hoge"
class C
  class << C # またはself
    def fuga #=> 特異メソッド
      'Hi'
    end
  end

  def hoge #=> インスタンスメソッド
    'Goodbye'
  end
end

# クラス内に定義したメソッドはインスタンスメソッド
obj = C.new 
p obj #=> #<C:0x00007fb9128df8d8>
p obj.hoge #=> 'Goodbye'

p C.instance_methods(false) #=> [:hoge]
p C #=> C
# 特異メソッドの呼び出し
# クラスメソッドの呼び出しと同じ
p C.fuga #=> 'Hi'