Menu
Coddy logo textTech

객체 연결하기

Coddy Lua 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 70개 중 28번째.

Lua의 .. 연산자는 문자열을 연결하지만, 객체를 문자열과 결합하고 싶다면 어떻게 해야 할까요? __concat 메타메소드를 사용하면 이것이 어떻게 작동해야 하는지 정확하게 정의할 수 있습니다.

Lua가 a .. b를 만나고 한 피연산자에 __concat 메타메서드가 있으면, 두 값을 인자로 하여 해당 함수를 호출합니다. 이는 객체가 문자열 표현식에 자연스럽게 어우러지도록 하고 싶을 때 유용합니다.

local Name = {}
Name.__index = Name

function Name:new(first, last)
    local obj = {first = first, last = last}
    setmetatable(obj, Name)
    return obj
end

function Name.__concat(a, b)
    if type(a) == "string" then
        return a .. b.first .. " " .. b.last
    else
        return a.first .. " " .. a.last .. b
    end
end

함수가 어떤 피연산자가 문자열인지 확인하는 점에 유의하세요. .."Hello " .. obj 또는 obj .. "!"와 같이 사용될 수 있으므로, 메타메소드는 두 경우를 모두 처리해야 합니다.

local person = Name:new("Ada", "Lovelace")

print("Dr. " .. person)      -- 출력: Dr. Ada Lovelace
print(person .. " PhD")      -- 출력: Ada Lovelace PhD

다른 연산자 메타메서드와 마찬가지로, __concat은 점 구문을 사용하며 두 피연산자를 인자로 받습니다. 산술 메타메서드와의 주요 차이점은 일반적으로 객체와 문자열이라는 혼합된 타입을 다루게 된다는 점입니다.

challenge icon

챌린지

쉬움

.. 연산자를 사용하여 문자열 표현식에 자연스럽게 녹아들 수 있는 Title 클래스를 만들어 보겠습니다. 이는 경칭이나 접미사를 사람의 직함에 추가하는 것과 같이, 객체를 문자열과 읽기 쉽고 직관적인 방식으로 결합하고 싶을 때 유용합니다.

코드는 두 개의 파일로 구성됩니다:

  • Title.lua: 타이틀 문자열을 저장하는 text 필드를 가진 Title 클래스를 정의합니다. :new(text) 생성자를 포함하고 __concat 메타메소드를 구현하세요. 메타메소드는 객체 앞에 문자열이 오는 경우("prefix" .. obj)와 객체 뒤에 문자열이 오는 경우(obj .. "suffix")의 두 가지 케이스를 모두 처리해야 합니다. 결과는 문자열과 타이틀의 텍스트를 적절하게 결합해야 합니다.
  • main.lua: Title 모듈을 불러오고(require), 타이틀 인스턴스를 생성한 다음, 양방향에서의 연결(concatenation)을 보여줍니다.

세 개의 입력을 받게 됩니다:

  1. 타이틀 텍스트 (예: "Engineer")
  2. 타이틀 앞에 붙일 접두사 문자열 (예: "Senior ")
  3. 타이틀 뒤에 붙일 접미사 문자열 (예: " III")

메인 파일에서 주어진 텍스트로 Title을 생성하세요. 그런 다음 두 번의 연결을 수행하고 각 결과를 별도의 줄에 출력하세요:

  1. 접두사 문자열과 타이틀 객체를 연결합니다.
  2. 타이틀 객체와 접미사 문자열을 연결합니다.

예를 들어, 입력값이 Engineer, Senior , III인 경우 출력은 다음과 같아야 합니다:

Senior Engineer
Engineer III

첫 번째 줄은 접두사와 타이틀이 결합된 것을 보여주고, 두 번째 줄은 타이틀과 접미사가 결합된 것을 보여줍니다. 여러분이 만든 __concat 메타메소드가 이러한 자연스러운 문자열 결합을 가능하게 합니다!

치트 시트

__concat 메타메소드를 사용하면 객체로 작업할 때 .. 연결 연산자에 대한 사용자 정의 동작을 정의할 수 있습니다.

Lua가 a .. b를 만나고 한 피연산자에 __concat 메타메소드가 있으면, 두 값을 인자로 하여 해당 함수를 호출합니다.

기본 구현

local MyClass = {}
MyClass.__index = MyClass

function MyClass:new(value)
    local obj = {value = value}
    setmetatable(obj, MyClass)
    return obj
end

function MyClass.__concat(a, b)
    if type(a) == "string" then
        return a .. b.value
    else
        return a.value .. b
    end
end

양쪽 피연산자 순서 처리

.."string" .. obj 또는 obj .. "string"과 같이 사용될 수 있으므로, 메타메소드는 어떤 피연산자가 문자열인지 확인하고 두 경우를 모두 처리해야 합니다:

function Name.__concat(a, b)
    if type(a) == "string" then
        return a .. b.first .. " " .. b.last
    else
        return a.first .. " " .. a.last .. b
    end
end

사용 예시

local person = Name:new("Ada", "Lovelace")

print("Dr. " .. person)      -- 출력: Dr. Ada Lovelace
print(person .. " PhD")      -- 출력: Ada Lovelace PhD

다른 연산자 메타메소드와 마찬가지로, __concat은 점(dot) 구문을 사용하며 두 피연산자를 인자로 받습니다.

직접 해보기

-- 입력 읽기
local titleText = io.read()
local prefix = io.read()
local suffix = io.read()

-- Title 모듈 불러오기
local Title = require('Title')

-- TODO: 주어진 titleText로 Title 인스턴스 생성

-- TODO: prefix를 title 객체와 연결하고 결과 출력

-- TODO: title 객체를 suffix와 연결하고 결과 출력
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Object Oriented Programming의 모든 레슨