トップページtech
582コメント172KB

プログラミング言語 Lua

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
Lua について語ろう。

http://www.lua.org/
0186デフォルトの名無しさんNGNG
いきなりendは、心臓に悪い。
0187デフォルトの名無しさんNGNG
>>185
それなら}のみにすれば更に吉かも?
0188デフォルトの名無しさんNGNG
vimでは対応してますか?
0189デフォルトの名無しさんNGNG
>>187
いっそ.とかの方が気持ちよくないか?
0190デフォルトの名無しさんNGNG
end に慣れたから正直些細なこととしか思わない。
Pascal の後で C をやったときは == にも抵抗があったがそれも今では些細なこと。
0191デフォルトの名無しさんNGNG
>>190
いや、そうではなくて(つまり、好き嫌いとかなれとかでなくて)
editorが対応してない香具師があるというのが問題なんだ

下手すればemacs専用になるよ(w
0192デフォルトの名無しさんNGNG
>>191
何を訳のわからんことを・・・
0193デフォルトの名無しさんNGNG
漏れは、c/awk/ruby/...と見て来たが、正直luaもハマリそうだ
しかし、言語が変わるたびに書き方変わるのが正直つらい。

いつになったら、--になれることやら。。。

だれか?マジデluaを改造してくれんか?
0194デフォルトの名無しさんNGNG
>>190
重度の不感症ですね。
0195デフォルトの名無しさんNGNG
>191
ttp://lua-users.org/wiki/LuaEditorSupport
Vim, Emacsen, Jed, MED, NEdit, TextPad, Scintilla/SciTE, EditPlus, EditPadPro, MC-Cooledit
0196デフォルトの名無しさんNGNG
>>195
おお〜、ありがとう!!
0197デフォルトの名無しさんNGNG
ついでといっちゃあなんだけど、if〜then のthen
ってなんで必要なんだろう?

改行じゃまずいのでしょうか?
0198デフォルトの名無しさんNGNG
>>195
これって単にハイライト表示するだけじゃないの?
{}のマッチと比較するには非力か?(ちがってたら、スマソ)
0199MLerNGNG
>>197
演算子の区分を決めるために必要。
ただし、別にthenじゃなくてもいいんだけど。
例えば、C言語の条件演算子'?' と ':' の間の式中には
優先度の低いカンマ演算子が置ける。これと同じ原理。
仮に改行を区切り子にすると、BASICの様な行指向言語に
なってしまう。
0200デフォルトの名無しさんNGNG
>>199
でも、どうでしょう?
実際のところifの条件箇所をマルチラインでサクッと書ける言語
なんてほとんどないと思うけど。。。
0201デフォルトの名無しさんNGNG
話が噛み合ってない。
0202200NGNG
えっと、うまく伝わらなかったみたいでスマソ、

例えば、すっごくなが〜い条件文があったとしても、
backslash で結べば十分だとおもうのですが。。。どこか欠けてますか?

if x>3 and \
y<3
a=4
end

来んな風には書けないとおもったが。。。

if x>3 and
y<3 then
a=4
end

0203200NGNG
いま手もとでやってみたら書けた(動いた)!
スマン>ALL
0204デフォルトの名無しさんNGNG
>>198
indent/lua.vim は適切にインデントしてくれる
0205デフォルトの名無しさんNGNG
だれかコンパイル済みのluaください。
0206デフォルトの名無しさんNGNG
http://angband.oook.cz/distrib/Angband-303.exe
0207デフォルトの名無しさんNGNG
>>205
luaのオフィサイトにおいてあるけど
0208デフォルトの名無しさんNGNG
>>195
最新のvimには両方ついてくるね
0209デフォルトの名無しさんNGNG
>>204

勘違いしてる香具師が多いので言っとくけど、インデントなんて
ど〜でもいいんよ!
0210デフォルトの名無しさんNGNG
言語仕様的にはどうでもいいけど、変なインデントは人が読むにはつらいので、適切にインデントしてくれることは重要だと思う。
0211デフォルトの名無しさんNGNG
pretty-printぐらい欲しいだろう
0212デフォルトの名無しさんNGNG
>>209

{ } じゃなくて end だと数があってるかがエディタで確認しにくい
  ↓
エディタが end を認識すればいいんだけど
  ↓
emacs ならできるよ
  ↓
じゃあ emacs 以外は?
  ↓
vim には標準で indent/lua.vim がついてくる
0213デフォルトの名無しさんNGNG
    ↓
vim なんか使ってネエ
    ↓
たかがindentがeditorに依存するのは馬鹿げてる
    ↓
luaは一応program作る言語
    ↓
pretty-printぐらい欲しいだろう
    ↓
pretty-print誰か作れ
0214デフォルトの名無しさんNGNG
>>213
知るか、死ね。
0215デフォルトの名無しさんNGNG
>>212,213

サンクス、流れがよくワカッた。
つまり、vimならインデントと言っても%によるマッチが(標準で)つかえるのね?

0216デフォルトの名無しさんNGNG
LUAって結局はCから呼ばれるライブラリみたいなもんでしょう?
これをスクリプト言語として使うのは、無理でないにしてもやや
目的外って感じになるのでしょうか???
0217デフォルトの名無しさんNGNG
>>216
んなこたないと思うよ。5.0ではtagまわりがさらに強化されてるし。>>108のリンク嫁
0218デフォルトの名無しさんNGNG
>>215
試してみたが、indentはインデントであって % によるマッチは行なわない。
改行した瞬間やendと打った瞬間にインデントされる。
また gg=G でバッファ全体のインデントが修正される。
詳しくはvim使いに聞いて。
0219デフォルトの名無しさんNGNG
>>218
やはり、というか%マッチの威力を知らん香具師のあおりの検証サンクス!
有る意味、自動でインデント(綺麗に)されてると、変なかたわれブロック
が出来たときにかえってバグ取りが難しくなる。

よって、endは糞決定!

>>217
結局TAGっていっても素直にADDのFUNCTIONと(この例読むかぎりでは)なん
の違いもない。(こちらは、99%もれの理かい不足!)
0220デフォルトの名無しさんNGNG
>>219
> 有る意味、自動でインデント(綺麗に)されてると、変なかたわれブロック
> が出来たときにかえってバグ取りが難しくなる。

そのためにも >> と << があるのでは。
0221デフォルトの名無しさんNGNG
>>220
なにそれ?
0222デフォルトの名無しさんNGNG
>>221
To increase the amount of indent in a line, use the ">" operator. Often this
is used as ">>", which adds indent to the current line.
そういうことじゃなくて?

まあ % 好きに非難されるのは理解できなくはない
0223デフォルトの名無しさんNGNG
もう分かってると思うが
普通のif文の中で、endのないifをいれてしまったら
と思うとぞっとする。
0224デフォルトの名無しさんNGNG
ほんと、構文については書き直して欲しいな、これ。
センスなさすぎ。
0225デフォルトの名無しさんNGNG
とはいえ、以外に伸びるなぁこの擦れ
こんなにマイナーな言語なのに。。。(w
0226デフォルトの名無しさんNGNG
sage
0227デフォルトの名無しさんNGNG
Lua5.0のcoroutine(Schemeの継続みたいなやつ)って結構おもろいな。
0228デフォルトの名無しさんNGNG
>>227
subroutineと違うのか?
0229デフォルトの名無しさんNGNG
おもろいけど独特過ぎないか
0230デフォルトの名無しさんNGNG
それは言いすぎでないか
0231デフォルトの名無しさんNGNG
coroutineって普通にCソースから使えないのかな?軽く実装してみたが
どうもうまくいかん。

lua_dostring(l, ... );
while( lua_resume(l) != 0 ){
;
}

というような感じの事をしたいのだけど、5.0Βはまだ謎がいっぱいだ。
0232デフォルトの名無しさんNGNG
あぁ、あと、構文だけど、ソースをちょっと弄ればCライクなスコープが
記述できるようになるんだけど、Luaって改変して配布するのってOKなの
かな?

まぁ、そこまでして使うのはどうかと思うけど、どーせ使うならあのダサ
いコメント「--」だけは//辺りに変更する事をお勧めするよ。
0233デフォルトの名無しさんNGNG
>>232
>ダサいコメント「--」だけは//辺りに変更する事をお勧めするよ。

正直、//に比べて--のどこがダサいのかわからん。

単にお前の好き嫌いだろ?

0234デフォルトの名無しさんNGNG
触ったことある言語だと Ada Occam Haskell Eiffel Sather は -- だったよ
あ SQL もそうだよ
珍しくもないな
0235デフォルトの名無しさんNGNG
begin endがダサいと言ってるのと変わらんわな
0236デフォルトの名無しさんNGNG
coroutine って resume で引数渡せるから油断すると goto なみに危険
0237デフォルトの名無しさんNGNG
>>233
理由は簡単。Cへの組み込みスクリプトだからコメントがCと同じほうが
いいに決まってる。それに--はCではデクリメント演算子なので意味合い
が違う。だから--コメントはダサい。と、個人的に思う。
まぁちょっとパッチ当てるだけで変更出来るんだからいいんだけどね。
0238デフォルトの名無しさんNGNG
コメントが // で出来るCの処理系ってそんなに多い?
0239デフォルトの名無しさんNGNG
gccでも-pedanticつけると//はエラーになるな
0240デフォルトの名無しさんNGNG
いつの話だ‥‥
今じゃ // コメントは ISO C の標準になってるよ。
0241デフォルトの名無しさんNGNG
gcc でも -std:c99 -pedantic とやればエラーにならない。
0242デフォルトの名無しさんNGNG
endやめて;にしてくれ>だれか
0243デフォルトの名無しさんNGNG
>>241
Invalid option `-std:c99'だってよ。ちなみにgcc 2.95.3
0244241NGNG
>>243
ごめん。-std=c99 のまちがい。
ていうかもはやぜんぜん Lua の話じゃないね。
0245デフォルトの名無しさんNGNG
>>232
Lua(5.0beta)はMITライセンス(修正BSDライセンス相当)だから、
自由に改変、再配布できるよ。

俺もコメントは//か#がいいのでパッチ作成キボン。
ついでにdo ... endを{ ... }にしてくれると最高。
0246デフォルトの名無しさんNGNG
>>231
test.c:
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main(int argc, char **argv) {
  int index, i;
  lua_State *L, *co;
  L = lua_open();
  lua_baselibopen(L);
  index = lua_gettop(L);
  lua_dofile(L, "test.lua");
  lua_settop(L, index);
  lua_getglobal(L, "coroutine");
  lua_pushstring(L, "create");
  lua_gettable(L, -2);
  lua_getglobal(L, "co_func");
  lua_call(L, 1, 1);
  co = lua_tothread(L, -1);
  lua_setglobal(L, "co");
  index = lua_gettop(L);
  for (i = 0; i < 4; i++) {
  lua_pushnumber(co, i);
  printf("c: resume=%d\n", lua_resume(co, 1));
  printf("c: co top=%d, L top=%d\n", lua_gettop(co), lua_gettop(L));
  printf("c: co result1=%lf\n", lua_tonumber(co, -2));
  printf("c: co result2=%lf\n", lua_tonumber(co, -1));
  }
  lua_close(L);
  return 0;
}
0247続きNGNG
test.lua:
function co_func(arg)
  i = 100
  print("co_func: start")
  while 1 do
    print("co_func: arg=", arg, " i=", i)
    i = i + arg
    arg = coroutine.yield(i, arg)
  end
end
0248デフォルトの名無しさんNGNG
>>246
こんな感じでもOK

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main(int argc, char **argv) {
  int i;
  lua_State *L, *co;
  L = lua_open();
  lua_baselibopen(L);
  lua_dofile(L, "test.lua");
  co = lua_newthread(L);
  lua_getglobal(co, "co_func");
  for (i = 0; i < 4; i++) {
lua_pushnumber(co, i);
    printf("c: resume=%d\n", lua_resume(co, 1));
    printf("c: co result1=%lf\n", lua_tonumber(co, -2));
    printf("c: co result2=%lf\n", lua_tonumber(co, -1));
  }
  lua_close(L);
  return 0;
}
0249デフォルトの名無しさんNGNG
>>246
うお神降臨!さっそく試してみます。ところでlua_closethreadって実装されて
なさげなのですが、任意のスレッドを開放するにはどうすればいいんでしょうね?
lua_close使うとエラー 出るし。マニュアルにはちゃんとあるんだけどなー。

>>245
Lua5.0b file:llex.c line:317に次レスを追加。//と/**/が普通に使えるようになります。
きちんとデバッグしてないので自己責任でどーぞ。#も似たような感じで。
ちなみに漏れはlua_commentblock( "//" , "/*" , "*/" )で自由にカスタムできるよう
にしてます。あと、--コメントを消し去りたいのならその次のブロックをコメントアウト。
 Cスコープ{}にあわせる方法はLuaを弄る訳ではなくプリプロセスを通してLua
コードに変換するだけなので汎用性はあるけど、ちょっと微妙。スマヌ。
0250デフォルトの名無しさんNGNG
case '/': {
next(LS);
if (LS->current != '/' && LS->current != '*' ) return '/';
/* else is a comment */
//long comment
if (LS->current == '*'){
while (1){
if( LS->current == '*' ){
next(LS);
if( LS->current == '/' ){
next(LS);
break;
}
continue;
}
if ( LS->current == EOZ) break;
next(LS);
}
continue;
}

//short comment
next(LS);
while (LS->current != '\n' && LS->current != EOZ){
next(LS);
}
continue;
}
0251デフォルトの名無しさんNGNG
あー、見直したらいきなりバグあるわ…。/*/がコメントとして扱えちゃう。
上の7行目(if (LS->current == '*'){の次)に
next(LS);
を追加しといてちょ。
0252デフォルトの名無しさんNGNG
声にならぬ
0253デフォルトの名無しさんNGNG
>>245
たとえ改変OKでも、言語仕様を変えてしまうのはどうかと思う。
0254デフォルトの名無しさんNGNG
べつに
0255デフォルトの名無しさんNGNG
>>249
>ところでlua_closethreadって実装されて

GCに引っ掛けると開放されるのかな?
というか、変数参照されたスレッドをクローズしちゃうとかなりやばそう。
0256デフォルトの名無しさんNGNG
 うーん、なんかLuaのメモリ管理ってガベコレしてるのか知らんけど、
すんげー量の未使用メモリが残るのな。開放のタイミングも全然良く解か
らんし、こりゃメモリリソースがキツい環境じゃ使用がためらわれるな。
断片化怖いしな。
0257デフォルトの名無しさんNGNG
でも、その割にはゲームとか組み込みとかリソースの厳しいアプリが多い様な
0258デフォルトの名無しさんNGNG
>>256
そりゃダメダメだな。
採用しようかと思ってたが、見送ることにするよ。
0259デフォルトの名無しさんNGNG
コメントは、漏れも#に変えて(ソース変えて)使ってる。
ただ、MLの感じでは5.1あたりから#もコメントとして認識される方向のようだね。
0260デフォルトの名無しさんNGNG
Cプログラムからのアクセスの仕方がよくわからないです。
わかりやすく説明してほしいなぁ。
0261デフォルトの名無しさんNGNG
どのへんが分からんの?
0262デフォルトの名無しさんNGNG
>>261

>>248の例だと、
co = lua_newthread(L); ここで"test.lua"の実行環境整えて、
lua_getglobal(co, "co_func"); co_funcを探して、
lua_pushnumber(co, i); co_funcに引数わたして、
printf("c: resume=%d\n", lua_resume(co, 1)); co_funcがyieldを実行するまで待って、
printf("c: co result1=%lf\n", lua_tonumber(co, -2)); スタックから結果を取り出す。
って感じで理解できるんだけど、

>>246の例では、getglobalとかgettable,settop等が何をやっているのかわかりません。
0263262NGNG
あと、
>>248の例で、co_funcがどのタイミングで実行されるのかもわかりません。
0264デフォルトの名無しさんNGNG
>>262
あー、coroutine, thread関係はとりあえず忘れたほうがいいかも?
5.0の新機能だし。

>>246のforの前まではLuaで書くと、以下の文と同様のことをしてる。

 co = coroutine.create(co_func)

(1)lua_getglobal(L, "coroutine");
 グローバル変数"coroutine"をスタックのトップに積む
 ちなみにこいつはテーブルだ。

(2)lua_pushstring(L, "create");
 文字列"create"をスタックのトップに積む

(3)lua_gettable(L, -2);
 スタックのトップから2番目の要素((1)のcoroutineのこと。テーブルである必要がある。)から、
 スタックのトップに積んである文字列("create")で示されるメンバをスタックに積む。
 このとき、スタックのトップはpopされる。
 ちなみに、createメンバは関数なので、その関数がスタックのトップに詰まれる。
 こいつは、(4)で使われる。

(3)lua_getglobal(L, "co_func");
 test.luaで定義された関数co_funcをスタックのトップに積む。

続く...
0265続きNGNG
(4)lua_call(L, 1, 1);
 関数コール: 引数が(3)のco_funcで、呼ぶ関数が(2)のcreate。
 ちなみに、lua_call(L, m, n)と呼ぶときは、スタックは以下のようになってなければならない。
  stack: ... [関数] [引数1] [引数2] ... [引数n] <- ここがスタックのトップ
 で、呼ばれるとスタックはこうなってる↓。
  stack: ... [戻り値1] [戻り値2] ... [戻り値m] <- ここがスタックのトップ
 つまり、(4)は、
  [関数"create"] [関数:"co_func"] -> [createの戻り値(スレッド)]
 となるわけだ。

(5) co = lua_tothread(L, -1);
  lua_setglobal(L, "co");
 スタックのトップから値をスレッド型でとってきてそれをグローバル変数"co"に設定する。

こんなんで分かるかな?スタックの状態を想像しながら読んでくれ。
coroutineのことは置いといて、LuaをCから使うための基本は大体入ってるような
気がする(グローバル変数の操作、テーブルの操作、Luaの関数呼び出し)。 
あとは、indexの指定の仕方とかどの関数で何がpushされて何がpopされるかが
分かれば大体作れると思うんだけど。

ちなみにcoroutineは、lua_baselibopen(L)を呼んだときに定義されます(ハズ)。
0266デフォルトの名無しさんNGNG
あ、ごめん。nとmが逆だ。
× ちなみに、lua_call(L, m, n)と呼ぶときは、スタックは以下のようになってなければならない。
○ ちなみに、lua_call(L, n, m)と呼ぶときは、スタックは以下のようになってなければならない。
0267デフォルトの名無しさんNGNG
>>263
関数が呼ばれるのは、lua_resumeが呼ばれたとき。
lua_resumeは、スレッドのスタックの一番下(index=1)に積んである関数を
呼ぶ(もしくはyieldで中断された実行を再開する)関数ね(多分)。
lua_resumeに指定するのはLじゃなくてスレッドオブジェクトだということに注意。

で、>>248>>246
co = coroutine.create(co_func)
for i = 0, 3 do
  r1, r2 = coroutine.resume(co, i)
  print("main:", r1)
  print("main:", r2)
end
と動作的には同じ事をしてる(厳密に同じわけじゃないけど)。
test.luaのこいつを書き加えれば同じように動くよ。
0268デフォルトの名無しさんNGNG
C の continue 相当ってどう書いてる?
0269デフォルトの名無しさんNGNG
>>264-267
coroutine.createってcoroutine["create"]って感じですね。
すごくわかりやすくて、Luaを組み込めるようになりそうです。
どうもありがとうございます。
0270デフォルトの名無しさんNGNG
マニュアルの日本語訳ってどこ行っちゃったの?
http://216.239.53.100/search?q=cache:www.etl.go.jp/etl/divisions/~ueno/lua/manual4jp.html
0271デフォルトの名無しさんNGNG
こっちに移ったみたい
http://staff.aist.go.jp/yutaka.ueno/lua/manual4jp.html
0272デフォルトの名無しさんNGNG
おお!サンクス。
こっちは最後まであるんだね。
これまで、googleのキャッシュをローカルに保存してみてたので、
ちゃんとしたのがあるのは嬉しいなぁ。
0273デフォルトの名無しさんNGNG
そういえば、Lua4.0とLua5.0bのC言語APIは微妙に違うんだよね。
ちょっとだけ混乱したよ。
0274デフォルトの名無しさんNGNG
table.function(a, b, c)

table:function(a, b, c)
は逆にして欲しかった。
もしくは、JavaScriptみたいにselfを暗黙のローカル変数にするか。
0275デフォルトの名無しさんNGNG
変えたいなら、さっさと修正すりゃいいじゃん。
0276デフォルトの名無しさんNGNG
仕様といえば、複数値がかえせるのに
それを一挙に代入しようとすると、扱いが変わってしまうとき
があるようなので、ちょっと萎えた。
0277デフォルトの名無しさんNGNG
そうなんだっけ?
例えばどんな場合か書いてもらえると嬉しい。
0278デフォルトの名無しさんNGNG
たとえば、
x,y=2,3
ならお望み通り

しかし、aho(0)->4,5 と返す関数があったとして、
x,y,z=aho(0),6
としてみて!
0279デフォルトの名無しさんNGNG
>>278
たとえば
A, B, C を集合とするとき <a,b>∈A×B, c∈C に対して
<x,y,z> = <<a,b>, c> で x=a ∧ y=b ∧ z=c を期待すべきか?
まあ、確かにそうかも知れない。

しかし、
x,y,z = 1,2 ; x == 1 and y == 2 and z == nil
が成り立つ世界でもそれは妥当か?
0280デフォルトの名無しさんNGNG
で、
function a()
  return 1, 2
end
x, y, z = 0, a()
とすると、
x=0, y=1, z=2
なんだよね。

確かに一貫性がないように見えるね。
リスト中に多値を返す関数がある場合は、
・リストが展開される
・常に戻り値が一つに丸められる
のどちらかに統一した方が仕様的には美しいかも?まぁ、好みの問題か。
(ただ、前者だと関数がいくつ値を返すかによってプログラムの動作が
異なってしまうので好ましくない。)

ちなみにこの辺の動作は、マニュアルの「Calling Functions」の項に
それとなく書かれてる。
0281280NGNG
うそ。
×「Calling Functions」の項
○「Function Calls」の項
http://staff.aist.go.jp/yutaka.ueno/lua/manual4jp.html#SECTION00045800000000000000
0282デフォルトの名無しさんNGNG
print((function()end)()) と a=(function()end)(); print(a) が違うのは気持ち悪い
0283280NGNG
>>282
ん?自然だと思うが?
0284デフォルトの名無しさんNGNG
>>282
L
ua 4.0 Copyright (C) 1994-2000 TeCGraf, PUC-Rio
>
> print((function()end)())
error: `)' expected;
last token read: `(' at line 1 in string "print((function()end)()) "
>
なんか実行できねーんですけど。
このインタプリタなんかおかしい?
0285デフォルトの名無しさんNGNG
> a=(function()end)(); print(a)
error: <statement> expected;
last token read: `(' at line 1 in string "a=(function()end)(); print(a) "

なんなの、これ。
一つも実行できねえ。
全然駄目だ・・
■ このスレッドは過去ログ倉庫に格納されています