2017年1月15日日曜日

Migrate svn repository to git remote bare repository

移行対象となるSVNのリポジトリのフォルダ構成は以下の通り。
この内、srcとtestのみを移行対象としたい(他は必要に応じて別プロジェクトとして移行する)。

http://192.168.XXX.XXX/svn/projectA/
trunk/src/*
trunk/test/*
trunk/env/*
trunk/doc/*
・・・
branches/branchXXX/src/*
branches/branchXXX/test/*
branches/branchXXX/env/*
branches/branchXXX/doc/*
・・・
tags/tagXXX/src/*
tags/tagXXX/test/*
tags/tagXXX/env/*
tags/tagXXX/doc/*

2016年3月29日火曜日

Luaのユーザーデータの利用例

C++側で定義したクラス(構造体)をLuaスクリプト側で使用する際には、専用のメモリブロックを利用する必要がある。

主に必要な手続きは以下。
  • void *lua_newuserdata (lua_State *L, size_t size)でユーザーデータ用のメモリブロックを確保
  • 確保したメモリブロック内に、対象クラスのインスタンスを配置
  • Luaスクリプト側に公開するメソッドを__indexメタメソッドへ登録

各ユーザーデータで取り違え(?)が生じないように以下を実施。

識別用のメタテーブルをC++側で設定しておき、Luaスクリプト側へ渡す。
(口述するサンプルコードではメタテーブルに紐づく名前を"person_type"としている)
Luaスクリプト側からユーザーデータを受け取った際(luaL_checkudata呼び出し時)には正しい型か否かを上記メタテーブルを介して検証する。

2016年3月28日月曜日

LuaのC関数側で非ローカルデータを格納する場所

Lua実行環境で非ローカルデータ(呼び出しの外部に存在するデータ)を格納するための場所は、Lua関数/C関数でそれぞれ以下が存在する。

Lua関数
  • グローバル変数
  • 関数の環境
  • 上位値(クロージャー内に保持される非ローカル変数)
C関数
  • レジストリ
  • 環境 ※Lua 5.2より廃止
  • 上位値(クロージャー内に保持される非ローカル変数)

後者のC関数における格納場所に関する覚書。

2016年3月22日火曜日

Luaでクラスの継承

__indexメタメソッドを利用する。

テーブルに対してキー値を参照する場合、
  1. 対象テーブル
  2. 1のテーブルのメタテーブル内の__indexメタメソッドにセットされているテーブル
  3. 2のテーブルのメタテーブル内の__indexメタメソッドにセットされているテーブル
  4. ・・・
の順番に該当キーが見つかるまで探索される。
__indexメタメソッドに基底クラスをセットする事で継承関係を実現出来る。

Luaでコンストラクタ定義

__callメタメソッドを使用する方法


local ClassA = setmetatable({}, {
    __call = function(cls, init)
	local self = {}

	-- localで変数を定義し、
	-- クロージャー経由でアクセスする事でprivate化。
	local private_field = init
	function self.get()
	    return private_field
	end

	return self
    end,
})

instanceA1 = ClassA(10)
instanceA2 = ClassA(20)
print(instanceA1.get())
print(instanceA2.get())

通常のメソッドを使用する方法


local function ClassB(init)
    local self = {}

    -- localで変数を宣言し、
    -- クロージャー経由でアクセスする事でprivate化。
    local private_field = init
    function self.get()
	return private_field
    end

    return self
end

instanceB1 = ClassB(10)
instanceB2 = ClassB(20)
print(instanceB1.get())
print(instanceB2.get())

[参考]

2016年3月21日月曜日

Luaのメタテーブル設定の省略形

テーブル t (以下の例では空)に対してメタテーブル mt を設定する場合は以下となる。

t = {}
setmetatable(t, mt)

上記は以下の省略形で記述可能。
第一引数で指定した空テーブルに対して、メタテーブル mt が設定されたものが、t に設定される。

t = setmetatable({}, mt)

[参考]

2016年3月19日土曜日

Luaの環境

書籍「Programming in Lua」の「14章 環境」を読んでいて、サンプルコード内のsetfenv/getfenvが利用できず躓いていたが、Lua 5.2からAPIが廃止されていた・・・。

Lua 5.2~

Lua 5.2 リファレンスマニュアル」から抜粋。

環境

  • 任意のグローバル変数 var への参照は構文的に _ENV.var に変換される。
  • _ENV は完全に正規の名前であり、同じ名前の変数や引数を定義しても構わない。
  • グローバル変数への参照は、Lua の通常の可視性ルール(レキシカルスコープ)に従い、 プログラムのその地点から見える _ENV が使われる。
  • _ENV の値として使われるテーブルは「環境」と呼ばれる。

グローバル環境

  • Luaには「グローバル環境」と呼ばれる特別な環境が存在し、変数 _G がこの値で初期化される。
  • チャンクをコンパイルすると、 そのチャンクの _ENV の値はグローバル環境で初期化される。そのため、デフォルトでは、 Lua コードのグローバル変数はグローバル環境のエントリを参照する。
  • すべての標準ライブラリはグローバル環境にロードされ、 それらの関数はグローバル環境で実行される。
print(_ENV == _G) -- true

a = 1

local function f(t)
    print(_ENV == _G) -- true
    local print = print
    -- ローカルの_ENVを宣言。参照先は引数で指定されたテーブルとする。
    local _ENV = t
    print(_ENV == _G) -- false
    -- 関数内で宣言された変数はローカルの_ENVに格納される。
    a = 2
    b = 3
end

local t = {}
f(t)
print(a,b)     -- 1   nil
print(t.a,t.b) -- 2   3
仮に「local _ENV = t」をコメントアウトすると、
print(a,b)     -- 2   3
print(t.a,t.b) -- nil nil
となる。

Lua 5.1以前

_ENVが用意されたのはLua 5.2から。
Lua 5.1までは、
getfenv(1)
setfenv(1, table)
を介して該当レベルの環境に対する参照と更新が可能だった。
Lua 5.2からはgetfenv/setfenvのAPIは廃止されている。

[参考]