MOE3: Unit#to_s メソッド
Unit の文字列化
Unit#to_s
への要求仕様は至極単純。
仕様 1
例えば「Lon にいる海軍」の
#to_s
を呼んだら"F Lon"
を返す。陸軍なら
"A Lon"
を返す。
最初の文字が "A"
か "F"
かの違いだけなので、メソッド本体は Unit#to_s
として実装してしまい、差分を Army
と Fleet
で吸収する形が自然な発想だろう。
それからもう一点、この先 Order#to_s
に関係してくるはずの仕様として、引数に Power
を一つ渡せるようにする。
仕様 2
引数として
Power
が渡された場合、その軍の所属国、すなわちUnit#power
と引数のPower
が一致しなければ、Unit#to_s
は戻り値に所属国のgenitive
を付与する。
前述の「Lon にいる海軍」の所属国が英で、Fleet#to_s
に渡された Power
が仏であれば、Fleet#to_s
は "English F Lon"
を返すのが正しい。
実装
実際に呼ばれるのは Army#to_s
または Fleet#to_s
であって、Unit#to_s
が直接呼ばれることはない。しかし派生クラスにしか存在しない symbol
メソッドを Unit#to_s
から呼び出すのが気持ち悪かったのでこうなった。
class Unit < ActiveRecord::Base belongs_to :phase belongs_to :power belongs_to :province def symbol # 派生クラスでオーバーライド end def to_s(owner = power) result = "%s %s"%[symbol, province.shortname] result = "%s %s"%[power.genitive, result] if owner != power result end end
徹底するなら Unit#symbol
では例外投げるべきだろうけど、単なる気休めなのでそこまでは必要なかろう。
class Army < Unit def symbol "A" end end
class Fleet < Unit def symbol "F" end end
ちなみに Province#shortname
はメソッド、Province#code
と Power#genitive
は属性である。
class Province < ActiveRecord::Base belongs_to :homepower, class_name:"Power" def shortname code.capitalize end end
class Power < ActiveRecord::Base end