Rubyが書けるようになってきたら読んでおこう

業務でのRails歴も2ヶ月を超えてだんだんRubyに慣れてきたんですが、昨日putsやpメソッドってどこにあるんだっけ?と聞かれて即答できたのが悔しかったので、Rubyの基本についておさらいしてみました。

ちなみに

pやputsなどの組み込み関数的に使うメソッドはObjectクラスがインクルードしているKernelモジュールにあります。
http://www.sakalab.org/prog-ruby/ruby-man-html-20080121/_C1C8A4DFB9FEA4DFB4D8BFF4.html

自分的理解

組み込み関数はない

Rubyはなんでもオブジェクトな言語なので実際にはどこからでも呼べる組み込み関数というものがあるわけではない。組み込み関数のように使えるpやputs、よく使うところだとlambdaやopenはオブジェクトクラスのprivateメソッド。

class Aaa
  def aaa
    puts "aaa!"
  end
end

Aaa.new.aaa # => aaa!

↑のputsメソッドはAaa.newで生成されてインスタンスのメソッドを呼び出しているということ。

上書きすると使えなくなる
class Aaa < File
  def aaa
    puts "aaa!"
  end
end

Aaa.new("test.txt", "w").aaa # => nil

あれputsした文字列はどこへ?

more test.txt
aaa!

なるほど、Fileクラスでputsはファイルに追記するメソッドに上書きされているから、test.txtにaaa!という文字がはかれたわけだ。

そのためのKernelモジュール

ここはあまり自信ないのだけれど、上の例でAaaではputsでコンソールに出したいとしよう(Fileを継承する意味ない!という話はとりあえず置いといて)

class Aaa < File
  include Kernel
  def aaa
    puts "aaa!"
  end
end

Aaa.new.aaa # => aaa!

できた!ポイントはinclude Kernel。

↓にあるように、ObjectのメソッドはKernelモジュールに定義されている。
http://www.sakalab.org/prog-ruby/ruby-man-html-20080121/Kernel.html

なぜモジュールに切り離してあるかといったら、Objectのメソッドを再定義してしまった場合でも上の例のように、Kernelをincludeすれば復活できるからだ…と思う(←ここ自信ない)

なんでもオブジェクトなら、トップレベルはなんなの?

あれは、object_idがmainのObjectのインスタンスの中にいる。(…だよね?)

トップレベルでメソッドを定義すると、オブジェクトクラスのメソッドを上書きしてしまう。
これは、インスタンス中でdefによりメソッドを定義すると、そのインスタンスが属するクラスのメソッドとして追加されるという動きによるものだ。

class Bbb
  def define_bbb
    def bbb
    end
  end
end

Bbb.new.methods - Object.new.methods # => ["define_bbb"]
Bbb.new.define_bbb # => nil
Bbb.new.methods - Object.new.methods => ["define_bbb", "bbb"]

define_bbbを呼び出した後にbbbメソッドがBbbクラスのインスタンスメソッドに追加されているのが分かる。同じようにトップレベルでのメソッド定義はObjectにインスタンスメソッドを追加しているわけだ。

とりあえず読んでおこう

その他色々調べて記事にまとめようと思ったんですが、それより↓を読めって感じでした。
http://dev.ariel-networks.com/articles/workshop/ruby/

この記事はRubyをはじめたばっかりの頃に参考にさせて貰っていたんですが、ある程度書けるようになった今読んでも色々と復習できました。オススメです。