読者です 読者をやめる 読者になる 読者になる

せかいや

いまいるここを、おもしろく http://sekai-in-the-box.appspot.com/

【Ruby】【るびま】継承したモジュールのsuper。初期化処理の遅延方法

Rubyist Magazine - Ruby コードの感想戦 【第 1 回】 WikiR
を読んでいました。

 

複数include したときのsuper は何を指す?

ルビまの記事の中に、こんな一文が↓

継承したときに initialize で super() するのは親クラスも初期化しないといけないからだろうなぁとは思います。

http://magazine.rubyist.net/?0040-CodePostMortem

記載されていたコード

class Counter
   include MonitorMixin

   attr_reader :count
   def initialize
     super()
     @count = 0
   end

 
ふむ。。
そういえば複数モジュールをincludeできるけど、
superでは全てのモジュールの初期化が呼び出されるのか?

 

module A
	def initialize
		p "aa"
	end
end
module B
	def initialize
		p "bb"
	end
end
class Hoge 
	include(A, B)
	def initialize
		p "hoge"
		super
	end
end
Hoge.new

 
■実行結果

"hoge"
"aa"

なるほど。最初にincludeしたものがsuperになるんだ。

そういえばこのあたりの継承関係は
パーフェクトRubyに書いてあった。そうだそうだ。

変換処理を遅延させる

遅延の工夫前

class Page
 def initialize(name)
   @name = name
   set_src("# #{name}\n\nan empty page. edit me.")
 end
 attr_reader :name, :src, :html, :warnings

 def set_src(text)
   @src = text
   km = Kramdown::Document.new(text)
   @html = km.to_html
   @warnings = km.warnings
 end
end

 
 

遅延の工夫後

def src=(text)
   @dirty = true
   @src = text
 end
 def html
   parse if @dirty
   @html
 end
 def warnings
   parse if @dirty
   @warnings
 end
 private
 def parse
   km = Kramdown::Document.new(@src)
   @html = km.to_html
   @warnings = km.warnings
   @dirty = false
 end

なるほど!
フラグを立てておいて、必要になったら要素を作成するのかー。

 
コード量が少ないことと「小さなクラス」は別に表現したほうが混乱が少ないのではー?
Rubyでは ClassA < ClassB は意味のあるコードだから。
と思いつつ。。

面白かったー