変数のスコープ

HelloWorldの次でいきなり、つまずいた。。。
最初、groovyshでやってたらdefのスコープがさっぱりわからんかった。
複数行で書くとエラーになってしまい、1行で書くと正常に動作する。
defがおかしいんじゃなくて、groovyshのブロックが1行というのが、
直感的にわからなかったのだ。

groovyshの場合の例

defなしなら複数行でもOK
groovy:000> hatenaID = "orangeclover"
===> orangeclover
groovy:000> println hatenaID
orangeclover
===> null
defありだと複数行だとNG
groovy:000> def twitterUserNmae = "orange_clover"
===> orange_clover
groovy:000> println twitterUserNmae
ERROR groovy.lang.MissingPropertyException: No such property: twitterUserNmae for class: groovysh_evaluate
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...
defありの場合は、一行ならOK
groovy:000> def twitterUserName = "orange_clover"; println twitterUserName
orange_clover
===> null

groovyの場合の例

defはブロック内でOK
hatenaID = "orangeclover"
def blogURL = "http://d.hatena.ne.jp/orangeclover"

if(true){
	twitterUserName = "orange_clover"
	def name = "秘密"
	println "TwitterのIDは@${twitterUserName}です。(ブロック内での表示)"
	println "私の本名は${name}です。(ブロック内での表示)"
}

println "はてなIDはid:${hatenaID}です。"
println "ブログのURLは${blogURL}です。"
println "TwitterのIDは@${twitterUserName}です。"

println "私の本名は${name}です。"
実行結果 groovy myname.groovy
TwitterのIDは@orange_cloverです。(ブロック内での表示)
私の本名は秘密です。(ブロック内での表示)
はてなIDはid:orangecloverです。
ブログのURLはhttp://d.hatena.ne.jp/orangecloverです。
TwitterのIDは@orange_cloverです。
Caught: groovy.lang.MissingPropertyException: No such property: name for class: myname
        at myname.run(myname.groovy:15)

メモ

  • defで宣言した変数はブロック内で有効。
  • defなしで使用した変数は、ブロック外でも有効 (クラスとの関係はまだ分からん)
  • 対話シェルgroovyshだと一行がブロックになる。