루아 p.17 - 조합형 인스턴스

루아 스크립트를 작성할 때 비슷한 이름을 가지고 있는 인스턴스들은 문자열을 조합해서 참조할 수 있는 방법이 있습니다. 다음 예제는 일반적으로 작성하는 방법을 다시 인스턴스 명을 조합해서 사용한 예제입니다.

  • 예제1

    local val1 = 0;
    local val2 = 0;
    local val3 = 0;

    val1 = 10;
    val2 = 20;
    val3 = 30;

  • 예제2

    local val1 = 0;
    local val2 = 0;
    local val3 = 0;

    for i = 1, 5 do
        _G[ "val" .. i ] = i * 10;
    end

이 방법은 변수 뿐만 아니라 함수도 마찬가지 방법으로 호출이 가능합니다.

  • 예제3

    function Func1()
        print( "Function 1");
    end

    function Func2()
        print( "Function 2");
    end

    function Func3()
        print( "Function 3");
    end


    function main()
        for i = 1, 5 do
            _G[ "Func" .. i ]();
        end
    end

루아 p.16 - 테이블 요소를 인자로 변환

루아 스크립트를 작성하다보면 테이블의 요소들을 인자로 넘겨줘야 하는 일이 간혹 발생합니다. 예를 들면 다음과 같은 경우입니다.

  • 예제1

    function main()
        local vector = { 12.9, 42.5, 9.3 };
        lcoal x = vector[ 1];
        lcoal y = vector[ 2];
        lcoal z = vector[ 3];

        print( "x = " .. x .. ", y = " .. y .. ", z = " .. z);
    end

위 예제는 unpack 함수를 사용하여 다음 예제와 같이 테이블의 요소를 각각의 인자에 대입시킬 수 있습니다.

  • 예제2

    function main()
        local vector = { 12.9, 42.5, 9.3 };
        lcoal x, y, z = unpack( vector);

        print( "x = " .. x .. ", y = " .. y .. ", z = " .. z);
    end

unpack은 다음과 같이 함수 인자로 전달할때도 유용하게 사용할 수 있습니다.

  • 예제3

    function SetVector( x, y, z)
        print( "x = " .. x .. ", y = " .. y .. ", z = " .. z);
    end

    function main()
        local vector = { 12.9, 42.5, 9.3 };
        SetVector( unpack( vector) );
    end

루아 p.15 - 함수 콜백(Callback)

루아에서도 함수 콜백(Callback)을 사용할 수 있습니다. 다음 예제를 통해서 살펴보도록 합시다.

  • 예제

    -- MyClass
    MyClass = {};

    function MyClass:TestOutput()
        print( "Hello world.");
    end


    -- NewMyClass
    NewMyClass = {};

    NewMyClass.m_cbFunc = nil;

    function NewMyClass:SetCallback( cbFunc)
        NewMyClass.m_cbFunc = cbFunc;
    end

    function NewMyClass:RunCallback()
        NewMyClass:m_cbFunc();
    end


    -- main
    function main()
        NewMyClass:SetCallback( MyClass.TestOutput);
        NewMyClass:RunCallback();
    end

루아 p.14 - 루아 테이블 상속

루아 테이블에는 기본적으로 상속 기능은 없습니다만, C언어의 클래스 상속과 비슷한 기능을 흉내낼 수는 있습니다. 다음 예제를 통해서 살펴보도록 합니다.

  • C언어

    // MyClass
    class MyClass
    {
    private:
        string m_strName;
        int m_nAge;

    public:
        virtual void SetName( string& strName) = 0;
        virtual void SetAge( int nAge) = 0;
    };


    // NewMyClass
    class NewMyClass : public MyClass
    {
    public:
        virtual void SetName( string& strName);
        virtual void SetAge( int nAge);
    };

    void NewMyClass::SetName( string& strName)
    {
        m_strName = strName;
    }

    void NewMyClass::SetAge( int nAge)
    {
        m_nAge = nAge;
    }

  • 루아

    -- MyClass
    MyClass = {};

    MyClass.m_strName = "";
    MyClass.m_nAge = 0;

    function MyClass:new()
        instance = {};
        setmetatable( instance, self);
        self.__index = self;
        return instance;
    end

    function MyClass:SetName( strName)
    end

    function MyClass:SetAge( nAge)
    end


    -- NewMyClass
    NewMyClass = MyClass:new();

    function NewMyClass:SetName( strName)
        MyClass.m_strName = strName;
    end

    function NewMyClass:SetAge( nAge)
        MyClass.m_nAge = nAge;
    end

위 예제처럼 부모 테이블에 새 인스턴스를 생성해서 반환해주는 new 함수를 만들고, 새 테이블을 생성할 때 이 함수를 호출함으로써 부모의 기능을 상속 받습니다. 또한, 부모의 함수를 다시 정의하면 함수 오버라이딩(overriding)이 가능합니다.

루아 p.13 - 클래스 만들기

루아에는 C언어와 같은 클래스 개념이 없습니다. 하지만, 테이블을 이용하여 비슷한 역할과 기능으로 동작시키는건 가능합니다. 이미 테이블에 관해서 익혀왔다면 어느정도 짐작은 하셨겠지요.

다음의 두 예제를 보면서 구조를 살펴보도록 하겠습니다. 먼저 첫번째 예제는 C언어로 만들어본 클래스이고, 두번째 예제는 루아로 다시 구현해본 예제입니다.

  • C언어

    class MyClass
    {
    private:
        string m_strName;
        int m_nAge;

    public:
        void SetName( string& strName);
        string& GetName();

        void SetAge( int nAge);
        int GetAge();
    };


    void MyClass::SetName( string& strName)
    {
        m_strName = strName;
    }

    string& MyClass::GetName()
    {
        return m_strName;
    }

    void MyClass::SetAge( int nAge)
    {
        m_nAge = nAge;
    }

    int MyClass::GetAge()
    {
        return m_nAge;
    }

  • 루아

    MyClass = {};

    MyClass.m_strName = "";
    MyClass.m_nAge = 0;

    function MyClass:SetName( strName)
        MyClass.m_strName = strName;
    end

    function MyClass:GetName()
        return MyClass.m_strName;
    end

    function MyClass:SetAge( nAge)
        MyClass.m_nAge = nAge;
    end

    function MyClass:GetAge()
        return MyClass.m_nAge;
    end

위처럼 테이블로써 메소드와 변수를 묶으면 객체를 생성하고 관리하기 편하며, 생성한 테이블에 단순히 nil을 입력해주는 것만으로 그 객체를 삭제할 수 있다는 점에서 매우 중요합니다.