ブロックと局所値

モジュールを使うことで,変数の名前を局所的なものとして扱うことができる.場合によっては,変数の参照名は大域的なものとしておき,変数の取る値だけを局所化したい.これを行うにはBlockを使う.

Block[{x,y,},body]局所値 を使い body を評価する
Block[{x=x0,y=y0,},body]に初期値を割り当てる

ブロックを使った局所値の設定

を使った式を入力しておく.
In[1]:=
Click for copyable input
Out[1]=
入力した式を評価させる. には局所的な値が使われる.
In[2]:=
Click for copyable input
Out[2]=
には何も大域的な値は割り当てられていない.
In[3]:=
Click for copyable input
Out[3]=

「モジュールと局所変数」で説明してあるように,Module[{x},body]において,変数 x は常に固有な名前を参照するように設定される.つまり,モジュールが使われるたびに固有とされ,また,大域変数 x からも固有とされるように x は名前が変更される.これに対して,Block[{x},body]では,x は大域的なスコープ x とされる.ただし,x の取る値は局所的なものとされる.したがって,ブロックが終了すると,x には昔の値が戻される.ブロック内ではどんな値でも割り当てることができる.

シンボル に値を割り当てる.
In[4]:=
Click for copyable input
Out[4]=
モジュール内の変数は固有の局所名を持つ.
ブロックでは,変数の大域名は維持されるが,変数の値は局所的なものでもよい.
ブロックにおいて, には局所値が割り当てられる.
In[7]:=
Click for copyable input
Out[7]=
ブロックの実行が終ると,もとの値が に戻される.
In[8]:=
Click for copyable input
Out[8]=

ブロックを使うと,実効的に「局在化された環境」を作り出すことができる.この環境では変数の値を一時的に変更することができる.あるブロックの実行中に評価される式は,そのブロックにある変数に対して現時点で定義されている現行値を使う.同じことは,ブロックで直接記述される本体の各式だけでなく,各式の評価により生成される式についても言える.

シンボル に対して遅延型の値を定義する.
In[9]:=
Click for copyable input
ブロックの外で を評価させると, に対する大域値が使われる.
In[10]:=
Click for copyable input
Out[10]=
に対して,ブロック内での使用のための一時的な値を指定することもできる.
In[11]:=
Click for copyable input
Out[11]=

DoSumTable等の反復処理を行う構成体ではBlockが使われる.これらの構成体では,実効的にBlockの機構が使われ反復変数がすべて局所的な値を持つものとして扱われている.

Sumを作用させると,自動的に反復変数 の値が局所的なものにされる.
In[12]:=
Click for copyable input
Out[12]=
反復構成体における局所値化はBlockより多少だが一般化されている.つまり,や純粋な変数も局所値化の対象になる.
In[13]:=
Click for copyable input
Out[13]=

直接引数としては与えられないが,関数の動作には影響を与える,という働きを持つ大域変数が使えると便利な場合がある.一例として,帰納的な反復回数の上限を決定するための大域変数$RecursionLimitがある.この変数はすべての関数の評価に影響を及ぼすが,関数の直接の引数としては働かない.

大域変数に一度値が割り当てられると,特別に変更されるまでは,その値は変わらない.場合によっては,特定の計算だけとか計算の一部分だけで値を有効としたいときもある.それを行うにも,ブロックを使うことができる.

「大域変数」 に依存する関数を定義する.
In[14]:=
Click for copyable input
この場合, の大域値が使われる.
In[15]:=
Click for copyable input
Out[15]=
ブロックの中では に対して局所値を設けることもできる.
In[16]:=
Click for copyable input
Out[16]=

大域変数を使い,関数のパラメータへの値の割当ての他に,関数からの結果の蓄積を行うこともできる.つまり,大域変数をあるブロックに対して局所化しておくことで,ブロックから呼び出される関数からだけの結果を蓄積させることができる.

この関数は,大域変数 を増分し,その現行値を返す.
In[17]:=
Click for copyable input
ブロックを使わないでを評価させると, の大域値を変更する.
In[18]:=
Click for copyable input
Out[18]=
ブロックを使うと, の局所値だけが変わる.
In[19]:=
Click for copyable input
Out[19]=
の大域値は同じままである.
In[20]:=
Click for copyable input
Out[20]=

Block[{x},body]等のブロックが評価されるときは,x に割り当てられている現行値が除去される.このため,理論上は,ブロックの中では x を実質的な「シンボル的な変数」として扱うことができる.しかし,x を戻り値としてブロックから返すと,それはブロック評価前の外部の値により置換されてしまう.

ブロックを評価させると, の現行値は除去される.
を含む式を戻り値とすると, の大域値が使われ式の評価が行われる.
In[22]:=
Click for copyable input
Out[22]=