Modules - kuimoani/defold GitHub Wiki
Modules
Lua ๋ชจ๋์ ์ฌ์ฉํ๋ฉด ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ํ๋ก์ ํธ๋ฅผ ๊ตฌ์กฐํ ํ ์ ์์ต๋๋ค. ์ด ๋ฉ๋ด์ผ์ Defold์์ ์ด๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ค๋ช ํฉ๋๋ค.
์ด ๊ธฐ๋ฅ์ ์ผ๋ฐ์ ์ผ๋ก ํ๋ก์ ํธ์ ์ค๋ณต์ ํผํ๋๋ฐ ์ข์ ์์ด๋์ด์ ๋๋ค. ๊ฐ๊ธฐ ๋ค๋ฅธ ๊ฒ์ ์ค๋ธ์ ํธ๋ฅผ ๋์ผํ๊ฒ ๋์์ํค๊ธฐ ์ํด ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ๋ณต์ฌ ๋ถ์ฌ๋ฃ๊ธฐ๋ก ๋ณต์ ํ ์๋ ์์ง๋ง, ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ๊ฒ์ ์ค๋ธ์ ํธ๊ฐ ๊ณต์ ํด์ ๋จ์ผ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ผ๋ก ๊ฒ์ ์ค๋ธ์ ํธ๋ค์๊ฒ ์ฆ๊ฐ์ ์ผ๋ก ์ํฅ์ ์ฃผ๊ฒ ํ ์ ์์ต๋๋ค.
Defold๋ ๊ณต์ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์คํฌ๋ฆฝํธ ํ์ผ์ ๋ค๋ฅธ ์คํฌ๋ฆฝํธ ํ์ผ์ ํฌํจํ ์ ์๊ฒ ํด ์ค๋๋ค. ๋ํ Lua ๋ชจ๋์ GUI ์คํฌ๋ฆฝํธ ํ์ผ๊ณผ ๊ฒ์ ์ค๋ธ์ ํธ์ ์ฌ์ฌ์ฉ์ ์ํด ์ธ๋ถ ์คํฌ๋ฆฝํธ ํ์ผ์ ๋ฐ์ดํฐ์ ๊ธฐ๋ฅ์ ์บก์ํ ํด์ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
Requiring files
์ฐ๋ฆฌ๊ฐ ์ฌ๋ฌ ์ข ๋ฅ์ ๋๋น๋ฅผ ํน์ง์ผ๋ก ๊ฐ์ง ์ดํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐ์ค์ด๋ผ๊ณ ๊ฐ์ ํด ๋ด ์๋ค. ์ฐ๋ฆฌ๋ ์ด ๋๋น๋ค์ ๋ช๋ช ๋์์ ๋ง๋ค๊ณ ์ด ๋์์ ๊ณต์ ํ๋ ค ํฉ๋๋ค. ์ด ์์ ์ ์ํด์๋ ์ฐ์ ๊ฒ์ ์ค๋ธ์ ํธ์ ์คํฌ๋ฆฝํธ ํ์ผ์ ์์ฑํ๋๋ก ํฉ๋๋ค.

"blue_butterfly.script"์ ์๋ ์ฝ๋๋ฅผ ์ ๋ ฅํฉ๋๋ค:
require "modules_example.flying"
function init(self)
fly_randomly()
end
function on_message(self, message_id, message, sender)
if message_id == hash("fly_randomly_done") then
fly_randomly()
end
end
์ฐ๋ฆฌ๋ fly_randomly() ๋ฅผ init() ์์ ํธ์ถํด์ ๋๋น๋ฅผ ๋๋คํ ์์น๋ก ๋ ์๊ฐ๊ฒ ํ ์๊ฐ์ ๋๋ค. ์ ๋๋ฉ์ด์ ์ด ์๋ฃ๋๋ฉด, "fly_randomly_done" ๋ฉ์ธ์ง๋ฅผ ๋ฐ์์ ๋ ๊ทธ ์ฆ์ ๋๋น๋ฅผ ์ ๋๋ค ์์น๋ก ๋ณด๋ ๋๋ค.
์ฒซ ๋ฒ์งธ ์ค "require modules_example.flying"๋ "modules_example" ํด๋(์ดํ๋ฆฌ์ผ์ด์ ๋ก์ง์ด ์ ์ฅ๋ ์์น์์)์์ "flying.lua" ์คํฌ๋ฆฝํธ ํ์ผ์ ์ฝ์ต๋๋ค.
require ๊ตฌ๋ฌธ์ ํ์ํ ํ์ผ๋ช ์ ๋ฌธ๋ฒ์ ์กฐ๊ธ ํน๋ณํฉ๋๋ค. Lua๋ ํ์ผ๋ช ์ .(์ฉ) ๋ฌธ์๋ฅผ ๊ฒฝ๋ก ๊ตฌ๋ถ์(path separators)๋ก ๋ณ๊ฒฝํฉ๋๋ค. (Mac OS X์ Linux์์ /, Windows์์ )
"flying.lua"์ ์์ฑํ๋ ค๋ฉด ํ๋ก์ ํธ์ ์ Lua Module File์ ์ถ๊ฐํ๊ณ ์ด๋ฆ์ ๋ฐ๊พธ๋ฉด ๋ฉ๋๋ค.


-- ์๋ ์์น๋ฅผ ์ ์ฅํด์ผํจ
local origin
-- ์๋ณธ ์์น์์ "radius" ๊ฑฐ๋ฆฌ๋งํผ ๋๋คํ ์์น๋ก ๋ ๋ ค๋ณด๋
-- ๋ ๋ ค ๋ณด๋ธ ํ "fly_randomly_done" ๋ฉ์ธ์ง๋ฅผ ๋๋๋ ค ๋ณด๋
function fly_randomly(radius)
-- radius ๋ฅผ ์ง์ ํ์ง ์์์ผ๋ฉด 100์ผ๋ก ์
ํ
radius = radius or 100
local go_id = go.get_id()
-- ์๋ ์์น ์ ์ฅ
if origin == nil then
origin = go.get_world_position(go_id)
end
-- ์๋ ์์น์์ "radius" ๊น์ง์ ์ต๋ ๊ฑฐ๋ฆฌ์ ๋๋ค ์์น ์์๋ด๊ธฐ
local rand_angle = math.random(0, 3.141592 * 2)
local rand_radius = math.random(radius)
local offset = vmath.rotate(vmath.quat_rotation_z(rand_angle),
vmath.vector3(rand_radius, 0, 0))
local rand_pos = origin + offset
-- ๋๋ฌด ๋น ๋ฅธ ์ ๋๋ฉ์ด์
์ ๋ฐฉ์งํ๊ธฐ ์ํด radius์ ๋ํด ์ค์ผ์ผ๋ ๋๋ค ์ฌ์์๊ฐ(duration)์ ์
ํ
ํจ
local rand_duration = math.random(radius) / 100 + (radius / 200)
-- ์ ๋๋ฉ์ด์
์ฒ๋ฆฌ, ์๋ฃ ํ์ ๋ฉ์ธ์ง๋ฅผ ๋๋ ค๋ณด๋
go.animate(".", "position", go.PLAYBACK_ONCE_FORWARD,
rand_pos, go.EASING_INOUTSINE, rand_duration, 0.0,
function ()
msg.post("#", "fly_randomly_done")
end)
end
์ด ์ฝ๋๋ ์์ฃผ ์ ๋์ํ๋ฉฐ ๋๋น๋ฅผ ์๋ ์์น(origin) ์ฃผ๋ณ์ผ๋ก ๋๋คํ๊ฒ ์์ง์ด๊ฒ ํฉ๋๋ค. ์ด์ ์ฐ๋ฆฌ๋ ๋ ธ๋์ ๋๋น์ ๊ฒ์ ์ค๋ธ์ ํธ๋ฅผ ์ปฌ๋ ์ ์ ์ถ๊ฐํด ๋ณด๋๋ก ํฉ์๋ค.

๋๋คํ๊ฒ ๋ ์๋ค๋๋ ์ฝ๋๋ ์ด๋ฏธ ์์ผ๋ฏ๋ก, ๋ ธ๋์ ๋๋น์ ์๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ถ๊ฐํด ๋ด ์๋ค.
require "modules_example.flying"
function init(self)
-- ๋
ธ๋ ๋๋น๋ ๋ ๋์ ๋นํ ๋ฐ๊ฒฝ์ ๊ฐ์ง
fly_randomly(200)
end
function on_message(self, message_id, message, sender)
if message_id == hash("fly_randomly_done") then
fly_randomly(200)
end
end
์ฝ๋๋ฅผ ์คํํ๋ฉด ๋ ๋๋น๊ฐ ๋์ผํ ์์ ์ ๊ธฐ์ค์ผ๋ก ๊ฒน์ณ ๋ ์๋ค๋๊ธฐ ์์ํฉ๋๋ค. ์ฌ๊ธฐ์ ์ผ์ด๋๋ ์ผ์ ์ดํดํ๋ ค๋ฉด, Defold๊ฐ Lua contexts๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ค์ ์ดํด๋ณด์๊ธฐ ๋ฐ๋๋๋ค.
์ฌ๊ธฐ์ ํ๋์๊ณผ ๋ ธ๋์ ๋๋น์๊ฒ๋ ๋ ๊ฒ์ ์ค๋ธ์ ํธ๊ฐ ๊ธ๋ก๋ฒ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ฉด์ ์๊ธด ๋ถ์์ฉ์ด ์์์ต๋๋ค. origin ๋ณ์์ ์ ์(definition)๋ถ๋ถ์ ๋ค์ ์ดํด๋ด ์๋ค.
-- ์๋ ์์น๋ฅผ ์ ์ฅํด์ผํจ
local origin
"local"๋ก ์ ์ํ๋ค๋ ๊ฒ์ ํ์ฌ Lua context์ local ์ด๋ผ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ๋ชจ๋ ๊ฒ์ ์ค๋ธ์ ํธ๋ค์ด ๋์ผํ Lua context์์ ํ๊ฐ(evaluate)๋ ํ, ๋ ธ๋์๊ณผ ํ๋์ ๋๋น๋ ์์ ๋์ผํ origin ๋ณ์๋ฅผ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค. ๋๋น ์ค๋ธ์ ํธ ์ค ํ๋๋ ์ด origin ๋ณ์๋ฅผ ์ ํ ํ๊ณ , ๋ค๋ฅธ ๋๋น ์ค๋ธ์ ํธ๊ฐ ๋ ์ด origin ๋ณ์์ ๊ฐ์ ๊ฐ์ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
-- "origin"์ ๋์ผํ ์ปจํ
์คํธ์์ ๋๊ฐ ์ด๋ฏธ ์
ํ
ํ๋ค๋ฉด ๋ ์
ํ
ํ ํ์ ์์
if origin == nil then
origin = go.get_world_position(go_id)
end
์ฐ๋ฆฌ๋ ์ด ๋ฒ๊ทธ๋ฅผ ์ฝ๊ฒ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๊ณง ์ดํด๋ณผ ์์ ์ ๋๋ค. ํ์ง๋ง ์ฐ์ ๋ ๋ฏธ๋ฌํ ๋ฌธ์ ๋ถํฐ ์ดํด ๋ณด๋๋ก ํฉ์๋ค.
Name spaces
์์ Lua ํ์ผ์์, ์ฐ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋๋ฐ ์ฌ์ฉ๋๋ origin ๋ณ์๋ฅผ ์ ์ํ์ต๋๋ค. ์ด ๋ณ์๋ช ์ ๋์ค์ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ ํ ๋ค๋ฅธ ์ํฉ์ "origin" ์ด๋ผ๋ ์ด๋ฆ์ ์ฌ์ฉํ๋ฉฐ ๋ค๋ฅธ ์ข ๋ฅ๋ก ๋์ํ๋ ๋๋น๋ฅผ ์ถ๊ฐํด์ผํ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค. ์ด๊ฒ์ ์ด๋ฆ ์ถฉ๋์ด ์ผ์ด๋๊ฒ ๋ฉ๋๋ค. ์ด๋ฆ ์ถฉ๋์ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ ์ค ํ๋๋ ๋ณ์๋ ํจ์ ๋ชจ๋์๊ฒ ํ์ผ๋ช ์ผ๋ก ์ ๋์ด๋ฅผ ๋ถ์ด๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
local flying_origin
function flying_fly_randomly(radius)
...
์ด ๋ฐฉ๋ฒ์ ์ ๋์ํ์ง๋ง, Lua๋ ๋ฐ์ดํฐ์ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ๊ตฌ์ฑํ๋ ๊ฐ๋จํ๊ณ ์ฐ์ํ ๋ฐฉ๋ฒ์ธ ๋ชจ๋(modules)์ ์ ๊ณตํฉ๋๋ค.
Modules
Lua ๋ชจ๋์ ๋์(behaviours)๊ณผ ํจ์(functions)๋ฅผ ์ํ ์ปจํ ์ด๋๋ก ์ฌ์ฉํ๋ Lua ํ ์ด๋ธ์ ๋๋ค. ์ฌ๊ธฐ "flaying.lua"์ ๋ชจ๋ ๋ฒ์ ์ด ์์ต๋๋ค. ์ฌ๊ธฐ์ ์์์ ๋ค๋ฃจ์๋ ๋ฐ์ดํฐ ๊ณต์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์์ ์ฌํญ๋ ํฌํจ๋์ด ์์ต๋๋ค.
-- "M" ํ
์ด๋ธ์ ๋ชจ๋์ ํฌํจ์ํด
local M = {}
-- ํ
์ด๋ธ์ ์๋ ์์น๋ฅผ ์ ์ฅํ๋๋ก ์ฌ์ฉํจ
-- ๋ชจ๋์ด ๋ชจ๋ ๊ฒ์ ์ค๋ธ์ ํธ์ ๊ณต์ ๋ Lua context์ ์ผ๋ถ๋ถ์ด ๋๋ฏ๋ก origin ๋ณ์๋ฅผ ์ง์ ์ ์ผ๋ก ์ ์ฅํ ์ ์์, ํ๋ ์ด์์ GO๊ฐ ์ด ๋ชจ๋์ ์ฌ์ฉํ๋ฉด ๋ฎ์ด ์์์ง
M.origins = {}
-- ์๋ณธ ์์น์์ "radius" ๊ฑฐ๋ฆฌ๋งํผ ๋๋คํ ์์น๋ก ๋ ๋ ค๋ณด๋
-- ๋ ๋ ค ๋ณด๋ธ ํ "fly_randomly_done" ๋ฉ์ธ์ง๋ฅผ ๋๋๋ ค ๋ณด๋
function M.fly_randomly(radius)
-- radius ๋ฅผ ์ง์ ํ์ง ์์์ผ๋ฉด 100์ผ๋ก ์
ํ
radius = radius or 100
-- ์๋ ์์น๋ฅผ ์ธ๋ฑ์ฑํ๋ ํ์ฌ ์ค๋ธ์ ํธ์ id๊ฐ ํ์ํจ
-- "."์ ์ฌ์ฉํ ์ ์์
local go_id = go.get_id()
-- ์ ์ฅ๋์ ์ด ์์ผ๋ฉด ํ์ฌ ์์น๋ฅผ origins์ ์ ์ฅํจ
if flying.origins[go_id] == nil then
flying.origins[go_id] = go.get_world_position(go_id)
end
-- ์๋ ์์น์์ "radius" ๊น์ง์ ์ต๋ ๊ฑฐ๋ฆฌ์ ๋๋ค ์์น ์์๋ด๊ธฐ
local rand_angle = math.random(0, 3.141592 * 2)
local rand_radius = math.random(radius)
local offset = vmath.rotate(vmath.quat_rotation_z(rand_angle),
vmath.vector3(rand_radius, 0, 0))
local rand_pos = flying.origins[go_id] + offset
-- ๋๋ฌด ๋น ๋ฅธ ์ ๋๋ฉ์ด์
์ ๋ฐฉ์งํ๊ธฐ ์ํด radius์ ๋ํด ์ค์ผ์ผ๋ ๋๋ค ์ฌ์์๊ฐ(duration)์ ์
ํ
ํจ
local rand_duration = math.random(radius) / 100 + (radius / 200)
-- ์ ๋๋ฉ์ด์
์ฒ๋ฆฌ, ์๋ฃ ํ์ ๋ฉ์ธ์ง๋ฅผ ๋๋ ค๋ณด๋
go.animate(".", "position", go.PLAYBACK_ONCE_FORWARD,
rand_pos, go.EASING_INOUTSINE, rand_duration, 0.0,
function ()
msg.post("#", "fly_randomly_done")
end)
end
return M
์ด์ ์คํฌ๋ฆฝํธ์์ ์ฐจ์ด์ ์ ๋ฐ์ดํฐ(flying.origins)์ ํจ์(flying.fly_randomly()) ๋ก ์ฑ์์ง flying ํ ์ด๋ธ์ ์์ฑํ ๊ฒ์ด ๋ค๋ฆ ๋๋ค. ์ฐ๋ฆฌ๋ ์ด ํ ์ด๋ธ์ ๋ฆฌํดํด์ ๋ชจ๋์ ์๋ฃํ๊ณ , ์ด ๋ชจ๋์ ์ฌ์ฉํ๊ธฐ ์ํด ๋๋น์ ์คํฌ๋ฆฝํธ๋ฅผ ์๋์ฒ๋ผ ๋ณ๊ฒฝํ๋ฉด ๋ฉ๋๋ค.
flying = require "modules_example.flying"
function init(self)
flying.fly_randomly()
end
function on_message(self, message_id, message, sender)
if message_id == hash("fly_randomly_done") then
flying.fly_randomly()
end
end
์ธ๋ถ ํ์ผ์ ์์ฒญ(require)ํ๋ฉด, ์์ฒญ๋ ์คํฌ๋ฆฝํธ์ ๋ฆฌํด๊ฐ์ ๋ณ์์ ํ ๋นํฉ๋๋ค.
flying = require "modules_example.flying"
๋ชจ๋์ด ๋ฐ์ดํฐ์ ๋ชจ๋ ์ฝ๋ ์ ๋ถ๋ฅผ ํฌํจํ ํ ์ด๋ธ์ ๋ฆฌํดํ๋ฉด flying ๋ณ์๋ฅผ ํตํด ํ ์ด๋ธ์ ์ฐธ์กฐํ ์ ์์ต๋๋ค. ํ ์ด๋ธ ์ด๋ฆ์ ์์๋ก ์ง์ด๋ ์๊ด ์์ผ๋ฏ๋ก ์๋์ ๊ฐ์ด ์์ฑํด๋ ๋ฉ๋๋ค.
banana = require "modules_example.flying"
function init(self)
banana.fly_randomly()
end
function on_message(self, message_id, message, sender)
if message_id == hash("fly_randomly_done") then
banana.fly_randomly()
end
end
์ฆ, ๋์ผํ ์ด๋ฆ์ ๊ฐ์ง ๋ ๊ฐ์ ๋ชจ๋์ ์ฌ์ฉํ ์๋ ์์ด์ ์๋ก ๋ค๋ฅธ ๋ณ์๋ช ์ผ๋ก ๋ก์ปฌ์ ํ ๋นํ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค.
๋ชจ๋ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ์ฌ ์ด์ ์ฐ๋ฆฌ๋ ์ด๋ฆ ์ถฉ๋์ ํผํ๊ณ ๊ณต์ ๋ ๊ธฐ๋ฅ์ ์บก์ํ ํ ์ ์๊ฒ ๋์์ต๋๋ค.
Best practices
Naming conventions
๋ชจ๋ ํ ์ด๋ธ์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ง๋ง, public ํจ์๋ ๊ฐ์ด ํฌํจ๋ ํ ์ด๋ธ์ ํ์ค ์ด๋ฆ์ผ๋ก M (http://lua-users.org/wiki/ModuleDefinition ์ฐธ๊ณ )์ ์ฌ์ฉํ๋ ๊ฒ์ ์ถ์ฒํฉ๋๋ค. M ์ด๋ฆ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋์ผํ ์ด๋ฆ์ ํจ์๋ก ๋ชจ๋ ํ ์ด๋ธ์ ๋ฐ๋ผํด ๋ฒ๋ฆฌ๋ ์ค์ ๋ฐ์๋ฅผ ๋ฐฉ์งํ๋๋ฐ ๋์์ด ๋ฉ๋๋ค.
--- ๋ชจ๋ ์ค๋ช
-- @module foobar
local M = {}
--- bar ์์๊ฐ ์ค๋ช
-- @field BAR
local M.BAR = "bar"
local function private_function()
end
-- ๋ชจ๋์ด ์ฑ๊ธํด์ด ์๋ ์ํ(non-singleton)๋ฅผ ์ ์ง ํด์ผ ํ๋ ๊ฒฝ์ฐ, ํ ์ํ์ "์ธ์คํด์ค"๋ฅผ ๋ฆฌํดํ๋ ํจ์๋ฅผ ์์ฑํด์ผ ํจ. ๊ทธ ๋ค์ ์ด ์ธ์คํด์ค๋ ๋ชจ๋ ํจ์๋ก ๋๊ฒจ์ง
-- @foobar์ ์ธ์คํด์ค๋ฅผ ๋ฆฌํด
function M.create()
local foobar = {
foo = "foo"
}
return foobar
end
--- ์ด ํจ์์์๋ ๋ญ๊ฐ ์์
ํฉ๋๋ค...
-- @function do_something
-- @param foobar
-- @return foo
function M.do_something(foobar)
return foobar.foo
end
--- ์ด ํจ์์์๋ ๋ญ๊ฐ ์์
ํฉ๋๋ค...
-- @function do_something_else
-- @param foobar
-- @return foobar
function M.do_something_else(foobar)
return M.do_something(foobar) + M.BAR
end
return M
Allow monkey patching
"๋ชฝํค ํจ์น(monkey patch)๋ ์๋ณธ ์์ค ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋์ ์ธ์ด์ ๋ฐํ์ ์ฝ๋๋ฅผ ์์ ํ๊ฑฐ๋ ํ์ฅํ๋ ํ ๋ฐฉ๋ฒ์ ๋๋ค." โ Wikipedia
Lua๋ ๋์ ์ธ์ด์ด๋ฏ๋ก ๋ด์ฅ๋ ๋ชจ๋ ์ ๋ถ๋ฅผ ์์ ํ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค. ์ด๋ ํ ์คํธ์ ๋๋ฒ๊น ์ด ์ฃผ ๋ชฉ์ ์ผ ๊ฒฝ์ฐ ๋๋จํ ๊ฐ๋ ฅํ๊ณ ์ ์ฉํฉ๋๋ค. ๋ชฝํค ํจ์น๋ ๊ฐ๋ ฅํ ์ปคํ๋ง์ ์ฝ๊ฒ ์ ๋ํ๋ฏ๋ก ์ผ๋ฐ์ ์ผ๋ก ์ข์ ์๊ฐ์ ์๋๋๋ค. ํ์ง๋ง ์ ๋ชจ๋์ ์์ฑํ๋ ๊ฒฝ์ฐ์๋ ๋ชฝํค ํจ์น๊ฐ ๊ฐ๋ฅํ๊ฒ ์ปค์คํ ๋ชจ๋์ ๋ง๋๋ ๊ฒ์ด ์ข์ต๋๋ค. Lua๋ ์๋์ ๊ฐ์ด ํ ์ ์๊ฒ ํด ์ค๋๋ค.
-- mymodule.lua
local M = {}
M.foo = function()
print('์ด๊ฒ์ public ๋ชจ๋ ํจ์์ด๋ค.')
end
setmetatable(M, {
__newindex = function(m, t)
error('์ ์ ๊ฐ ' .. t .. ' ์์ฑ์ ๋ชจ๋์ ์ถ๊ฐํ๋ ค๊ณ ์๋ํ๋ค!')
end
})
return M
์์ ํธ๋ฆญ์ ์ข์ ์์ด๋์ด๋ ์๋๋๋ค. ๋ชจ๋์ ๋ฌด์์ ์ฌ์ฉํ ์ง ๊ฒฐ์ ํ๋ ๊ฒ์ ์ ์ ์๊ฒ ๋งก๊ธฐ๋ ๊ฒ์ด ์ข์ต๋๋ค.
Beware of locals
์์์ ์ธ๊ธํ ์คํ์ผ๋ก ๋ชจ๋์ ์ ์ํ์ง ์๊ธฐ๋ก ํ๋ค๋ฉด, local์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์กฐ์ฌํด์ผ ํฉ๋๋ค. ์ฌ๊ธฐ ์์ ๊ฐ ์์ต๋๋ค. (kiki.to ์์ ๋ฐ์ท):
local M = {}
local function sum(a, b)
return a + b
end
local function mult(a, b)
local result = 0
for i=1,b do
result = sum(result, a)
end
return result
end
M.sum = sum
M.mult = mult
return M
์ด๊ฒ์ ์์ฃผ ๊ฐ๋จํ ๊ณ์ฐ๊ธฐ ๋ชจ๋์ ๋๋ค. ์ด ๋ชจ๋ ํ ์ด๋ธ์ด ๋ง์ง๋ง์ ์ด๋ป๊ฒ public ํจ์๋ค์ ํ ๋นํ๋์ง ์ ์ดํด๋ณด์ญ์์ค. ๋ํ local mult() ํจ์๊ฐ local sum() ํจ์๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง๋ ์ดํด๋ณด์ญ์์ค. ์ด๋ ๊ฒ ํ๋ ๊ฒ์ด ์กฐ๊ธ ๋น ๋ฅผ ์๋ ์์ง๋ง ์ฌ๊ธฐ์ ๋ฏธ๋ฌํ ๋ฌธ์ ๊ฐ ์์ ์ ์์ต๋๋ค. ๋ง์ฝ ์ฐ๋ฆฌ๊ฐ ์ด๋ค ์ด์ ๋ก ์๋์ ๊ฐ์ด ๋ชจ๋์ ๋ชฝํค ํจ์น(monkey patch) ํ๋ ค ํ๋ค๋ฉด:
local summult = require("summult")
summult.sum = function(a,b) return 1 end
print(summult.mult(5,2))
์ด์ , ์ฌ์ ์ ๋ ํ์๋ summult.mult(5,2) ๋ ์ฌ์ ํ 10์ ๋ฆฌํด(1์ ์์ํ๊ฒ ์ง๋ง)ํฉ๋๋ค. ์ด ๋ฌธ์ ๋ ์ ์ ๊ฐ ๋ชจ๋ ํ ์ด๋ธ์์ sum() ํจ์๋ฅผ ๋ณ๊ฒฝ ํ์ง๋ง multi() ๋ด๋ถ์ ์ผ๋ก๋ ์ฌ์ ํ local๊ณผ ์์ ๋์ง ์์ ํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
global scope๋ฅผ ์ค์ผ์ํค์ง ๋ง๊ณ ๋ด๋ถ ์ํ(internal state)๋ฅผ ๋ ธ์ถ์ํค๊ฑฐ๋ ์์ด๋์ค์ง ์๊ฒ ํ๊ธฐ
์ด ๋ชจ๋ฒ์ฌ๋ก๋ ๋ชจ๋์๋ง ๊ตญํ๋ ๊ฒ์ ์๋์ง๋ง ์ ์ญ ๋ฒ์(global scope)์์ ์ํ๋ฅผ ์ ์ฅํ๊ฑฐ๋ ํจ์๋ฅผ ์ ์ํ๋ฉด ์๋๋ ์ค์์ฑ์ ๋ค์ ํ ๋ฒ ์๊ธฐํ ๊ฐ์น๊ฐ ์์ต๋๋ค. ์ ์ญ ๋ฒ์์์ ์ํ๋ฅผ ์ ์ฅํ๋ ๋ช ๋ฐฑํ ์ํ์ฑ ์ค ํ๋๋ ๋ชจ๋์ ์ํ๊ฐ ๋ ธ์ถ๋๋ค๋ ๊ฒ์ด ์์ผ๋ฉฐ ๋ค๋ฅธ ์ํ์ฑ์ผ๋ก๋ ๋์ผํ global ๋ณ์๋ฅผ ์ฌ์ฉํ ๋ ๋ ๋ชจ๋์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์๋ ์๋ค๋ ๊ฒ์ ๋๋ค. Defold๋ ๋์ผํ ์ปฌ๋ ์ ์ ์ค๋ธ์ ํธ ๊ฐ์๋ง Lua context๋ฅผ ๊ณต์ ํ๋ฏ๋ก ์ง์ ํ ์๋ฏธ์ ์ ์ญ ๋ฒ์(global scope)๋ ์กด์ฌํ์ง ์์ต๋๋ค.
๊ฐ๋ฐํ๋ ๋์์๋ global table์ ๋ชจ๋ํฐ๋ง ํด์ global table์ด ์์ ๋ ๋ ๋ง๋ค error() ๋ฅผ ๋ฐ์์ํค๋ ๊ฒ์ด ์ข์ต๋๋ค.
์์ธํ ์ ๋ณด๋ Lua Wiki ํ์ด์ง http://lua-users.org/wiki/DetectingUndefinedVariables ์ฐธ๊ณ
์ด ์ฝ๋๋ global table์ ๋ณดํธํ๋๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
-- ์ ์ธ๋ฑ์ค๋ก๋ถํฐ ํ
์ด๋ธ์ ๋ณดํธํ๊ธฐ ์ํ ๋ชจ๋. ์ผ๋ฐ์ ์ผ๋ก global scope๋ฅผ ๋ณดํธํ๋๋ฐ ์ฌ์ฉ๋จ
-- https://gist.github.com/britzl/546d2a7e32a3d75bab45 ์์ ์ต์ ๋ฒ์ ๊ฐ์ ธ์ค๊ธฐ
-- @module superstrict
-- @usage
--
-- -- Defold ์ฌ์ฉ ์์
-- -- gameobject์ gui script์ ๋ผ์ดํ์ฌ์ดํด ํจ์๋ค์ ํ์ฉํจ
-- -- ๋ํ ๋ฐ์คํฌํ์์ ๋๋ฏธ ๊ตฌํ์ ์ํด facebook๊ณผ iap ๋ชจ๋ ํ ๋น์ ํ์ฉํจ
-- -- whitelist๊ฐ ํจํด์ด ์ผ์นํ๋์ง๋ฅผ ๋ค๋ฃจ๊ณ ์ด ์์ ์์ '__' ์ ๋์ด๊ฐ ์๋ ๋ชจ๋ ํจ์ ๋ํ ์ ์ญ ๋ฒ์(global scope)์์ ํ์ฉ ๋จ
-- local superstrict = require("superstrict")
-- superstrict.lock(_G, { "go", "gui", "msg", "url", "sys", "render", "factory", "particlefx", "physics", "sound", "sprite", "image", "tilemap", "vmath", "matrix4", "vector3", "vector4", "quat", "hash", "hash_to_hex", "hashmd5", "pprint", "iap", "facebook", "push", "http", "json", "spine", "zlib", "init", "final", "update", "on_input", "on_message", "on_reload", "__*" })
--
-- -- ํ์ฉ๋จ
-- __allowed = "abc"
--
-- -- ํ์ฉ๋จ
-- facebook = dummy_fb
--
-- -- ํ์ฉ๋จ
-- function init(self)
-- end
--
-- -- ์๋ฌ ๋ฐ์ํจ
-- if foo == "bar" then
-- end
--
-- -- ์๋ฌ ๋ฐ์ํจ
-- function global_function_meant_to_be_local()
-- end
--
local M = {}
-- ํ
์ด๋ธ๊ณผ whitelist ์ด๋ฆ์ ๋งคํํจ
local whitelisted_names = {}
-- ์ ๊ฒจ์ง ํ
์ด๋ธ์ ํ์ฉ๋์ง ์๋ ์ก์ธ์ค๋ฅผ ํ ํ์๊ฐ ์์ผ๋ฏ๋ก ๋๊ตฌ๋ ์๋ฌ ํจ์๋ก ์๋ง์ผ๋ก ๋ง๋ค์ง ์๋๋ก ํ์ธํ ๊ฒ
local _error = error
--- ํ
์ด๋ธ์ ํค๊ฐ whitelist์ ์๋์ง ์๋์ง ์ฒดํฌ
-- @param t whitelist ์ด๋ฆ์ ์ฒดํฌํ๋ ค๋ ํ
์ด๋ธ
-- @param n ์ฒดํฌํ๋ ค๋ ๋ณ์์ ์ด๋ฆ
-- @return true n์ด t์ whitelist์ ํฌํจ๋์ด ์๋ค๋ฉด
local function is_whitelisted(t, n)
for _,whitelisted_name in pairs(whitelisted_names[t] or {}) do
if n:find(whitelisted_name) then
return true
end
end
return false
end
--- ๋ณดํธ๋ ์ ์ธ๋ฑ์ค
-- ์ง์ ๋ ์ด๋ฆ์ด whitelist ํ
์ด๋ธ์ ์๋์ง ์ฒดํฌํจ.
-- ์์ผ๋ฉด ์๋ฌ ๋ฐ์์ํด
-- @param t ์ ์ธ๋ฑ์ค๊ฐ ์
ํ
๋ ํ
์ด๋ธ
-- @param n ํ
์ด๋ธ์ ์
ํ
๋ ๋ณ์ ์ด๋ฆ
-- @param v ์
ํ
๋ ๊ฐ
local function lock_newindex(t, n, v)
if is_whitelisted(t, n) then
rawset(t, n, v)
return
end
_error("ํ
์ด๋ธ [" .. tostring(t) .. "] ์ ์ ๊ฒผ์ต๋๋ค. '" .. n .. "'์ ๊ฐ์ ์ฐ๋ ค๊ณ ์๋์ค์
๋๋ค. ๋น์ ์ whitelist์ ์ถ๊ฐํ๊ฑฐ๋ local๋ก '" .. n .. "' ์ ์ ์ธํด์ผ ํฉ๋๋ค.", 2)
end
--- ๋ณดํธ๋ __index
-- ์ ์๋์ง ์์ ๊ฐ์ ์ฝ์ผ๋ ค ํ๋ฉด ์๋ฌ ๋ฐ์
-- @param t ์ ์ธ๋ฑ์ค๊ฐ ์
ํ
๋ ํ
์ด๋ธ
-- @param n ํ
์ด๋ธ์ ์
ํ
๋ ๋ณ์ ์ด๋ฆ
local function lock_index(t, n)
if is_whitelisted(t, n) then
return rawget(t, n)
end
_error("ํ
์ด๋ธ [" .. tostring(t) .. "] ์ ์ ๊ฒผ์ต๋๋ค. ์ ์๋์ง ์์ ๊ฐ '" .. n .. "'์ ์ฝ์ผ๋ ค ์๋์ค์
๋๋ค.", 2)
end
--- ํ
์ด๋ธ ์ ๊ทธ๊ธฐ. ํ
์ด๋ธ์ ์ ๊ฐ(ํจ์ ๋ฐ ๋ณ์)์ด ํ ๋น๋๋ ๊ฒ์ ๋ฐฉ์งํจ
-- ์ผ๋ฐ์ ์ธ ์ฉ๋๋ก๋ global scope๋ฅผ ์ค์๋ก ํ ๋นํ์ง ๋ชปํ๊ฒ lock(_G) ๋ฅผ ํธ์ถํด ๋ณดํธํ๋ ๊ฒ์
-- @param t ์ ๊ทธ๋ ค๋ ํ
์ด๋ธ
-- @param whitelist ํ
์ด๋ธ์ ํ์ฉ๋ ์ด๋ฆ์ ๋ชฉ๋ก
function M.lock(t, whitelist)
assert(t, "์ ๊ทธ๋ ค๋ฉด ํ
์ด๋ธ์ ๋๊ฒจ์ผ ํจ")
whitelisted_names[t] = whitelist or {}
local mt = getmetatable(t) or {}
mt.__newindex = lock_newindex
mt.__index = lock_index
setmetatable(t, mt)
end
---
-- ํ
์ด๋ธ ์ธ๋ฝํ๊ธฐ
-- @param t ์ธ๋ฝํ๋ ค๋ ํ
์ด๋ธ
function M.unlock(t)
assert(t, "์ธ๋ฝํ๋ ค๋ฉด ํ
์ด๋ธ์ ๋๊ฒจ์ผ ํจ")
local mt = getmetatable(t) or {}
mt.__newindex = rawset
mt.__index = rawget
setmetatable(t, mt)
end
return M
๋ํ ๋ชจ๋์ ์ฌ์ฉ์์๊ฒ ๋ ธ์ถํ๋ ๋์ ์ ๋ด๋ถ ์ํ๋ฅผ ๋ค๋ฃฐ ์ ์๋ ํจ์๋ฅผ ์ ๊ณตํด์ผ ํฉ๋๋ค. ๋ง์ฝ ๋ด๋ถ ์ํ๋ฅผ ๋ค๋ฃจ๋ ํจ์๋ฅผ ์ ๊ณตํ๋ฉด ๋ชจ๋์ ์ฌ์ฉ์์๊ฒ ์ํฅ์ ๋ฏธ์น์ง ์์ผ๋ฉด์ ๋ชจ๋์ ๋ด๋ถ ์์ ๋ง ๋ฆฌํํ ๋ง ํ๊ธฐ ์ฌ์์ง๋๋ค. ์ํ๋ฅผ ์บก์ํ ํ๋ ๊ฒ์ OOP ์ธ์ด์์ ์ผ๋ฐ์ ์ด์ง๋ง Lua ๋ชจ๋ ๊ฐ๋ฐ์์๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์ ์ฉ๋ฉ๋๋ค.
Stateless or stateful modules?
์ํ๊ฐ ์๋ ๋ชจ๋(stateful modules)์ ๋ด๋ถ ์ํ๋ฅผ ์ ์งํ์ฌ ๋ชจ๋์ ๋ชจ๋ ์ฌ์ฉ์ ๊ฐ์ ๊ณต์ ๋๋ ์ฑ๊ธํค(singleton)๊ณผ ๋น๊ตํ ์ ์์ต๋๋ค.
local M = {}
-- ๋ชจ๋์ ๋ชจ๋ ์ฌ์ฉ์๊ฐ ์ด ํ
์ด๋ธ์ ๊ณต์ ํจ
local state = {}
function M.do_something(foobar)
table.insert(state, foobar)
end
return M
์ํ๊ฐ ์๋ ๋ชจ๋(stateless modules)์ ์ด๋ ํ ๋ด๋ถ ์ํ๋ ์ ์งํ์ง ์์ต๋๋ค. ๋์ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ local์ธ ๊ฐ๋ณ ํ ์ด๋ธ๋ก ์ํ๋ฅผ ๋ ธ์ถ(externalize )ํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ์ํ๊ฐ ์๋ ๋ชจ๋๋ก ์ ๊ทผํ๋ ๋๋ถ๋ถ์ ๋ฐฉ๋ฒ์ผ๋ก๋ create() ํน์ new() ๊ฐ์ ๋ชจ๋ ๋ด์ ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒ์ ์ข ์ข ์์กดํฉ๋๋ค. ์์ฑ์ ํจ์๋ ์ํ๊ฐ ์ ์ฅ๋ ํ ์ด๋ธ์ ๋ฆฌํดํ๋ฉฐ, ๊ตฌํ์ ๋ฐ๋ผ์ ๋๋ก๋ ๋ชจ๋ ํจ์ ์์ฒด๊ฐ ๋๊ธฐ๋ ํฉ๋๋ค.
state table๋ง ์ฌ์ฉํ๋ Stateless modules
์๋ง๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ ์ํ(state)๋ง์ ํฌํจํ ์ ํ ์ด๋ธ์ ๋ฐํํ๋ ์์ฑ์ ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ผ ๊ฒ๋๋ค. ์ด ์ํ(state)๋ state table์ ๋ค๋ฃจ๋ ๋ชจ๋ ํจ์์ ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฉํฐ๋ก ๋ช ์์ ์ผ๋ก ๋ชจ๋๋ก ๋ณด๋ ๋๋ค.
local M = {}
local function private_function(self, bar)
return self.public_variable .. bar
end
function M.public_function(self, bar)
return private_function(self, bar)
end
function M.new(foo)
local instance = {
public_variable = foo
}
return instance
end
return M
์๋์ ๊ฐ์ด ๋ชจ๋์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
local foobar = require(โfoobarโ)
local fb = foobar.new(โfooโ)
print(fb.public_variable)
print(foobar.public_function(fb, โbarโ))
metatables๋ฅผ ์ฌ์ฉํ๋ Stateless modules
Metatables๋ Lua์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ๋๋ค. ์ด๋ป๊ฒ ๋์ํ๋์ง ์ข์ ํํ ๋ฆฌ์ผ์ http://nova-fusion.com/2011/06/30/lua-metatables-tutorial/ ์์ ์ฐพ์ ์ ์์ต๋๋ค.
๋ ๋ค๋ฅธ ์ ๊ทผ๋ฒ์ผ๋ก๋ ํธ์ถ ๋๋ง๋ค ๋ชจ๋์ public ํจ์๋ค๊ณผ ์ํ๋ฅผ ํฌํจํ ์ ํ ์ด๋ธ์ ๋ฆฌํดํ๋ ์์ฑ์ ํจ์๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
local M = {}
local function private_function(self, bar)
return self.public_variable .. bar
end
function M:public_function(bar)
return private_function(self, bar)
end
function M.new(foo)
local instance = {
public_variable = foo
}
return setmetatable(instance, { __index = M })
end
return M
์๋ ๋ฐฉ๋ฒ์ผ๋ก ์ด ๋ชจ๋์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
local foobar = require(โfoobarโ)
local fb = foobar.new(โfooโ)
print(fb.public_variable)
print(fb:public_function(โbarโ))
๋ชจ๋์์ ํจ์๋ฅผ ์ ์ํ๊ณ ํธ์ถํ ๋ ์ฝ๋ก (:) ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. o:foo(x) ๊ณผ ๊ฐ์ ํํ์์ o.foo(o, x) ์ ๋ค๋ฅธ ํํ์ด๋ฉฐ, ํจ์ ์ ์ธ์์๋ ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ก self๊ฐ ์ถ๊ฐ๋ฉ๋๋ค.
๋ ์์ธํ ๋ด์ฉ์ http://www.lua.org/pil/5.html ์ฐธ๊ณ
Stateless modules using closures
๋ชจ๋์ ์ ์ํ๋ ์ธ ๋ฒ์งธ ๋ฐฉ๋ฒ์ผ๋ก๋ Lua closures(http://www.lua.org/pil/6.1.html ์ฐธ๊ณ )๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ํจ์๋ ์ธ์คํด์ค๋ฅผ ๋ฆฌํดํ๊ณ ํด๋ก์ ๋ ์ธ์คํด์ค์ private, public ๋ฐ์ดํฐ์ ํจ์๋ค์ ํฌํจํ๊ณ ์์ต๋๋ค. ์ฌ๊ธฐ์๋ metatables๋ฅผ ์ฌ์ฉํ ๋ ์ฒ๋ผ ์ธ์๊ฐ(๋ช ์์ ์ผ๋ก๋ ์์์ ์ผ๋ก๋ ์ฝ๋ก (:) ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ๋)์ผ๋ก ์ธ์คํด์ค๋ฅผ ๋๊ธธ ํ์๊ฐ ์์ต๋๋ค. ๋ํ ์ด ๋ฐฉ๋ฒ์ ํจ์ ํธ์ถ์ด "__index" metamethods ๋ฅผ ํตํ ํ์๊ฐ ์์ผ๋ฏ๋ก metatables์ ์ฌ์ฉํ๋ ๊ฒ ๋ณด๋ค ๋ค์ ๋น ๋ฆ ๋๋ค. ํ ๊ฐ์ง ๋จ์ ์ ๊ฐ ํด๋ก์ ๊ฐ ๋ฉ์๋์ ๋ณต์ ๋ณธ์ ํฌํจํ๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ ์๋ชจ๊ฐ ํฌ๋ค๋ ์ ์ ๋๋ค. ๋ ๋ค๋ฅธ ๋จ์ ์ ๊น๋ํ ๋ฐฉ๋ฒ์ผ๋ก ์ธ์คํด์ค ๋ฉ์๋๋ฅผ ๋ชฝํค ํจ์น(monkey patch)ํ ์ ์๋ค๋ ์ ์ด ์์ต๋๋ค.
local M = {}
function M.new(foo)
local instance = {
public_variable = foo
}
local private_variable = ""
local private_function = function(bar)
return instance.public_variable .. private_variable .. bar
end
instance.public_function = function(bar)
return private_function(bar)
end
return instance
end
return M
์๋์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๋ชจ๋์ ์ฌ์ฉํ์ญ์์ค.
local foobar = require(โfoobarโ)
local fb = foobar.new(โfooโ)
print(fb.public_variable)
print(fb.public_function(โbarโ))
๋ชจ๋๊ณผ ๋ชจ๋ ํจ์๋ ๋ช ํํ ๋ชฉ์ ์ผ๋ก ๊ฐ์ง๊ณ ์์๋๋ก ๋์ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๋ชจ๋์ ์ฃผ๋ก ์ฌ์ฌ์ฉ์ ๋จ์ํ ํ๊ณ ๋์์ ์บก์ํ ํ๊ธฐ ์ํด ๋ง๋ค์ด ์ก์ต๋๋ค. ๋ชจ๋์ ์์ฑํ ๋, ์์ํ ๋์์ด ๋ชจ๋, ํจ์, ์ธ์์ ์ด๋ฆ์ด ๋ณด์ด๋ ๋๋ก ๊ฐ๋จํ ์ถ๋ฆฌํ ์ ์๋๋ก ์ค๊ณํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
๋ง์ฝ ๋ชจ๋ ๊ณ์ ์ ํจ์ ์ด๋ฆ์ด login(username, password) ์ด๋ผ๋ฉด ํน์ ์ ์ ์ด๋ฆ๊ณผ ๋น๋ฐ๋ฒํธ๋ฅผ ์ฌ์ฉํ์ฌ ๊ณ์ ์ ๋ก๊ทธ์ธ ํ๋ ํจ์๋ผ๊ณ ์ถ๋ฆฌํ๊ธฐ๊ฐ ์ฝ์ต๋๋ค.
๋ชจ๋๊ณผ ๋ชจ๋ public ํจ์๋ค์ ๋ฌธ์ํ ํ์ธ์.
๋ชจ๋ ๋๋ ํจ์๋ฅผ ๋ฌธ์ํ ํ๋ฉด, ํจ์๋ ์ธ์ ์ด๋ฆ์ผ๋ก ์ถ์ ํ๊ธฐ ์ด๋ ค์ด ์ ๋ณด๋ฅผ ๊ธฐ์ตํด ๋ด๊ธฐ ์ฌ์์ง๋๋ค. ๋ง์ ๊ฒฝ์ฐ, ์งง๊ณ ์ ์ด๋ฆ์ง์ด์ง ํจ์๋ ์ธ์๋ ๋ชจ๋์ด ์ด๋ป๊ฒ ๋์ํ๊ณ ๋ฌด์์ ์ฌ์ฉํ๊ณ ํจ์ ํธ์ถ๋ก๋ถํฐ ๋ฌด์์ ๊ธฐ๋ํ๋์ง ์์ธกํ๊ธฐ ์ถฉ๋ถํ์ง๋ง, ๋ฌธ์ํ๋ก๋ ๋ฐํ๊ฐ, ์ ์ ์กฐ๊ฑด, ์ฌ์ฉ์์ ๋ฅผ ๋ช ์ํ ์ ์์ต๋๋ค. LDoc ํ์ค์ ์ฌ์ฉํ์ฌ ๋ฌธ์ํ๋ฅผ ํด๋ณด์ธ์.
์์ธํ LDoc ๋ฌธ์ ํ์ค์ https://github.com/stevedonovan/LDoc ์์ ์ฐพ์ ์ ์์ต๋๋ค.