たとえば、外部のURLにリクエストするような関数では、
def getJSON = {
println("requesting...")
val result = scala.io.Source.fromURL("http://api.hostip.info/get_json.php?ip=8.8.8.8").mkString
println("request done")
result
}
println(getJSON)
println(getJSON)
println(getJSON)
その関数を呼ぶたびにHTTPリクエストが発生していまう。
requesting...
request done
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
requesting...
request done
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
requesting...
request done
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
これを def
から lazy val
にすると
lazy val getJSON = {
println("requesting...")
val result = scala.io.Source.fromURL("http://api.hostip.info/get_json.php?ip=8.8.8.8").mkString
println("request done")
result
}
println(getJSON)
println(getJSON)
println(getJSON)
HTTPリクエストは1回だけになる
requesting...
request done
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
{"country_name":"UNITED STATES","country_code":"US","city":"Mountain View, CA","ip":"8.8.8.8"}
ちなみに、先のScalaコードから println を取り除けば1行になる。
lazy val getJSON = scala.io.Source.fromURL("http://api.hostip.info/get_json.php?ip=8.8.8.8").mkString
PHPのプロジェクトをScalaで書きなおしているが、PHPで書こうとすると static で変数を宣言して、値が NULL かどうかを判定するようなコードになるので、Scalaのlazy valはすばらしいと思った。
<?php
function getJSON() {
static $result;
if ($result === null) {
$result = file_get_contents("http://api.hostip.info/get_json.php?ip=8.8.8.8");
}
return $result;
}
var_dump(getJSON());
var_dump(getJSON());
var_dump(getJSON());