規定数のリトライ成功失敗における反復「式」の効用
Rubyでは反復は文でなく式である.そのため,途中で中断した場合,反復式として戻り値を持てる.すると,規定数のリトライ処理を,成功した場合と失敗した場合で,論理的に整合するよううまく記述できる.
ネットワーク越しのデータ取得は,必ずしも成功せずタイムアウトする場合があるからね...
json = nil if [1, 2, 3].each {|t| if t > 1 LOG.info msg + "retry" sleep t end json = JSON.parse(`wget -q -t 2 #{uri} -O - | ./html2json.rb`) break if json["itemID"] > 0 # 在庫あり }.nil? LOG.debug msg + json["itemID"].to_s else # 在庫なし LOG.info msg + "no stock" row[0] = 'd' if opts.isRakuten puts CSV.generate_line(row, {force_quotes: true}) end
もし,反復式であることを知らないと,例外構文使っちゃうかも.
あるいは,反復が文しかない言語であれば,例外構文を使わざるを得ない.
この場合,在庫なしが正常ケースで,在庫ありが例外ケースとなる.
これは論理的に正しいプログラムといえるだろうか?
こういう場合,いちいち例外にするのは,大仰すぎないだろうかと.
なんとなれば,外部へ通信する部分にはすべて,例外構文にするべきだろうか?
論理的には,在庫有りも在庫なしも,正常ケースとみなすのが仕様として妥当な気がする.
begin json = nil [1, 2, 3].each {|t| if t > 1 LOG.info msg + "retry" sleep t end json = JSON.parse(`wget -q -t 2 #{uri} -O - | ./html2json.rb`) raise unless json["itemID"] > 0 # 在庫あり } LOG.debug msg + json["itemID"].to_s rescue # 在庫なし LOG.info msg + "no stock" ...略 end
例外構文ではなく,フラグを使ってもよい.
json = nil found = false [1, 2, 3].each {|t| if t > 1 LOG.info msg + "retry" sleep t end json = JSON.parse(`wget -q -t 2 #{uri} -O - | ./html2json.rb`) if json["itemID"] > 0 # 在庫あり found = true break end } if found LOG.debug msg + json["itemID"].to_s else # 在庫なし ... 略 end
さらにフラグが気持ち悪い人は,フラグの代わりに番兵を使う人もいるかも.