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