using使ったversionのくじ引きプログラム

勉強会中に、これについて、簡単に解説したら、closeしたい場合はどうするの?的な話がでた。

で、普通にやるとしたら、fromURLの戻り値のBufferedSourceというものを、

一度変数に代入

使い終わったら、それのcloseというメソッド呼ぶ

っていう手順になるわけですが・・・↓

val buffer = scala.io.Source.fromURL("""http://api.atnd.org/events/users/?event_id=9889""")

val str = buffer.mkString  //Stringに変換

buffer.close  //もういらないので閉じる

//以下は同じ処理やればいいよ

で、ちょっと普通すぎてつまらないので、この前につくったusing使ってやってみる

//これは前に載せたusing文そのまま
def using[A <: {def close()},B](resource:A)(func:A => B):Unit = {
    try{
      func(resource)
    }catch{
      case e:Exception => e.printStackTrace
    }finally{
      if(resource != null) resource.close()
    }
  }
  
  
val 座れる人数 = 10

using( scala.io.Source.fromURL("""http://api.atnd.org/events/users/?event_id=9889""") ){ buffer =>

  val str = buffer.mkString

  val usersNodeSeq = scala.xml.XML.loadString(str) \\ "nickname"

  val users = usersNodeSeq.collect { case user if user.text != "kaigaiengineer" => user.text }

  util.Random.shuffle(users) take 座れる人数 foreach println

}

微妙・・・(´Д`)

using自体が値を返すようにしてみる

//値返すように変更したversion
def using[A <: {def close()},B](resource:A)(func:A => B):Option[B] = {
  try{
    Some( func(resource) ) //成功したら、Someに包んで返す
  }catch{
    case e:Exception => e.printStackTrace
    None  //失敗したら、ログ吐いて、None返す
  }finally{
    if(resource != null) resource.close()
  }
}
  
  
val 座れる人数 = 10

val result = using( scala.io.Source.fromURL("""http://api.atnd.org/events/users/?event_id=9889""") ){ _.mkString }

result match {

  case Some(str) => {

    val usersNodeSeq = scala.xml.XML.loadString(str) \\ "nickname"

    val users = usersNodeSeq.collect { case user if user.text != "kaigaiengineer" => user.text }

    util.Random.shuffle(users) take 座れる人数 foreach println

  }
  
  case _ => 
  
}

大して読みやすくない気もする・・・てか、URL渡したら、それの内容のOption[String]を返すユーティリティ関数作っちゃったほうがいいかもねぇ