スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--.--.-- | スポンサー広告

[Lua] 暗黙のグローバル変数定義を抑制する方法

あれからいろいろML内を探し回って、

このあたりとか
このあたりとかを参考にしましたが・・・

とりあえずこんな感じになりました。
プログラムの最初で

use_explicit_globals() 

とすれば有効になり。

global("変数名",値) 

または
global "変数名" 

でグローバル変数を定義できます。

定義していないグローバル変数に値を代入したり使ったりすると
ランタイムエラーになります。

これで前回書いた「弊害」はほとんどなくなるかなと思います。
あくまでテストは甘いのであまり信用しないように・・・。

※このコードは自由に使ってもらってかまいません。

追記:このあと少し修正しました。>こちら。



---- explicit_globals.lua ---

-- グローバル変数存在チェックテーブル
-- table for global var definition checking
local gdef = {}
local gdef_enabled = nil

-- グローバル変数全体のメタテーブルをセット
-- set metatable for gloval environment
if getmetatable(_G) == nil then
setmetatable(_G, {})
end

-- グローバル変数定義関数
-- the function to define global vars
function global(n, v)
if not gdef_enabled then
error("calling function global() when explicit-globals not enabled")
end
if gdef[n] == true then
error("re-definition of global \"" .. tostring(n) .. "\"")
end
rawset(_G, n, v)
gdef[n] = true
end


-- 暗黙のグローバル変数定義を禁止(global定義必須にする)
-- prohibit implied definition of global vars
function use_explicit_globals()
getmetatable(_G).__newindex = function (t,n,v)
if type(v) ~= "function" then
if gdef[n] == nil then
error("assignment to undefined global \""
.. tostring(n) .. "\"; use function global(\"var\", val)")
end
end
rawset(_G, n, v)
end
getmetatable(_G).__index = function (t,n)
if gdef[n] == nil then
error("attempt to use undefined global \""
.. tostring(n) .. "\"; use function global(\"var\", val)")
end
return rawget(_G, n)
end
gdef_enabled = true
end

-- 暗黙のグローバル変数定義を開放(通常動作)
-- back to normal
function use_implicit_globals()
getmetatable(_G).__newindex = nil
getmetatable(_G).__index = nil
gdef_enabled = nil
end



以下はテスト用のスクリプトです。

------------ test script テスト用スクリプト
use_explicit_globals()
--use_implicit_globals() -- if you want to do the old way : チェックなしに戻す場合

global "SomeVariable"

SomeVariable = 1

function ClearSomeVariable()
print(tostring(SomeVariabl)) -- TYPO should result in a error
SomeVariabl = 0 -- ミスタイプなのでここでエラーになるべき
end

ClearSomeVariable()



※Lua5.0.2向けですが、多分Lua5.1でも動きます。Lua4以下では動きません。

追記:
実装している時に気付いたのですが、
__newindex や __index のメタメソッドは既に存在するキーに対しては呼ばれないんですね。

既に存在するキーに対応するメタメソッドが別にあればよさそうなもんですが、ないみたいです。そういうことをしたいなら、対象テーブルを常時空にして、実体データは別のテーブルで扱えということのようです。なんだかなぁ。

このため、上の実装では、既に存在するグローバル変数についてはそのまま問題なく使える実装になってます。でも一旦nilを代入すると未定義扱いに変化すると思われます。
スポンサーサイト

2005.08.25 | Comments(0) | Trackback(0) | Lua

コメント

コメントの投稿


秘密にする

新しい記事へ <<  | HOME |  >> 古い記事へ

広告:

カテゴリ展開メニュー

  • 未分類(13)
  • Lua(38)
  • プログラミング(11)
  • 食べ物(3)
  • SPAM(2)
  • ゲーム開発(4)
  • GIS/GPS/GoogleMaps(2)
  • スポーツ(1)
  • Skype API(1)
  • AR(1)

はてブ ランキング

ブログ全体: このWikiのはてなブックマーク数

プロフィール

はむ!

Author:はむ!
よく使う言語・環境:
C++,C,Lua,java,VBA,DB
たまにPHPとかjavascript
血液型:O型

メール: lua%ham.nifty.jp
(%を@に変えてください)
ついったー: @hammmm

Lua関連アンテナ

ブロとも申請フォーム

この人とブロともになる

全記事表示リンク

全ての記事を表示する

ブログ内検索


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。