メッセージ

2005年10月27日の記事

2005/10/27(木)ApolloのPanelでinitializeがオーバーライドできなかった理由

class MyPanel < Phi::Panel
  def initialize
    # ≪処理≫
  end
end

MyPanel.new
というコードを書いたのだが、≪処理≫が実行されない(本来なら処理の前にsuperを書くが、わかりやすくするために削った)。

で、この場合newで呼ばれるのはPhi::Panelのコンストラクタのようで、オーバーライドしたはずのinitializeを通らない。

これはどうやらPhi::Panel上でnewが再定義されている所為らしい。下はGtkの記事だがApolloでも似たようなことをやっているのではないかと推測。再定義したnewはinitializeを呼ばないという解釈で良いと思う。
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/5885

いやちゃんとソース読んで無いので確証はないのだが(読み方すら分からない)。

ということで、
class MyPanel < Phi::Panel
  def MyPanel.new
    # ≪処理≫
  end
end

MyPanel.new
としてやれば願いが叶う。newはクラスオブジェクトのメソッド(こういう言い方でいいんだっけ?)なので、def newではなく、def MyPanel.newと書く。superは省略したが、ちゃんとやるならもちろん返り値の設定までしてやらなきゃいけない。
ret = super
≪処理≫
ret
≪処理≫の中でプロパティいじるような目的がほとんどだと思うので、こんな書き方が定番になるんだろう。initializeと大きく異なるのはこの中でselfを呼ぶとクラスオブジェクトが返ってくることだ。
class B
end

class A < B
  def A.new
    ret = super
    p self
    ret
  end
end

p A.new

--出力--
A
#<A:0x2bb42c8>
つまりこうか。

プロパティを設定するときはsuperの返り値(ここではret)に対して設定してやらなきゃならない。

#追記
newからinitializeを呼んでやった方が汎用性が高い。
OK キャンセル 確認 その他