LoginSignup
10
10

More than 5 years have passed since last update.

Lua言語をざっとペロる(for ComputerCraft)

Last updated at Posted at 2016-02-06

前提とまえがき

ComputerCraft1.78 の lua のバージョンを調べてみたら 5.1 だった。公式では 5.2っぽいことが書いてあったけどどうなんだろ。後日調査する。ちなみ僕がやった調べ方として、コンピュータのコンソールを開き、lua と入力するとインタラクティブモードになる。

インタラクティブモードでのプロンプトでは、print(_VERSION) と入力するとバージョンは表示される

スクリーンショット 2016-02-06 21.14.53.png

インタラクティブモードを抜けるには 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()

ざっとこんな感じで、タートルちゃんをある程度自由に動かせるはず。記事はちょいちょい更新する。

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10