コードを評価する際、OMakeの変数には3つの異なる種類の名前空間があります。変数は プライベート なものにしたり、 現在の オブジェクトのフィールドを参照したり、 グローバル な名前空間の一部として用いることができます。名前空間を指定するには、変数名の前に修飾子を直接明示する必要があります。この3つの名前空間は分割されており、変数は一つ、あるいはさらに多くの名前空間に束縛することができます。
# プライベートな名前空間
private.X = 1
# 現在のオブジェクト
this.X = 2
# パブリック、グローバルに定義された名前空間
global.X = 3
private. 修飾子は変数が現在のファイルやスコープ上のプライベートなものであると定義したい場合に用います。値は外のスコープから参照することができません。プライベートな変数は静的にスコープされています。
Obj. =
private.X = 1
print() =
println(The value of X is: $X)
# 出力:
# The private value of X is: 1
Obj.print()
# XはObj内のプライベート変数なので、エラーとなります
y = $(Obj.X)
加えて、プライベート変数はグローバルな変数の値に影響を及ぼしません。
# パブリックなxの値は1
x = 1
# このオブジェクトはxのプライベートな値を使用しています
Obj. =
private.x = 2
print() =
x = 3
println(The private value of x is: $x)
println(The public value of x is: $(public.x))
f()
# 出力:
# The private value of x is: 3
# The public value of x is: 1
Obj.print()
プライベート変数は2つの性質を持っています。
プライベート変数は定義されたファイルしか参照できません。
プライベート変数はたとえ明示的に export 文を使用したとしてもエクスポートできません。
private. =
FLAG = true
section
FLAG = false
export
# FLAGはまだtrueです
section
FLAG = false
export FLAG
# FLAGは現在falseです
this. 修飾子はオブジェクトのローカルなフィールドについて定義したい場合に用います。オブジェクト変数は動的にスコープされます。
X = 1
f() =
println(The public value of X is: $(X))
# 出力:
# The public value of X is: 2
section
X = 2
f()
# Xはオブジェクト中の保護されたフィールドを表しています。
Obj. =
this.X = 3
print() =
println(The value of this.X is: $(X))
f()
# 出力:
# The value of this.X is: 3
# The public value of X is: 1
Obj.print()
# この文は正しく、Yには3が束縛されます。
Y = $(Obj.X)
一般的に、保護されたオブジェクト変数を定義することは良いとされています。プロジェクトの他の部分で定義された変数と被ってしまったために起こる、意図しないバグを生み出さないためです。その結果、コードはよりモジュール化されます。
global. 修飾子はグローバルに動的なスコープを持つ変数を定義したい場合に用います。以下の例では、 global. 宣言は束縛文 X = 4 が動的にスコープされた変数であることを指定しています。グローバル変数はオブジェクトのフィールドとして定義することが できません 。
X = 1
f() =
println(The global value of X is: $(X))
# 出力:
# The global value of X is: 2
section
X = 2
f()
Obj. =
protected.X = 3
print() =
println(The protected value of X is: $(X))
global.X = 4
f()
# 出力:
# The protected value of X is: 3
# The global value of X is: 4
Obj.print()
OMake 0.9.8では、 protected は this 修飾子と同義語でした。
osh>protected.x = 1
- : "1" : Sequence
osh>value $(this.x)
- : "1" : Sequence
0.9.9ではこの仕様は変更され、 protected 修飾子は変数が現在のオブジェクトまたはファイルについてのローカル変数とし、外部からアクセスできないようにしたい場合に用います。
OMake 0.9.8では、 public は global 修飾子と同義語でした。
osh>public.x = 1
- : "1" : Sequence
osh>value $(global.x)
- : "1" : Sequence
0.9.9ではこの仕様は変更され、 public 修飾子は変数が現在のファイルまたはオブジェクトの外部からアクセスできるようにしたい場合に用います。
いくつかの修飾された変数が同時に定義された場合、修飾子のブロックが優先的に定義されます。文法はオブジェクトの定義と似ていますが、それはオブジェクト名それ自体が修飾子だからです。例えば、以下のプログラムはプライベート変数 X と Y を定義しています。
private. =
X = 1
Y = 2
修飾子はブロック内で新しく定義された変数の、デフォルトの名前空間を指定しています。その違いを除いて、ブロックの内容は完全に通常のコードとしてふるまいます。
private. =
X = 1
Y = 2
public.Z = $(add $X, $Y)
# "The value of Z is 3" と出力される
echo The value of Z is $Z
変数名が修飾されていない場合、その名前空間は最も近くで定義された名前空間か、この変数が定義されているスコープの名前空間が用いられます。私たちは以前すでにこの現象を例を通して見ています。その例では、変数の定義が修飾されていても、その後に来る変数は明示的に修飾されていなかったはずです。以下の例では、最初に宣言された $X は プライベート な変数 $(private.X) が関連付けられています。なぜならこれは最も近くで定義されているからです。パブリックな変数 X は未だに 0 であり、この変数を指定するためには明示的に修飾しなければなりません。
public.X = 0
private.X = 1
public.print() =
println(The value of private.X is: $X)
println(The value of public.X is: $(public.X))
時々、修飾子を定義する事なしに変数宣言することが有効である場合があります。例えば、私たちはプログラムの後ろで定義された変数 X を用いる関数を持っていたとしましょう。 declare 文はこのような場合に使うことができます。
declare public.X
public.print() =
println(The value of X is $X)
# "The value of X is 2" と出力される
X = 2
print()
最後に、明示的に修飾されていない変数についてはどうなるのでしょうか?このような場合、以下のルールが使われます。