superではまった
サブクラスから継承元クラスのAPIを呼び出すときに使うsuperですが、RubyのそれをJavaのごとく使ってしまい痛い目に。
Javaが↓こんなだからって、
void hoge() { // 継承もとクラスのhoge()を実行。 super.hoge(); }
Rubyでおなじノリで書いちゃダメです。
def hoge() # 継承もとクラスのhoge()を実行、はされるんだけどさ。 super.hoge end
解説
悪い例
以下はこの罠にはまった哀れなコードの例です。
# 親クラス class Node def initialize( name, next_node ) @next_node = next_node @name = name end def next() @next_node end attr_reader :name end # サブクラス class SubNode < Node def initialize( name, next_node ) super(name, next_node) end def next() # 親クラスのnextを呼び出しているつもり。 super.next end end # 1, 2, 3, 4 と出力されるはずが、3がすっ飛ばされる! node = Node.new("1", SubNode.new( "2", Node.new( "3", Node.new("4", nil ) ) ) ) while node != nil puts node.name node = node.next end
実行結果です。3がすっ飛ばされています。
1 2 4
nextが戻り値でも実装されているため、エラーにならずだいぶはまりました.orz
あと、Java使い向け注意点として、rubyのsuperで括弧と引数が省略された場合、現在のメソッドの引数がそのまま引き渡されるという動作になります。これも知らないとはまりそうなのでご注意。