Rubyで動的クラスを使ったクラス設計を考える

地元鉄道の時刻表や駅の情報を返すAPIを考えている。 (Alexaのスキルを作りたくて、そのためのデータを返すAPIがほしいのだった)

欲しいのは、駅の情報(info)・時刻表(timetable)・運賃(fare)。

Akaden というのは地元鉄道の愛称。正式名称は遠州鉄道、略して遠鉄。車体が赤いので市民は「赤電」と呼んでいる。

駅名をメソッドにする

::Akaden::Info.shin_hamamatsu
=> { name: '新浜松', address: '' , ...}
::Akaden::Timetable.kamijima
=> [ { detection: 'upto', week: 'weekday', time: '10:35' }, ... ]

gist.github.com

駅名をクラスにする

::Akaden::ShinHamammatsu.info
=> { name: '新浜松', address: '' , ...}
::Akaden::Kamijima.timetable
=> [ { detection: 'upto', week: 'weekday', time: '10:35' }, ... ]

返すデータはいずれも "駅" が主語なのだから、こちらのほうが良さそう。

駅名をクラスにする場合の実装はこのような感じ。const_setdefine_method を使って動的なクラスを作っている。

gist.github.com

const_set にブロックを渡すときは、()で括ってあげる必要があるらしい、ここで少しハマった。 define_method :station しているのは、クラス内で駅名をインスタンス変数的に使いたかったので。instance_variable_set でも良さそうだけど。。

$ ruby app.rb
"Kamijima info!"
"Kamijima upto weekend timetable"
"DaiichiDori donwnto weekday timetable"