Stacktrace:
[1] top-level scope at /Users/foo/Desktop/Julia/test99.jl:5
[2] include(::String) at ./client.jl:457
[3] top-level scope at In[2]:1
[4] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091
この後例えば
s = 0
という行を実行させた後,再度
include("test99.jl")
を実行すると
0
┌ Warning: Assignment to `s` in soft scope is ambiguous because a global variable by the same name exists: `s` will be treated as a new local. Disambiguate by using `local s` to suppress this warning or `global s` to assign to the existing global variable.
└ @ nothing /Users/foo/Desktop/Julia/test99.jl:2
となる。
さて,普通のプログラミング言語だとどうなっていたっけ?と思い,まずは R でやってみる。
Julia でのプログラムを以下のように書き換えて test99.R に保存する。
for (i in 1:10) {
s = i == 1
s = s + i
}
print(s)
コマンドラインからこれを Rscript で実行すると
$ Rscript test99.R
[1] 10
なんのエラーもなく,期待される答え 10 を表示する。
R か RCommander で
source("test99.R")
としても,同じく 10 を表示する。エラーはない。
次に Python でやってみる。以下のプログラムを test99.py として保存する。
for i in range(1, 11):
s = i == 1
s = s + i
print(s)
コマンドラインからは
$ python3 test99.py
10
となるし,REPL でもエラーなく,同じ答え 10 が表示される。
我々としては,R や Python の振る舞いの方が普通に思われるが,確かに for ループの中で最初に s にアクセスするときは,「s なんかないよ」というのが理にかなっているのかも知れないなあ。
さて,悩んでいてもどうにもならないので,対策を考える。
for の内と外で s といっても違いがあるということで,
s = 999
for i = 1:10
s = i == 1
s = s + i
end
println(s)
としただけでは,まだ期待するような結果にはならない。
999
┌ Warning: Assignment to `s` in soft scope is ambiguous because a global variable by the same name exists: `s` will be treated as a new local. Disambiguate by using `local s` to suppress this warning or `global s` to assign to the existing global variable.
└ @ nothing /Users/aoki/Desktop/Julia/test99.jl:3
ところで,関数もまた変数スコープを持つので,このプログラムを関数定義でくるんでやる。
function func()
s = 999
for i = 1:10
s = i == 1
s = s + i
end
println(s)
end
これではじめて,for の内と外の s が同じものになる。その後で,関数を読んでやれば,期待する答え 10 が表示される。
s = 999 が初期化は不要だが定義が必要としたものだ。
func()
10