この初版はLua 5.0用に書かれました。後続のバージョンでも概ね関連性はありますが、いくつかの違いがあります。
第4版はLua 5.3を対象にしており、Amazonやその他の書店で購入できます。
書籍を購入することで、Luaプロジェクトを支援することもできます。


4.2 - ローカル変数とブロック

Luaはグローバル変数の他にも、ローカル変数をサポートしています。ローカル変数はlocalステートメントで作成します。

    j = 10         -- global variable
    local i = 1    -- local variable
グローバル変数とは異なり、ローカル変数のスコープは、それらが宣言されたブロックに限定されます。ブロックとは、制御構造の本体、関数の本体、チャンク(変数が宣言されているコードを含むファイルまたは文字列)です。
    x = 10
    local i = 1        -- local to the chunk
    
    while i<=x do
      local x = i*2    -- local to the while body
      print(x)         --> 2, 4, 6, 8, ...
      i = i + 1
    end
    
    if i > 20 then
      local x          -- local to the "then" body
      x = 20
      print(x + 2)
    else
      print(x)         --> 10  (the global one)
    end
    
    print(x)           --> 10  (the global one)
対話モードでこのサンプルを入力すると、期待通りの動作にならないことに注意してください。2行目のlocal i = 1は、単体で完了チャンクです。この行を入力するとすぐにLuaはそれを実行し、次の行で新しいチャンクを開始します。その時点で、local宣言はすでにスコープ外です。対話モードでこのようなサンプルを実行するには、すべてのコードをdoブロックで囲む必要があります。

可能な場合はいつでもローカル変数を使用するのが、適切なプログラミングスタイルです。ローカル変数を使用すると、不要な名前でグローバル環境が乱雑になるのを防ぐことができます。さらに、ローカル変数へのアクセスは、グローバル変数へのアクセスよりも高速です。

Luaはローカル変数の宣言をステートメントとして処理します。したがって、ステートメントを記述できる場所であれば、ローカル宣言を記述できます。スコープは宣言の後から始まり、ブロックの終わりまで続きます。宣言には初期割り当てを含めることができます。これは従来の割り当てと同じように機能します。余分な値は破棄されます。余分な変数はnilになります。具体的には、宣言に初期割り当てがない場合、すべての変数がnilで初期化されます。

    local a, b = 1, 10
    if a<b then
      print(a)   --> 1
      local a    -- `= nil' is implicit
      print(a)   --> nil
    end          -- ends the block started at `then'
    print(a,b)   -->  1   10

Luaでは、次のような慣用句が一般的です。

    local foo = foo
このコードはローカル変数のfooを作成し、グローバル変数fooの値で初期化します。この慣用句は、後で他の関数がグローバルfooの値を変更しても、チャンクが必要な場合にfooの元の値を保持する必要があるときに役立ちます。また、fooへのアクセスを高速化します。

多くの言語では、ブロック(またはプロシージャ)の最初にすべてのローカル変数を宣言する必要があるため、ブロックの途中で宣言を使用するのは好まれない場合があります。これはその逆です。必要な場合にのみ変数を宣言することで、初期値なしで変数を宣言する必要がほとんどなくなり(そのため、初期化を忘れることもほとんどありません)。さらに、変数のスコープが短くなり、可読性が向上します。

ブロックを明示的に区切り、キーワードdo-endで囲むことができます。このdoブロックは、1つ以上のローカル変数のスコープを細かく制御する場合に役立ちます

    do
      local a2 = 2*a
      local d = sqrt(b^2 - 4*a*c)
      x1 = (-b + d)/a2
      x2 = (-b - d)/a2
    end          -- scope of `a2' and `d' ends here
    print(x1, x2)