勉強会中に、これについて、簡単に解説したら、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]を返すユーティリティ関数作っちゃったほうがいいかもねぇ