例
春, 夏, 秋, 冬, 春, 夏, ... のように循環する概念を Ruby で表したい。具体的には
Season.new('春').next #=> #<Season @name="夏">
Season.new('夏').next #=> #<Season @name="秋">
Season.new('秋').next #=> #<Season @name="冬">
Season.new('冬').next #=> #<Season @name="春">
Season.new('春').prev #=> #<Season @name="冬">
Season.new('夏').prev #=> #<Season @name="春">
Season.new('秋').prev #=> #<Season @name="夏">
Season.new('冬').prev #=> #<Season @name="秋">
となるような Season クラスを実装したい。
方法
剰余を使う。
class Season
attr_reader :name
NAMES = %w[春 夏 秋 冬].freeze
def initialize(name)
raise(ArgumentError) unless NAMES.include?(name)
@name = name
end
def next
self.class.new(NAMES[(index + 1) % NAMES.length])
end
def prev
self.class.new(NAMES[(index - 1) % NAMES.length])
end
private
def index
NAMES.index(name)
end
end
方法 (ボツ)
循環するイテレータを使う。難しく考えすぎていたのでボツ。
class Season
attr_reader :name
NAMES = %w[春 夏 秋 冬].freeze
def initialize(name)
raise(ArgumentError) unless NAMES.include?(name)
@name = name
end
def next
seasons = NAMES.cycle
until seasons.next == name do; end
self.class.new(seasons.peek)
end
def prev
seasons = NAMES.cycle
tmp = nil
loop do
tmp = seasons.next
break if seasons.peek == name
end
self.class.new(tmp)
end
end