Skip to content

Instantly share code, notes, and snippets.

@rirakkumya
Created April 19, 2012 15:14
Show Gist options
  • Save rirakkumya/2421593 to your computer and use it in GitHub Desktop.
Save rirakkumya/2421593 to your computer and use it in GitHub Desktop.
def foo[A,B](in:Option[A])(valid:PartialFunction[Option[A],Either[B,A]])(invalid:PartialFunction[Option[A],Either[B,A]])(other: =>Either[B,A]) = {
if(!valid.isDefinedAt(in) && !invalid.isDefinedAt(in)) {
other
}else{
(valid orElse invalid)(in)
}
}
def getFirstData(id:String) = {
foo(Cache.get(id)){
case Some(r) if r.startsWith("x") => Right("foo")
case Some(r) => Right(r)
}{
case Some(r) if r == "badcode" => Left(BadRequest)
}{
Left(NotFound)
}
}
@lyricallogical
Copy link

折角なのでもう少しだけ書かせてください。

基本的に、問題の発生箇所とその例外処理が離れれば離れるほど、コードは読みにくくなると思っています。
具体的には下のような話です。

def bad() =
  if (success) {
    ... longlonglonglong process
  } else {
    valueForNotSuccess
  }

def good() = {
  if (!success) {
    return valueForNotSuccess
  }
  ... longlonglonglong process
}

return は使うべきでないとする主張もあるとは思いますが、そこはまあ置いておいて…
これはサンプルコードなので、まあどちらも大差なくみえますが、longlonglonglong processs が非常に縦に長かったとしたらどうでしょうか。もちろん、そもそもそんな長い処理は関数として抽出しろ、というのは全く正しい主張だと思うのですが…そこは本質ではないと思います。

というような視点で見ても、矢張り rirakkumya さんのコードは読みにくいということがいえるのではないかと思います。None だった場合には NotFound を返す、という例外処理が、Cache.get から離れてしまっているためです。

(余談ですが、ボクは try catch による例外処理は、「距離」を長くしがちなので「構文として」好きではないです。そもそも「例外」自体好きではないですが…)

長々とすいませんでした。以上です。
コードの readability に関しては、様々な視点があり、多くの場合、例外処理の最適解はケースバイケースなのだと思います。ボクが上述した主張が常に正しいとも思っていません。というわけで、こういう視点もあるよ、という意見は大歓迎です。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment