最大値で値を制限できる数値クラスの作成
久々の日記です。最大値を制限できる数値クラスが作りたいなと思ってたらものっそいキモイのが出来上がったので公開。
値を直接変更できないのでvalue=というメソッドを使用することにしましたが、それ以外は普通の数値として扱えるはず。
require "delegate" class SizedNumeric < DelegateClass(Numeric) attr_accessor :max def initialize max @max = max super 0 end def value= value raise RangeError unless (0..max).include? value __setobj__ value end def coerce other [other, __getobj__] end end
追記
「数値クラスはimmutable」という突っ込みに対して修正してみましたがこれはコレでキモイというか不便でした。
class SizedNumeric < DelegateClass(Numeric) attr_accessor :max def initialize max, value = 0 raise RangeError unless (0..max).include? value @max = max super value end def coerce other [other, __getobj__] end def method_missing *args SizedNumeric.new @max, super end end
snum = SizedNumeric.new 5, 0 #=> 0 snum += 5 #=> 5 snum+1 # RangeError
足し算しただけでRangeErrorてどうなの。
「上限のある数値」はNumericじゃないのでmutable、と考えて名称を変更したほうが良さそうな予感。