3

Rails モデルから API を呼び出していますが、API が 200 以外のコードで返された場合にエラーを発生させたいと考えています。それ以外の場合は、データをキャッシュ/遅延ロードします。これは私の方法です:

def data
    @data ||= SNL.get_list(name)
    raise StandardError, @data.inspect unless @data.success?
    @data
end

これは機能しますが、これを1行で達成できるかどうか疑問に思っていました。and演算子を an と組み合わせて使用​​しようとしましたunlessが、機能しませんでした。

更新: tokland の回答を受け入れました。なぜなら、私は 1 行を要求し、彼/彼女は 2 つの非常に優れた解決策を提供したからです。最後に実際に使ってみます

def data
  @data ||= SNL.get_list(name)
  @data.success? ? @data : (raise StandardError, @data.inspect)
end

読みやすさのために。@data例外が発生することはめったにないので、単に return のための 3 行目が嫌いでした。odiszapc の回答は、簡潔さと読みやすさの最善の妥協点だと思います。みんな、ありがとう。

4

4 に答える 4

3

ワンライナーを書くのに苦労することはありませんが、tapどうしても必要な場合は使用できます。

def data
  (@data ||= SNL.get_list(name)).tap { |d| d.success? or raise StandardError.new(d.inspect) }
end

また、短絡ロジックの場合:

def data
  (@data ||= SNL.get_list(name)).success? && @data or
    raise StandardError.new(@data.inspect) }
end
于 2012-06-20T07:16:46.647 に答える
2

terneray演算子を使用できます。ただし、コードをできるだけ読みやすくすることが非常に重要だと思います。そして、一般的に私の経験では、水平方向に少し広がりすぎるコードは、一般的に従うのが少し難しいです。

確認する必要があることが1つあります。nilを返し、演算子を一緒SNL.get_list(name)に使用しようとすると、機能しません。and

この問題は私に何度も起こりました。サンプル例:

nil and puts 'hello'

あなたのirbでこれを試してください。動作しません。この問題は私に何度も発生しました。

于 2012-06-20T06:58:53.620 に答える
1

試す

def data
    (@data ||= SNL.get_list(name)).success? ? @data :  raise(StandardError, @data.inspect)
end

繰り返しますが、@ Sohaibのポイントは有効ですが、これはまったく読みにくいです! ゴミのようではなく、たくさんの括弧

于 2012-06-20T07:15:05.110 に答える
1

多分

def data
  @data ||= SNL.get_list(name)
  @data.success? ? @data : (raise StandardError, @data.inspect)
end

または、よくわかりません。次のようなものです。

def data
  (@data ||= SNL.get_list(name)).success? ? @data : (raise StandardError, @data.inspect)
end
于 2012-06-20T06:52:33.493 に答える