2011-02-10 5 views
1

私はLuaのスコープ規則を少し混乱させています。私は、以下の私が質問(複数可)をお聞きしたいの問題を強調するためのLuaスクリプトのスニペットを提出した:Lua可変スコープ、関数forward宣言、 'require'ステートメントを使用してLuaスクリプトをリファクタリングする

-- 'forward definitions' 
-- could these be moved to the bottom of the script to 'tidy up' the script? 
-- could these reside in another file imported by require 'filename' to tidy up the script even more? 

[[ Note: This function is accessing variables defined later on/elsewhere in the script 
     and is also setting a variable (flag) which is then used elsewhere in the script 
]] 

function war_is_needed() 
    if (goodwill:extendsToAllMen() and peace) then 
     if player:isAppointedLeader() then 
      economy_is_booming = false 
      return true 
     else 
      economy_is_booming = nil 
      return true 
     end   
    else 
     economy_is_booming = nil 
     return false 
    end 
end 



world = WorldFactory:new('rock#3') 
player = PlayerFactory:getUser('barney', world) 

while (not player:isDead()) do 
    peace = world:hasPeace() 
    goodwill = world:getGoodwillInfo() 

    if war_is_needed() then 
     world:goToWar() 
    else 
     if (not economy_is_booming) then 
      player:setNervousState(true) 
      player:tryToStartAWar() 
     else 
      player:setNervousState(false) 
      player:liveFrivously() 
     end if 
    end 
end 

私の質問は、(グローバル変数は悪とみなすことができることを今のところ無視)されています

  • スクリプトの上部にある機能をスクリプトの下部に移動して、スクリプトを整理することはできますか?
  • スクリプトの別のファイル 'warfuncs.lua'にリファクタリング(つまり移動)し、関数定義をrequire 'warfuncs.lua'に置き換えることでスクリプトにインポートできますか?

上記の二つの質問に答えながら、スクリプトの先頭に関数が/他の場所スクリプト で、後に定義された変数にアクセスしても、その後である変数(フラグ)を設定していることを心に留めてください。スクリプトのどこかで使用されます。

LuaがCまたはC++に埋め込まれている場合(オブジェクトがヒープ上に作成されている可能性がある)、スコープ規則が変更されますか?

答えて

1

lhfが正しい場合は、あなたのコードをリファクタリングすることができ、それでも動作します。しかし、この特定のスクリプトの例はすべてグローバルなものですが、事実上一時的な変数(たとえば、ループまたは単一の関数の範囲内)で作業する場合、それらを次のように宣言することをお勧めします。 local

C/C++への埋め込みに関する3番目の質問に関しては、アプリケーションが単一のLua状態を作成してスクリプトファイルをロードするため、Luaスクリプト内のスコープルールに違いはありません。 requireを実行するファイルは、C/C++アプリケーションの初期化中にロードされた状態のスコープ内で実行されます。あなたはちょうどあなたがあなたの関数/変数を定義していることを確認する必要が私の知る限り

2

war_is_needed whileループの後には移動できません。 whileループが関数に含まれていた場合は、war_is_neededの後ろに移動することができます。すべてがグローバルなので、2番目の質問に対する答えは「はい」です。

1

/...それらを使用する前に、そうそこにこのスニペットは問題

function foo() 
    print(a) 
end 
a="Bar!" 
foo() 

に与えることはありません。しかし、これは以下となります。

a="Bar!" 
foo() 
function foo() 
    print(a) 
end 

関数を実行する前にすべてを定義し、変数を効果的に使用する必要があります。メインスクリプトやdofileでそれらを定義するかどうかは関係ありません。

関連する問題