前提とまえがき
ComputerCraft1.78 の lua のバージョンを調べてみたら 5.1 だった。公式では 5.2っぽいことが書いてあったけどどうなんだろ。後日調査する。ちなみ僕がやった調べ方として、コンピュータのコンソールを開き、lua
と入力するとインタラクティブモードになる。
インタラクティブモードでのプロンプトでは、print(_VERSION)
と入力するとバージョンは表示される
インタラクティブモードを抜けるには exit()
で。
5.1のリファレンス:Lua 5.1 Reference Manual
ちなみにこの記事はCCがそのうち 5.2 になるということで Mac OS X Yosemite に 5.2 を突っ込んでソースを動かした後にサンプルソースとして書くようにしています。
HelloWorld
行末にセミコロンがいらないデザインになってる
print("HelloWorld")
コメント
ハイフン2つで行コメントが開始
-- コメント
複数行のコメントは --[[ と --]] を使うよ
--[[
1. foo
2. bar
3. baz
--]]
変数
RubyやPHP同様宣言無しで扱える
foo = 'bar'
スコープ
関数でスコープが区切られてるわけではないので(レキシカルスコープってやつかな)、関数内でローカルな変数を扱う場合は local を使う
function foo()
bar = 'baz'
end
print(bar) --> baz
funcion foo()
local bar = 'baz'
end
print(bar) --> nil
型
type()
で調べられる。この記事では userdata型 と thread型 は扱わない
a = nil
b = 1
c = 'str'
d = true
e = function() end
f = {1, 2, 3}
--> 自作のクラスっぽいの(JSに似てる
G = {}
G.new = function(name, age)
local obj = {}
obj.name = name
obj.age = age
obj.show = function()
print('name:'..obj.name..' age:'..obj.age)
end
return obj
end
g = G.new('chrowa3', 20)
g.show() --> name:chrowa3 age:20
print(type(a)) --> nil
print(type(b)) --> number
print(type(c)) --> string
print(type(d)) --> boolean
print(type(e)) --> function
print(type(f)) --> table
print(type(g)) --> table
算術演算子
演算子 | 説明 | 例 |
---|---|---|
+ | 加算 | 1 + 1 |
- | 減算 | 1 - 1 |
* | 乗算 | 1 * 1 |
/ | 除算 | 1 / 1 |
% | 余剰 | 1 % 1 |
^ | 冪乗 | 1 ^ 1 |
lua にはイクリメント、デクリメントがないので ++ や -- は使えない。ってことで
i = i + 1
--だの
i = i - 1
-- だの
i = i * 2
だので対応
文字列
リテラルはシングルクォート、ダブルクォートで括る
foo = "bar"
bar = 'baz'
文字列結合
ピリオド2つでつなげる
foo = 'Hello'
bar = 'World'
print(foo..bar) --> HelloWorld
配列っぽいの(正しくはテーブル
arr = {1, 2, 3}
要素数
table.maxn() で取得できる
arr = {1, 2, 3}
length = table.maxn(arr)
print(length)
インデックスは 1 から
arr = {1, 2, 3}
print(arr[0]) --> nil
print(arr[1]) --> 1
テーブルは可変長配列
arr = {1 ,2, 3}
arr[4] = 4
print(table.maxn(arr))
テーブルへは参照が格納
arr = {1, 2, 3}
print(arr) --> 0x7fb922409210
代入すると参照がコピーされるので副作用がある
foo = {1, 2, 3}
bar = foo
bar[1] = 10
print(foo[1]) --> 10
要素を末尾に追加 table.insert
arr = {1, 2, 3}
table.insert(arr, 4)
print(arr[4]) --> 4
第二引数でインデックスを指定すれば任意の場所に挿入可能
arr = {1, 2, 3}
table.insert(arr, 1, 0) --> 第二引数は挿入先のインデックス
print(arr[1]) --> 0
print(arr[4]) --> 3
print(table.maxn(arr)) --> 4
要素を末尾から取り出す table.remove
arr = {1, 2, 3}
last = table.remove(arr)
print(last) --> 3
print(table.maxn(arr)) --> 2
第二引数でインデックスを指定すれば任意の要素を取り出せる
arr = {1, 2, 3}
ele = table.remove(arr, 1)
print(ele) --> 1
print(table.maxn(arr)) --> 2
連想配列(正しくはテーブル
hash = {foo = 1, bar = 2, baz =3}
print(hash['foo']) --> 1
print(hash['bar']) --> 2
print(hash['baz']) --> 3
キーが文字列ならばドットシンタックスで参照可能
hash = {foo = 1, bar = 2, baz =3}
print(hash.foo)
print(hash.bar)
print(hash.baz)
制御文
まず条件演算子、論理演算子に触れ、if文、for文、while文にだけ触れておく
条件演算子
演算子 | 説明 | 例(true |
---|---|---|
> | 左辺が大きければtrue | 2 > 1 |
< | 右辺が大きければtrue | 1 < 2 |
>= | 左辺が右辺以上ならばtrue | 2 >= 1 |
<= | 右辺が左辺以上ならばtrue | 1 <= 2 |
== | 同値 | 1 == 1 |
~= | 異なる | 1 != 2 |
論理演算子
演算子 | 説明 | 例(true |
---|---|---|
and | 【且つ】 JS の && にあたる。 | foo and bar |
or | 【または】 JS の || にあたる | foo or bar |
not | 【ではない】 JS の ! にあたる | ! foo |
if文
else 以外には then を、if文の終了には end を書き、elseif とつなげるデザイン。
if - else
foo = true
if foo then
print('foo is true.')
else
print('foo is false.')
end
--> foo is true
elseif
foo = true
bar = false
if foo and bar then
print('foo is true.')
elseif foo and not bar then
print('foo is true. bar is false')
end
--> foo is true. bar is false
for文
特徴的なのは、終了は「条件」でなく「値」。
for 初期値, 終了値, 増加量 do
-- なんらかの処理
end
たとえば
for i = 0, 5, 1 do
print(i)
end
では
0
1
2
3
4
5
と表示される。テーブルをループさせる場合、
arr = {'foo', 'bar', 'baz'}
len = table.maxn(arr)
for i = 1, len, 1 do
print(arr[i])
end
--> foo
--> bar
--> baz
てな感じで。
while
無限ループ
while true do
--> infinite loop
end
ループから抜けるには break
を使う。breakは end の直前でしか使えないらしい。
while true do
print('hoge')
break
end
--> hoge
ちなみに continue
的なものは無いみたい。if文を駆使しましょう。
関数
定義
関数は function 〜 end
で定義する。
function foo()
--> 何らかの処理
end
呼び出しは定義後にする必要がある。Cみたい。
function hoge()
print('hoge called.')
end
hoge() --> hoge called.
定義前に呼び出すとエラー
hoge()
function hoge()
print('hoge called.')
end
lua: FunctionTest.lua:1: attempt to call global 'hoge' (a nil value)
stack traceback:
HelloWorld.lua:1: in main chunk
[C]: in ?
戻り値
return
で返す。break 同様 end の直前にある必要がある。
function foo()
return 'bar'
end
print(foo()) --> bar
引数
function twice(num)
num = num * 2
return num
end
print(twice(2))
可変長引数
function foo(...)
arg = {...}
len = table.maxn(arg)
print(len) --> 5
end
foo(1,2,3,4,5)
多値を戻す場合、return にカンマ区切りで返し、受け取り側で返ってきた分の変数を用意して扱う。
function foo()
return 1,2,3,4,5
end
a,b,c,d,e = foo()
print(e)
とはいっても素直にテーブルで返した方がよさげ。
function foo()
return {1,2,3,4,5}
end
bar = foo()
print(type(bar)) --> table
print(table.maxn(bar)) --> 5
プロトタイプちゃん
さっきも書いたけど一応。テーブルとlocalスコープがわからないとちんぷんかんぷんになると思う。
Profile = {}
Profile.new = function(name, age)
local obj = {}
obj.name = name
obj.age = age
obj.show = function()
print('name:'..obj.name..' age:'..obj.age)
end
return obj
end
chrowa3 = Profile.new('chrowa3', 20) --> name:chrowa3 age:20
chrowa4 = Profile.new('chrowa4', 30) --> name:chrowa4 age:30
chrowa3.show()
chrowa4.show()
ざっとこんな感じで、タートルちゃんをある程度自由に動かせるはず。記事はちょいちょい更新する。