<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>Lua</title><link>http://blogs.wankuma.com/izmktr/category/2117.aspx</link><description>Lua</description><managingEditor>出水 洸太郎</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>出水 洸太郎</dc:creator><title>[Lua]関数と変数は装備しないと意味ない</title><link>http://blogs.wankuma.com/izmktr/archive/2009/10/31/182601.aspx</link><pubDate>Sat, 31 Oct 2009 03:35:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/10/31/182601.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/182601.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/10/31/182601.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/182601.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/182601.aspx</trackback:ping><description>&lt;p&gt;今回はluaL_loadfile関数とluaL_dofile関数の違いです。(正式にはマクロだけど)&lt;br&gt;どちらも、ファイルからLuaスクリプトを読み込む関数なのですが、&lt;br&gt;luaL_loadfile関数は読みこむだけ、luaL_dofile関数は読みこんだ後スクリプトを実行をします。&lt;/p&gt; &lt;p&gt;Luaでこんなプログラムを読みこむ事を考えます。&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e8b2906c-3b19-4dfb-b309-31731755586e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;function foo()
  print "call foo"
end

function hoo()
  print "call hoo"
end
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;C言語からfooやhooを呼び出しながら使う、という事を想定していますが、&lt;br&gt;ここで読みこむ時はluaL_dofile関数を使う必要があります。&lt;/p&gt;
&lt;p&gt;C言語に慣れていると、luaL_loadfile関数で読みこむだけで中間コードへの変換は出来ているから、&lt;br&gt;実行する必要はない、と考えてしまうのですが、それは間違いです。&lt;/p&gt;
&lt;p&gt;先ほどのスクリプトを書き換えるとこうなります。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5308139b-8af0-453d-8d9c-16e2ef95aec0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;foo = function()
  print "call foo"
end

hoo = function()
  print "call hoo"
end
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;以上でわかるとおり、グローバル変数のfoo, hoo に関数の内容を代入するために&lt;br&gt;スクリプト全体を実行する必要があるのです。&lt;br&gt;Luaには関数宣言に当たるものがないので、中間コードに変換されているだけでは意味を持ちません。&lt;/p&gt;
&lt;p&gt;バッファから読み込む場合は、luaL_loadbuffer関数を使いますが、&lt;br&gt;luaL_dofile関数に当たる関数はないので、lua_pcall関数を使って実行する必要があります。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/182601.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[Lua]すべてを破壊しすべてを繋げ</title><link>http://blogs.wankuma.com/izmktr/archive/2009/08/05/179859.aspx</link><pubDate>Wed, 05 Aug 2009 23:26:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/08/05/179859.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/179859.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/08/05/179859.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/179859.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/179859.aspx</trackback:ping><description>&lt;p&gt;こんなソースがあるとします。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e5d4433c-57d4-4508-a75a-c4b2c38fd98a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="vb"&gt;function destroyer()
  print = nil
  _G = nil
end
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;何をやっているかというと、printと_Gを破壊しています。&lt;br&gt;非常に困ったちゃんなプログラムです。&lt;/p&gt;
&lt;p&gt;Luaは関数定義もグローバル変数の代入と見なすため、このように破壊できてしまいます。&lt;/p&gt;
&lt;p&gt;で、どうすればいいかというと、グローバル変数を与えなければよいのです。&lt;br&gt;Luaでは関数が入っている変数に「環境」というものを設定できます。&lt;br&gt;環境とは要はグローバル変数のことです。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c405df0b-6a9f-46a8-9b61-9e46d99d6a5c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="vb"&gt;dummy = {}
setfenv(destoryer, dummy)

destoryer()&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;こう書くと、上のとんでもない関数を実行しても問題ありません。&lt;br&gt;dummy._Gやdummy.printは書き換わりますが、もともとのグローバル変数には影響を受けません。&lt;/p&gt;
&lt;p&gt;…しかし、使いどころが思いつきません。&lt;br&gt;グローバル変数が全くない＝標準関数もなく、他に定義された関数もないって事で、&lt;br&gt;相当綿密に作らないといけないし、destoryerを読み込む方法はどうするの？という問題まであります。&lt;br&gt;誰か使い方教えて(汗&lt;/p&gt;
&lt;p&gt;ついでに、C言語から呼び出すならluaL_newstate() で作れば保護されるわけで…。&lt;/p&gt;
&lt;p&gt;ここまでシビアな状況を想定する場合、Lua単体で組むことは少ないですよねぇ？&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/179859.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[Lua]多次元ポケット</title><link>http://blogs.wankuma.com/izmktr/archive/2009/06/30/176785.aspx</link><pubDate>Tue, 30 Jun 2009 01:39:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/06/30/176785.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/176785.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/06/30/176785.aspx#Feedback</comments><slash:comments>95</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/176785.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/176785.aspx</trackback:ping><description>&lt;p&gt;C言語には多次元配列というものがあります。&lt;br&gt;実際には、y * xmax + x という演算を行うだけなのですが、Luaにはありません。&lt;/p&gt; &lt;p&gt;という事で作ってみました。&lt;br&gt;こんな感じで使います。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a6d16fd4-6463-414b-8ba7-278cb272099e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="vb"&gt;ary = CreateDimArray(5, 5, 5)

ary[3][2][5] = 325

print (ary[3][2][5])
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;実際のソースはこれ。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7b068738-0d47-4241-8908-bf507375eb48" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="vb"&gt;MetaDimArrayLast = {
  __index = function (table, key)
    return table.value[table.pos + key]
  end
  ,
  __newindex = function(table, key, value)
    table.value[table.pos + key] = value
  end
}

MetaDimArray = {
  __index = function (table, key)
    local t = table
    local pos = rawget(table, "pos")
    if (pos) then
      t.d = t.d + 1
      t.pos = (pos + key - 1) * t.dim[t.d]
    else
      t = {
        value = table.value,
        dim = table.dim,
        pos = (key - 1) * table.dim[2],
        d = 2
      }
    end
    
    if (t.d &amp;lt; #t.dim) then
      setmetatable(t, MetaDimArray)
    else
      setmetatable(t, MetaDimArrayLast)
    end
    
    return t
  end
}

function CreateDimArray(...)
  local dim = {...}
  -- 1次元以下なら普通のテーブル返して終わり
  if (#dim &amp;lt; 2) then return {} end
  
  local t = {
    dim = dim,
    value = {}
  }
  setmetatable(t, MetaDimArray)
  
  return t
end
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;うん、複雑ですね。&lt;/p&gt;
&lt;p&gt;実は、3つのクラスが作られています。&lt;br&gt;まず、CreateDimArrayで作られる型。&lt;br&gt;そして、ary[3] やary[3][2] と、三次元型なのに、すべての添え字が揃ってない時に返す型。&lt;br&gt;最後に三次元分すべてがそろった時に返す型です。&lt;/p&gt;
&lt;p&gt;__indexと__newindexをこねくり回してうまいこと作っているので、ソースを追っかけてみてください。&lt;/p&gt;
&lt;p&gt;さて、実際どうなのか…。&lt;/p&gt;
&lt;p&gt;このようなものを作らず、ちゃんとy * xmax + x という式を毎回適用した場合と、&lt;br&gt;実際にテーブルを作成した場合(ジャグ配列)とを比較してみました。&lt;br&gt;後者はこういうことです。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:eacb12d6-a9f8-4340-ac92-3c1d0be97f25" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="vb"&gt;ary = { 
  { {}, {}, {}, {}, {}, }, 
  { {}, {}, {}, {}, {}, }, 
  { {}, {}, {}, {}, {}, }, 
  { {}, {}, {}, {}, {}, }, 
  { {}, {}, {}, {}, {}, }, 
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;結果は…私の冒頭で紹介したパターンは、5倍遅いという結論になりました。&lt;/p&gt;
&lt;p&gt;特に、参照、代入時のボトルネックがあるのが問題です。&lt;br&gt;今回作ったパターンはメタテーブルの参照を行ううえ、&lt;br&gt;毎回テーブルを作っては破棄しているので、速度が遅いのも仕方ないでしょう。&lt;/p&gt;
&lt;p&gt;なお、テーブルを実際に作成するパターンと、y * maxx + x のパターンと比較すると、&lt;br&gt;テーブル作成を大量にするとジャグ配列パターンは若干遅いのですが、&lt;br&gt;参照、代入に関しては違いがみられないほどでした。&lt;/p&gt;
&lt;p&gt;これは、Luaが連想配列と線形配列(ランダムアクセスできる配列)を同時に持っているためと推測できます。&lt;br&gt;ですから、言うほど速度劣化にはつながらないのです。&lt;/p&gt;
&lt;p&gt;素直に、多次元を作る場合はジャグ配列パターンで実装するのが良いと思います。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/176785.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[Lua]よりぬきくりぬき</title><link>http://blogs.wankuma.com/izmktr/archive/2009/06/08/174454.aspx</link><pubDate>Mon, 08 Jun 2009 02:13:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/06/08/174454.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/174454.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/06/08/174454.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/174454.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/174454.aspx</trackback:ping><description>&lt;p&gt;参考＞&lt;a href="http://blogs.wankuma.com/izmktr/archive/2009/04/03/170749.aspx"&gt;[Lua]いっぱいもらって～いっぱいあげれる～&lt;/a&gt;&lt;/p&gt; &lt;p&gt;可変長引数の便利な構文をいろいろ書いていきます。&lt;/p&gt; &lt;p&gt;Luaの可変長引数を下の関数に引き渡す方法です。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2030c1f4-c750-4759-854d-85854abba3f3" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;function foo(...)
  hoo(...)
end&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;単純にこうすればよいのです。&lt;br&gt;しかし、Luaだといろいろ引数を加工が用意です。&lt;/p&gt;
&lt;p&gt;まず、1番目の引数は除いて、2番目以降の引数から渡したい場合です。&lt;br&gt;これには2つの方法があります。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:36717f80-1219-4a2c-9fd8-e607d5472c91" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;function foo(first, ...)
  hoo(...)
end

function foo2(...)
  hoo(select(2, ...))
end&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;一つは最初に変数を置いて、残りを可変長引数とする方法です。&lt;br&gt;こうすると1番目が取り除かれたものが...の内容となります。&lt;/p&gt;
&lt;p&gt;もうひとつは、selectを使う方法です。&lt;br&gt;これは、最初の引数の数値以降にある引数を返す関数です。&lt;br&gt;今回の場合は最初の1個を取り除きたいので、2を指定して2個目以降を取得しています。&lt;/p&gt;
&lt;p&gt;なお、selectにはもう一つ使い方があり、最初の引数に"#"を渡すことで引数の数を取得することができます。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f876e152-295b-4bc7-93df-b713e1c04df3" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;function count(...)
  print(select("#", ...))
end

-- 6が出力される
count (1, 2, 3, 4, 5, 6)&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;C言語の可変長引数はとても使いにくい印象がありますが、&lt;br&gt;Luaの可変長引数は気軽に使って行けるので気軽に使っていきましょう。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/174454.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[Lua]名前空間とメンバ関数でアクセス演算子が違うのは困る</title><link>http://blogs.wankuma.com/izmktr/archive/2009/06/03/174074.aspx</link><pubDate>Wed, 03 Jun 2009 22:54:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/06/03/174074.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/174074.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/06/03/174074.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/174074.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/174074.aspx</trackback:ping><description>&lt;p&gt;表題の通りです。&lt;br&gt;こんな違いでピリオドとコロンを使い分けろと言われても、ピリオドに統一してくれよ！と思います。&lt;br&gt;正直、面倒でしかたないと思います。&lt;/p&gt; &lt;p&gt;具体的に、どういうことなのか。&lt;br&gt;こういうことです。&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9fbb7df8-8316-4176-b684-d795c8820306" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;Vector ={}
MetaVector = { __index = Vector }

function Vector:Length()
  return math.sqrt( self.x * self.x + self.y * self.y )
end

function CreateVector(x, y)
  local t = {x = x, y = y}
  setmetatable(t, MetaVector)
  return t
end

pos = CreateVector(30, 40)

print (pos.x, pos.y)
print (pos:Length())
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;mathを名前空間として使っているので、math.sqrtはピリオドです。&lt;br&gt;メンバ変数のpos.x, pos.yもピリオドです。&lt;br&gt;しかし、メンバ関数になる、pos:Length() はコロンになります。&lt;/p&gt;
&lt;p&gt;この辺のからくりは以前に書いています。　[&lt;a href="http://blogs.wankuma.com/izmktr/archive/2009/02/20/168484.aspx"&gt;[Lua]古きを温め新しきに誤魔化す&lt;/a&gt;]&lt;br&gt;簡単に言うと、selfというthisに当たるものを使いたい場合はコロンなのです。&lt;/p&gt;
&lt;p&gt;が、使い分けは面倒です。&lt;br&gt;特にLuaは引数の過不足をエラーとしないので、ピリオドとコロンを間違えてもエラーが出ません。&lt;/p&gt;
&lt;p&gt;だったら、全部ピリオドでアクセスできるようにしてしまえばいいんですよ。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:99e06bdc-4680-4c1a-9d55-0fe2793006c0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;MetaWrap = {
  __index = function(tbl, key)
    local value = tbl._tbl[key]
    if (type(value) == "function") then
      return function(...) return value(tbl._tbl, ...) end
    else
      return value
    end
  end
  ,
  __newindex = function(tbl, key, value) tbl._tbl[key] = value end
}

function WrapTable(tbl)
  local t = {_tbl = tbl}
  setmetatable(t, MetaWrap)
  return t
end

pos = WrapTable(CreateVector(30, 40))

print (pos.x, pos.y)
print (pos.Length())
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ものの見事にpos.Length()とメンバ関数もピリオドでアクセスできるようになりました！&lt;br&gt;みての通り余計なものが入っているのでコロンでアクセスするよりは遅くなってしまうのですが、&lt;br&gt;こういう書式にこだわるのは別の言語でも良くやることですよね。&lt;/p&gt;
&lt;p&gt;__newindexも設定しているので、新たにキーを追加しても問題ありません。&lt;/p&gt;
&lt;p&gt;ということで、ピリオドとコロンを使い分けるような言語…おっと、誰か来たようだ…こんな時間にだれかな…。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/174074.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[Lua]ハンプティプロパティ</title><link>http://blogs.wankuma.com/izmktr/archive/2009/06/03/174035.aspx</link><pubDate>Wed, 03 Jun 2009 02:17:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/06/03/174035.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/174035.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/06/03/174035.aspx#Feedback</comments><slash:comments>520</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/174035.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/174035.aspx</trackback:ping><description>&lt;p&gt;まずはこのソースを見てください。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8ab0576a-92c3-4721-a6d8-fff3b52235a0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;angle = CreateAngle()

angle.deg = 90
print("deg =", angle.deg, "rad =", angle.rad)

angle.rad = math.pi * 2
print("deg =", angle.deg, "rad =", angle.rad)
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;実行結果はこうなります。&lt;/p&gt;
&lt;p&gt;deg =&amp;nbsp;&amp;nbsp; 90&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rad =&amp;nbsp;&amp;nbsp; 1.5707963267949&lt;br&gt;deg =&amp;nbsp;&amp;nbsp; 360&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rad =&amp;nbsp;&amp;nbsp; 6.2831853071796
&lt;p&gt;degに入れても、radに入れても両方の値が変わっています。&lt;br&gt;C#のプロパティ構文を知らないと、ちょっと不思議な動作になってます。&lt;/p&gt;
&lt;p&gt;実は、angleにはdegというキーはあっても、radというキーはありません。&lt;br&gt;故にangle.radの値はnilが返ってくるはずですし、&lt;br&gt;angle.radに値を代入すると、新しくradというキーが作られるはずです。&lt;/p&gt;
&lt;p&gt;キーがない場合、メタテーブルの__indexが参照され、&lt;br&gt;キーを新しく作ろうとすると、メタテーブルの__newindexが参照されます。&lt;/p&gt;
&lt;p&gt;よって、CreateAngleのソースは以下のようになります。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5c34b5eb-4ce3-4e2a-b145-b37570e21e65" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;MetaAngle = {
  __index = function(self, key)
    if (key == "rad") then return self.deg * math.pi / 180 end
  end
  ,
  __newindex = function(self, key, value)
    if (key == "rad") then self.deg = value / math.pi * 180 end
  end
}

function CreateAngle(n)
  local t = {}
  if (n) then t.deg = n else t.deg = 0 end
  
  setmetatable(t, MetaAngle)
  
  return t
end
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;__index, __newindexにテーブル型を入れておけば、そのテーブルの中身が参照されますが、&lt;br&gt;関数型を入れておくこともでき、そこでradというキーが渡された時の動作を記述します。&lt;/p&gt;
&lt;p&gt;今は、keyの内容をifで比較していますが、数が多くなればそれ用のテーブルを作った方がいいでしょう。&lt;br&gt;Luaのテーブルはハッシュを使っているので、高速な動作が期待できます。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/174035.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[Lua]スーパーDRY</title><link>http://blogs.wankuma.com/izmktr/archive/2009/04/18/171650.aspx</link><pubDate>Sat, 18 Apr 2009 04:45:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/04/18/171650.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/171650.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/04/18/171650.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/171650.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/171650.aspx</trackback:ping><description>&lt;p&gt;DRY = Don't repeat yourself という規則があります。&lt;br&gt;おんなじことなら二回書くな、ってやつですね。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e51f5020-2654-409d-8075-588e456c99b7" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="vb"&gt;function event()
  message("いくぜ、おれの必殺技")
  sound("どーん.wav")
  message("えい")
  sound("がーん.wav")
  message("とう")
  sound("どどーん.wav")
  message("とりゃー")
end
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;上のソースはおおざっぱに書いたものですが、soundとmessageが入ってます。&lt;br&gt;messageはコルーチンのyieldになっています。&lt;/p&gt;
&lt;p&gt;これを実行したとき、wavをその都度読んでいるので遅いという問題があるとします。&lt;br&gt;出来れば先読みして、メモリに転送しておいて、そちらから再生したい、とします。&lt;/p&gt;
&lt;p&gt;で、この先読みするファイルのリストをどうやって作るか…。&lt;br&gt;Luaってのはすべての関数がグローバル変数なので、messageを空関数にして&lt;br&gt;soundのリストをどっかにため込む構造にしてしまえばいいわけです。&lt;br&gt;リストを作り終わった後は、元の関数を再定義して終わりです。&lt;/p&gt;
&lt;p&gt;関数ではなく変数、というところがポイントですね。&lt;br&gt;同じコードなんだけど、別の動きをさせることが簡単にできます。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/171650.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[Lua]Rangeで簡単 コーディング</title><link>http://blogs.wankuma.com/izmktr/archive/2009/04/13/171350.aspx</link><pubDate>Mon, 13 Apr 2009 23:28:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/04/13/171350.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/171350.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/04/13/171350.aspx#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/171350.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/171350.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/izmktr/archive/2009/04/11/171256.aspx"&gt;[Lua]俺の家Range&lt;/a&gt;の続きです。&lt;/p&gt; &lt;p&gt;Luaの拡張forはコルーチンを使うとすっきり記述できるのですが、&lt;br&gt;コルーチンの生成って結構重い処理らしいので、コルーチンを使わない方法です。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5d896322-674c-463b-b6a6-092b6c28bbc7" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;a = {100, 200, 300, 400, 500}

for k,v in next, a, nil do
  print (k, v)
end
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;next(テーブル名, キー名) で次のキーとその値を返す関数があります。&lt;br&gt;最初のキーが欲しい時はキー名にnilを、&lt;br&gt;そして最後のキーでこれを呼び出すと返り値のキーがnilになります。&lt;/p&gt;
&lt;p&gt;どっかで見たと思ったらlua_next()というC言語側にある関数にそっくりなわけですね。&lt;br&gt;C言語の方はスタックでちょっと苦労するのですが…。&lt;/p&gt;
&lt;p&gt;ともあれ、基本はこのnextの書式なんですよね。&lt;br&gt;下の展開したものを見てもらえるとわかると思います。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:b8000e24-187b-495a-afa7-32c55224481b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;a = {100, 200, 300, 400, 500}

local k = nil
while true do
  k, v = next(a, k)
  if (k == nil) then break end
  print (k, v)
end
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;inの後ろには3つの式が必要で、関数、ワーク用テーブル、初期値となり、&lt;br&gt;関数がワーク用テーブル、現在値の引数を取り、返したい個数を返り値とします。&lt;br&gt;そして、第一返り値がnilの時、ループが終了します。&lt;/p&gt;
&lt;p&gt;ワーク用テーブルを引数に取れるので、ここでゴネゴネするのもいいですが、&lt;br&gt;Luaはクロージャーを使えるので、今回はそちらで解決してみたいと思います。&lt;/p&gt;
&lt;p&gt;前回作ったRangeをコルーチンを使わずに書いてみた例です。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:edeb288b-ab00-40a7-b8aa-464b571769c8" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;function range(idx, loop) 
  local max = idx + loop
  local f = function (a, b)
    if (b + 1 &amp;lt; max) then  return b + 1 end 
    return nil
  end
  return f, nil, idx - 1
end

for i in range(100, 10) do
  print (i)
end
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;いろいろな正解例があるでしょうが、とりあえず一例です。&lt;/p&gt;
&lt;p&gt;普通のforより拡張forの方がいろいろと便利なので、&lt;br&gt;新しいイテレータの作り方は押さえておきたいところです。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/171350.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[Lua]俺の家Range</title><link>http://blogs.wankuma.com/izmktr/archive/2009/04/11/171256.aspx</link><pubDate>Sat, 11 Apr 2009 19:23:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/04/11/171256.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/171256.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/04/11/171256.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/171256.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/171256.aspx</trackback:ping><description>&lt;p&gt;Luaのコルーチンにはcoroutine.wrapという関数があります。&lt;br&gt;これは、コルーチンになった関数を返してくれるもので、&lt;br&gt;返ってくる関数を呼び出せばコルーチンになっているというものです。&lt;/p&gt; &lt;p&gt;主な使い方は、イテレータの生成です。&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:3a318c6e-ce0c-436f-9509-94ea61544136" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;function func()
  for i = 1, 10 do
   coroutine.yield(i)
  end
end

itr = coroutine.wrap(func)

for i in itr do
  print (i)
end
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ところが、この使い方だと、funcの引数を与えることができません。&lt;br&gt;そこで、上の方法を一工夫加えて、C#のRangeみたいな関数を作ってみます。&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:823e4a57-6114-4fb1-a848-4de98abd3214" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;function range(start, loop)
  local func = function()
    for i = 0, loop - 1 do
      coroutine.yield(i + start)
    end
  end
  return coroutine.wrap(func)
end

for i in range(100, 10) do
  print (i)
end
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;forの中に直接入れられるように、coroutine.wrap で返ってくる関数を戻り値にします。&lt;br&gt;そして、引数で与えられないのなら、カリー化しちゃえばいいんですな！&lt;/p&gt;
&lt;p&gt;ということで、割と簡単にイテレータも作れます。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/171256.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C][Lua]tolua++にだって&amp;hellip;出来ないことはある&amp;hellip;</title><link>http://blogs.wankuma.com/izmktr/archive/2009/04/06/170817.aspx</link><pubDate>Mon, 06 Apr 2009 03:11:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/04/06/170817.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/170817.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/04/06/170817.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/170817.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/170817.aspx</trackback:ping><description>&lt;p&gt;tolua++は便利なんですが、従来のlua_Stateを受け取る形ができません。&lt;/p&gt; &lt;p&gt;tolua++はC言語のグルーコードを生成してくれるツールなので、&lt;br&gt;C言語で書けない形式は生成できないのです。&lt;br&gt;ですから、可変長引数、可変長返り値、型がわからない引数などは受け取れません。&lt;/p&gt; &lt;p&gt;int foo(lua_State *); という関数だと、自動的に見切ってくれないかな～という淡い期待は打ち砕かれ…。&lt;br&gt;ちなみに、int foo(...); という形式なら、未対応と言われて終了です。&lt;/p&gt; &lt;p&gt;そこで何とかしたのがこれ。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:49f97a1a-9277-436f-99ab-9c68a9e80dfd" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;class Test{
public:
  int action1(lua_State *L);
  int action2(lua_State *L);
};

template &amp;lt;typename T, int (T::*F)(lua_State *) &amp;gt;
int glue_func(lua_State *L){
  T *self = (T *) tolua_tousertype(L,1,0);
  lua_remove(L, 1);
  int ret = (self-&amp;gt;*F)(L);
  return ret;
}

void regist(lua_State *L){
  luaL_getmetatable(L, "Test");

  lua_pushcfunction(L, (lua_CFunction)( glue_func&amp;lt;Test, &amp;amp;Test::action1&amp;gt;) );
  lua_setfield(L, -2, "action1");

  lua_pushcfunction(L, (lua_CFunction)( glue_func&amp;lt;Test, &amp;amp;Test::action2&amp;gt;) );
  lua_setfield(L, -2, "action2");

  lua_pop(L, 1);
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;まず、tolua++で、Testのクラスだけはグルーコードを生成しておきます。&lt;br&gt;action1, action2 はluaを使って登録するので、tolua++でグルーコードは生成しません。&lt;/p&gt;
&lt;p&gt;登録する関数は、glue_funcのテンプレートを使って、自動的にグルーコードを作ってやります。&lt;br&gt;&lt;a href="http://bbs.wankuma.com/index.cgi?mode=al2&amp;amp;namber=34669"&gt;ここで偉い人から頂いた解答をコピペしただけですけど&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;ただ、このコードはselfが本当にTest型なのか調べずにキャストしているので、よいコードではありません。&lt;br&gt;本来なら、tolua_isusertypeを使って、Test型なのかのチェックをするべきでしょう。&lt;/p&gt;
&lt;p&gt;わざわざ、こんな方法を考えるきっかけは、Luaの関数型を受け取りたかったわけです。&lt;br&gt;関数型はC言語で表せないので、受け取ることはできません。&lt;/p&gt;
&lt;p&gt;しかし、この関数型はとても便利ですので、使えないからと諦めるには惜しすぎます。&lt;br&gt;関数型をC言語で扱う方法は「&lt;a href="http://blogs.wankuma.com/izmktr/archive/2009/03/30/170398.aspx"&gt;[C][Lua]Luaの中の迷宮&lt;/a&gt;」を見てください。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/170817.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>