トップ » 技術記事 » 高速スクリプト言語「Lua」を始めよう!(2) - 高速スクリプト言語「Lua」を始めよう!(2)

高速スクリプト言語「Lua」を始めよう!(2) - 高速スクリプト言語「Lua」を始めよう!(2)

タグ: Lua

本稿では動作速度が高速で、非常に移植性が高い組み込み向けのプログラミング言語「Lua」の使い方について紹介します。Lua は、JavaScript や Pascal に似ていることから、とても手に馴染みやすいのが特徴です。自作アプリケーションにちょっとしたスクリプト言語を組み込みたい場合に重宝します。そこで、Lua のインストールから、簡単な使い方を紹介し、簡単なアプリケーションに組み込んで使うまでの過程を解説します。

本稿の目標

本稿では、Lua がどんなプログラミング言語なのかを紹介し、実際に簡単なアプリケーションに組み込んで使ってみるところまでを紹介します。

前回(第一回目)は、Lua とは何か、そして、どんな風にプログラムを書くのかを紹介しました。今回(第二回目)は、Lua の便利な機能を紹介します。

前回の補足

前回、Hello World や偶数奇数の判定や、素数の表示など基本的なプログラムを作って、Lua のプログラムの雰囲気をつかんでみました。さっそくプログラムを作っていきたいところですが、前回紹介しなかった基本的な事柄をまとめてみようと思います。

コメントについて

前回、– が一行コメントを表すということを紹介しました。それでは、複数行にわたるコメントはどう書くのかというと、次のように –[[ .. ]] のように書きます。

-- 一行コメント
-- [[
ここが
複数行のコメント
です!
]]
文字列の表し方

これと関連して、文字列を表す場合に、一般的なプログラミング言語の "文字列" の他に、角カッコを重ねて、[[文字列]] のように書くこともできます。

もちろん、[[..]] の間には、改行を挟むこともできます。

print [[
こんにちは。
今日は爽快な風が吹く
秋の良い日でした!
]]

一般的なダブルクォート(" .. ")の文字列中には、エスケープ記号(改行記号の\n や ダブルクォート \" )も記述することができますが、[[..]]の文字列では、エスケープ記号が展開されないので注意が必要です。

また、[[ .. ]] の中で、[[ を記述したい場合のために、[==[ .. ]==] のような不思議な囲み記号を利用して文字列を表現することもできます。

print [==[
こんにちは。
どんなときも
挨拶は重要です。
]==]

Lua で利用できる値の型

それでは、今回扱いたい内容に入っていきます。前回、プログラムを見てある程度分かったことと思いますが、Lua は動的な型言語です。変数は決まった型を持たず、文字列や数値、関数と、さまざまな値を代入させることができます。

Luaで用意されているのは、以下の8つの基本型です。

  • nil
  • ブーリアン(真偽) — boolean
  • 数値 — number
  • 文字列 — string
  • 関数 — function
  • テーブル — table
  • スレッド — thread
  • ユーザーデータ — userdata

nil は C言語の null に当たるもので、初期化していない変数は、値が nil になっています。また、ブーリアン型は、true か false の真偽値を取ります。

これらは、基本関数の type() を使って確認することができます。

i = 50
print(type(i))  -- number
print(type(43)) -- number
s = "abc"
print(type(s))     -- string
print(type("abc")) -- string
v = true
print(type(v))  -- boolean

それでは、1つずつ、それぞれの型の特徴を確認していきましょう。

文字列の操作でみる Lua

Lua で文字列を操作するには、string ライブラリを使います。string ライブラリの利用例として、簡単なものとして、文字列から任意の部分を取り出して表示するものを作ってみます。

-- sub.lua
s = "abcdefg"
n = string.sub(s, 2, 4)
print(n)

string.sub() は、文字列の部分文字列を取り出す関数です。上記のプログラムを実行すると、文字列 s の 2文字目から4文字目までの部分文字列 bcd を抜き出します。

$ lua test.lua
bcd

次に、文字列の文字コードを1文字ずつ表示するプログラムを作ってみます。

-- str_test.lua
s = "abcdefg"

for i=1,string.len(s) do
  ch   = string.sub(s, i, i)
  code = string.byte(s, i, i)
  fmt  = string.format("[%s:%x]",ch,code)
  io.write(fmt)
end

これを実行すると以下のようになります。

$ lua str_test.lua
[a:61][b:62][c:63][d:64][e:65][f:66][g:67]

ここで出てきた string ライブラリの使い方は以下の通りです。

書式 意味
string.sub(s [,i [,j]]) sのiバイト目からjバイト目までを取り出す
string.byte(s [,i [,j]]) sのiバイト目からjバイト目までの内部コードを返す
string.len(s) sのバイト数を返す
string.format(t,e1,e2..) 書式 t に引数e1,e2..を埋め込んで返す
文字列をオブジェクト指向風に扱う方法

そして、Lua が面白いのは、string.XXX のライブラリで、第一引数が文字列のものを、オブジェクト指向風に記述できる点です。

たとえば、string.sub(s, 2,4) をオブジェクト指向風に書くと、s:sub(2,4) のように記述できます。同様にして、string.len("abc") も、s:len() のように記述できます。

それでは、先ほど作ったサンプルをオブジェクト指向風に書き換えてみます。

-- str_test2.lua
s = "abcdefg"
for i=1,s:len(s) do
  ch   = s:sub(i,i)
  code = s:byte(i,i)
  fmt  = "[%s:%x]"
  str  = fmt:format(ch,code)
  io.write(str)
end

どうでしょう!オブジェクト指向風に書くと、とてもすっきりと記述することができます。この辺りが Lua のシンプルながら、使いやすい言語にまとまっているポイントと言える部分かもしれません。

※余談ですが、string.len(s) は、s:len() と書けるほか、長さ演算子の # を使って、#s と書くことができます。

テーブル型について

Lua が JavaScript に似ている部分に、テーブル型が挙げられます。Lua には、配列変数がなく、代わりにテーブル型を利用します。

テーブル型を生成するには、テーブルコンストラクタを利用します。例えば、tbl という名前のテーブルを作るには、以下のように記述します。配列変数のように使う場合、添字は1から始まります。

tbl = {}
tbl[1] = "a"    -- 要素1(先頭)に、"a" を代入
print( tbl[1] ) -- 要素1の値を参照する

そして、テーブルコンストラクタでは、テーブルの初期値を指定することができます。

-- table_test.lua
tbl = {"A","B","C","D"}
print( tbl[1] )
print( tbl[3] )

これを実行すると以下のような結果が得られます。

$ lua table_test.lua
A
C

つまり、tbl = {"A","B","C"} と書くのと以下のように書くのは同じ意味になります。

tbl = {}
tbl[1] = "A"
tbl[2] = "B"
tbl[3] = "C"
連想配列

また、テーブル型は、配列変数のように使えるほかに、連想配列としても利用できます。連想配列とは、キーと値のペアでデータを保存できる機能のことです。言い換えるなら、通常、配列変数は数字を添字にして値を取り出すのですが、連想配列では、キーワードとなる文字列を添字にして値を取り出すことができます。

-- table_test2.lua
age = {}
age["mike"] = 8
age["taro"] = 4
age["poro"] = 3
print(age["taro"])

これを実行すると、4 が表示されます。

もちろん、連想配列もコピーコンストラクタで初期化することができます。上記のプログラムは、下記のように書いても同じ意味になります。コピーコンストラクタを使うと、テーブルの初期化が非常に簡単にできることが分かりますね。

age = {mike=8,taro=4,poro=3}
print(age["taro"])
テーブルコンストラクタって、JSONよりスゴイ!!

よくよく観察してみると、これって、JavaScript の Array や Object の初期化(JSON形式)にそっくりです。JavaScript では、Array と Object が別物なので、Array の初期化を、a = [1,2,3]、Object の初期化を、{mike:8, taro:4, poro:3} と書きますが、Lua では、これを区別しないので、このような簡潔な形で記述できるようになっているのです。

他に、より凝った書き方としては、以下のように配列の要素の番号を指定できるようになっています。

t = {[3] = "c", [1] = "a", [2] = "b"}
print(t[1])
print(t[2])
print(t[3])

これを実行すると、a b c が得られます。

テーブルのキーと値を列挙する

それから、テーブル型の最後に、テーブルの値の一覧を列挙する方法を紹介します。このためには、for .. in と pairs() 関数を利用します。

-- enum.lua
tbl = {miyu=18,sato=25,kumi=20}
for key,val in pairs(tbl) do
  print(key, val)
end

この出力結果は以下のようになります。

$ lua enum.lua
miyu    18
kumi    20
sato    25

まとめ

以上、今回は、文字列について、そしてオブジェクト指向風の書き方ができることについて、また便利なテーブル型について紹介しました。だんだん Lua が分かってくると、Lua の可能性が開けてくる気がしますね。特に、テーブルは非常に便利です。次回は、今回紹介できなかった関数についてと、Lua のもう少し深い部分の文法を掘り下げてみたいと思います。お楽しみに。

Series Navigation«高速スクリプト言語「Lua」を始めよう!(1)高速スクリプト言語「Lua」を始めよう!(3)»

執筆者紹介

クジラ飛行机

クジラ飛行机

くじらはんど(http://kujirahand/)にて、日本語プログラミング言語「なでしこ」(IPA未踏ユース採択)、テキスト音楽「サクラ」(OSPオンラインソフト大賞入賞)など多くのオンラインソフトを開発。著書に「Flexプロフェッショナルガイド」「なでしこ公式バイブル」、「一週間でマスターするActionScript3.0」など。

TrackBack URL :