2016年3月19日土曜日

Luaの環境

書籍「Programming in Lua」の「14章 環境」を読んでいて、サンプルコード内のsetfenv/getfenvが利用できず躓いていたが、Lua 5.2からAPIが廃止されていた・・・。

Lua 5.2~

Lua 5.2 リファレンスマニュアル」から抜粋。

環境

  • 任意のグローバル変数 var への参照は構文的に _ENV.var に変換される。
  • _ENV は完全に正規の名前であり、同じ名前の変数や引数を定義しても構わない。
  • グローバル変数への参照は、Lua の通常の可視性ルール(レキシカルスコープ)に従い、 プログラムのその地点から見える _ENV が使われる。
  • _ENV の値として使われるテーブルは「環境」と呼ばれる。

グローバル環境

  • Luaには「グローバル環境」と呼ばれる特別な環境が存在し、変数 _G がこの値で初期化される。
  • チャンクをコンパイルすると、 そのチャンクの _ENV の値はグローバル環境で初期化される。そのため、デフォルトでは、 Lua コードのグローバル変数はグローバル環境のエントリを参照する。
  • すべての標準ライブラリはグローバル環境にロードされ、 それらの関数はグローバル環境で実行される。
print(_ENV == _G) -- true

a = 1

local function f(t)
    print(_ENV == _G) -- true
    local print = print
    -- ローカルの_ENVを宣言。参照先は引数で指定されたテーブルとする。
    local _ENV = t
    print(_ENV == _G) -- false
    -- 関数内で宣言された変数はローカルの_ENVに格納される。
    a = 2
    b = 3
end

local t = {}
f(t)
print(a,b)     -- 1   nil
print(t.a,t.b) -- 2   3
仮に「local _ENV = t」をコメントアウトすると、
print(a,b)     -- 2   3
print(t.a,t.b) -- nil nil
となる。

Lua 5.1以前

_ENVが用意されたのはLua 5.2から。
Lua 5.1までは、
getfenv(1)
setfenv(1, table)
を介して該当レベルの環境に対する参照と更新が可能だった。
Lua 5.2からはgetfenv/setfenvのAPIは廃止されている。

[参考]

0 件のコメント:

コメントを投稿