2011-09-27 34 views
17

私のLuaスクリプトでは、可変数の引数を持つ関数を作成しようとしています。私が知る限り、以下のように動作するはずですが、どういうわけかTI-NSpireのLua 5.1でエラーが発生します(グローバルargはゼロです)。私は間違って何をしていますか?ありがとう!可変数の関数引数Lua 5.1

function equation:init(...) 
    self.equation = arg[1] 
    self.answers = {} 
    self.pipe = {arg[1]} 
    self.selected = 1 

    -- Loop arguments to add answers. 
    for i = 2, #arg do 
     table.insert(self.answers, arg[i]) 
    end 
end 

instance = equation({"x^2+8=12", -4, 4}) 
+0

'call'メタメソッドが' equation'に定義されているコードを追加してください。このコードはそれがなければ本当に意味をなさない。 – Mankarse

答えて

31

Luis's answerを試してみてください言語に初心者よりterserはを望ん可能性がある場合、権利です。私はそれをちょっと詳しく説明しようと思います。

あなたの質問は、TI計算機の特定のモデルに埋め込まれたLuaのコンテキストにあります。したがって、スタンドアロンのLuaとは異なる詳細がありますが、ほとんどの場合、それらの詳細は、あなたの環境で利用できるライブラリと関数に関係します。 Luaの組み込みバージョンがその作者によって配布されたスタンドアロンのLuaと大きく異なることは珍しいことです(ただしLuaはオープンソースなので可能です)。 (Lua Binariesは多くのプラットフォーム用のバイナリのリポジトリです。Lua for Windowsは、Windows用電池、付属の完全なディストリビューションです。)

あなたのサンプルコードでは、交絡要因、それは電卓が提供するクラスのシステムとのインターフェースに必要な詳細を持っていますフレームワーク。その詳細は、ほとんどあなたのequationオブジェクトとequation:init()関数が呼び出されている間に接続が存在しないと表示されます。それを接着できる技術があるので、それはちょうど気晴らしです。

あなたが知っているあなたの質問は、可変長関数(可変数の引数を持つ関数)が宣言され、Luaでどのように実装されているかを混乱させます。 Luisの答えに対するあなたのコメントから、あなたはLuaのプログラミング(PiL)のオンライン版を読んでいます。あなたはsection 5.2を引用しました。 PiLは言語のバックグラウンドの良いソースです。残念なことに、可変的な機能は、流行してきた機能の1つです。ライン上の本の版はLuaバージョン5.0では正しいですが、TIの電卓はおそらくLua 5.1.4を実行しています。

ルア5では、変数の関数は、残りの引数を表すシンボル...で終わるパラメータリストで宣言されています。 Lua 5.0では、argという名前の "マジック"ローカル変数が呼び出され、...に一致する引数を含むテーブルが含まれていました。これは、すべてのバリデーショナル関数が呼び出されたときにテーブルを作成することを必要としました。これは不要なオーバーヘッドとガベージコレクタへの負担の原因です。したがって、Lua 5.1では、実装が変更されました。...は、呼び出された関数で一致する引数のエイリアスとして直接使用できますが、実際にテーブルは作成されません。代わりに、引数の数が必要な場合はselect("#",...)と書き、n番目の引数の値が望ましい場合はselect(n,...)と書きます。

例の混乱要因がクラスシステムに戻ってきます。関数equation:init(...)を宣言したいとします。この宣言はコロン構文を使用するため、equation.init(self,...)と書くことと同等です。したがって、最終的にクラスフレームワークの__callメタメソッドを使用して呼び出されると、実際の最初の引数はselfとなり、0以上の実際の引数は...と一致します。

以下アムルさんのコメントで述べたように、表現select(n,...)が実際にself.answersを構築するため、この場合に特に有用であるが、また、self.pipeの初期設定で可能なバグにつながる上のn番目の引数から、すべての値を返します。ここで

は、あなたがequation:init()のあなたの定義で達成しようとしているものの私の改訂近似であるが、私は手元にTI電卓の一つを持っていないと、これはテストされていないことに注意してください:

function equation:init(...) 
    self.equation = select(1, ...) 
    self.pipe = { (select(1,...)) } 
    self.selected = 1 
    self.answers = { select(2,...) } 
end 

上記の改訂版では、最初の引数である1つの要素と、残りのすべての引数を含むテーブルを作成する{select(2,...)}を含むテーブルを作成するために{(select(1,...))}と書いています。このようにしてテーブルに挿入できる値の数には限界がありますが、その制限は関数の戻り値の数や関数に渡すことができるパラメータの数に関係しているため、 ...への参照を超えました。これは一般的ではない可能性があり、{ unpack(t) }とすると、tの配列部分がすべてコピーされないことに注意してください。

関数の書き方がやや効率的ではない方法は、渡された引数の上にループを書くことです。これは元の答えのバージョンです。それは次のようになります:

+0

うわー、おかげさまで詳細な答えがたくさん!これはまさに私が意味していたものです。私は '...'が 'arg'というテーブルを作ることを期待していましたが、これは起こりませんでした。あなたのご親切に感謝します! – Frog

+1

correction-select(n、...)は、n番目の引数を返しません。むしろ、n番目の引数だけでなく、その後のすべての引数も返します。 –

+2

@AmrBekhit、右、簡単に見落とされる詳細。 'select(n、...)'はn番目以降の引数を返します。これは文脈によってn番目のものに狭められることがよくあります。しかし、そのプロパティはここで便利ですので、私は私の答えを更新します。 – RBerteig

20

function equation:init(...) 
    local arg={...} 
+3

それは問題を解決します。しかし、なぜそれはインターネット上で提唱されているように動作しないのですか? – Frog

+0

@Frog: 'equation.init'はどうやって呼びますか?あなたが呼んでいるように見えるのは「方程式」だけです。あなたが使用しているクラスシステムがありますか? –

+0

@Frog、アドバイスを受けた場所へのポインタで質問を更新するか、新しい質問をしてください。インターネットは大きな場所です....すべてが信頼できるアドバイスを持っているわけではありません。 ;-) – RBerteig

関連する問題