脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

メタプログラミングRuby 第1章 まとめ

メタプログラミングRubyの第1章を読んで、自分が興味あったとこのまとめ

クラスとモジュールの違い

  • classクラスはnew(), allocate(), superclass()を追加したmoduleにすぎない
  • includeされるものにはmoduleを使う
  • モジュールはクラス名が被らないようにネームスペースとして使うこともある
  • インスタンスを生成したり継承したりするものにはクラスを使う
  • 大抵の場合はクラスとモジュールのどちらも使うことは出来るが、目的に応じて使い分けると、他の人が読むときにわかりやすい
  • クラスもモジュールもインスタンスと違って定数である
  • 定数のパスはコロン二つ(::)で区切る
  • moduleはincludeされると,無名クラスを作ってラップされ、継承チェーンでincludeしたクラスの真上に来る
  • :print, :puts, :pとかはKernelモジュールのインスタンスメソッドで、ObjectクラスがKernelをインクルードして、Objectは全てのオブジェクトのsuperclassである
  • Kernelモジュールにメソッドを追加すればRubyのプログラムのどこでも使用することが出来る
  • gem()はKernelのインスタンスメソッドである
Kernel.private_instance_methods.grep(/^gem/)
=> [:gem, :gem_original_require]

self

  • カレントオブジェクトのこと
  • Rubyのプログラムが実行される場所
  • メソッドを呼び出すときはレシーバがself
  • レシーバを明示しない場合は常にselfがに対するメソッド呼び出しになる
  • Rubyのプログラムを開始すると、インタプリタが作成したmainというオブジェクトの中に入る
self #===> main
self.class #===> Object
  • クラスやモジュール内で、かつメソッド外の場合のselfはそのクラス(モジュール)を示す
  • pivateメソッドは、レシーバをつけて使えない=暗黙的にselfをレシーバとするということ

インスタンス変数とインスタンスメソッドの所在

Rubyの他の言語より優れた点

  • C#Javaもクラスはclassクラスのインスタンスであるが、Rubyに比べて非常に限定的で、実行時にクラスの作成は出来ないし、クラスのメソッドを変更することも出来ない。
  • クラスの情報は他の言語では読み取れるだけだが、Rubyは実行時に書き込むことも出来る

require()とload()とincludeの違い

  • requireとloadはファイルを読み込み、includeはmoduleを読み込む
  • load()はファイルを実行するために使う
  • 二番目の引数にオプションを与えると、定数を外部に漏らさない
load(’file’名, true)
    • この場合、無名モジュールを作成し、それをネームスーペースとして使って${ファイル名}の定数を読み込む
  • require()はライブラリを読み込むために使う
  • requireに二番目のオプションがないのは、ライブラリのファイルからクラス名を読み込むことが前提だから
  • includeでは、後にincludeされたものが優先される
module A
  def test_method
    puts "A"
  end
end

module B
  def test_method
    puts "B"
  end
end

class Test
  include A
  include B
.
.
.
end

Test.new.test_method #===> B
    • 継承チェーン的にincludeする毎に真上に無名クラスとしてmoduleを配置するので、同じメソッド名があった場合、後に読み込んだBの方のメソッドが呼び出される

(最初のAは一個上に押し出される)