Menu
Coddy logo textTech

明示的な「self」

CoddyのLuaジャーニー「Object Oriented Programming」セクションの一部 — レッスン 2/70。

関数がテーブル内にある場合、その同じテーブル内のデータにアクセスしたり、変更したりする必要があることがよくあります。しかし、ここで問題があります。関数は自分がどのテーブルに属しているかをどうやって知るのでしょうか?

解決策は、テーブルを関数の最初の引数として明示的に渡すことです。慣習として、このパラメータは self と名付けられます:

local counter = {
    value = 0
}

function counter.increment(self)
    self.value = self.value + 1
end

counter.increment(counter)
print(counter.value)  -- 出力: 1

どのように counter.increment(counter) を呼び出し、テーブル自体を引数として渡しているかに注目してください。関数内では、self はそのテーブルを指しており、これによって self.value を読み取ったり変更したりできるようになります。

このパターンは、テーブル名をハードコーディングすることなく、関数がテーブルのデータを操作できるようにするために不可欠です。現在のカウントをリセットして返す関数を考えてみましょう:

function counter.reset(self)
    local old = self.value
    self.value = 0
    return old
end

print(counter.reset(counter))  -- 出力: 1
print(counter.value)           -- 出力: 0

テーブルを手動で渡すことでも機能しますが、繰り返しのように感じられることがあります。次のレッスンでは、これを自動的に処理する、より洗練された構文について学びます。

challenge icon

チャレンジ

簡単

count フィールドを 0 で初期化した、tracker という名前のテーブルを作成してください。

以下の処理を行う関数 tracker.addAmount(self, amount) を追加してください:

  • 第1引数として self (テーブル自身) を受け取る
  • 第2引数として amount を受け取る
  • self.countamount を加算する

2つの入力を受け取ります:

  1. 加算する1つ目の数値
  2. 加算する2つ目の数値

tracker.addAmount を2回呼び出し(各入力に対して1回ずつ)、毎回第1引数としてテーブルを渡してください。両方の呼び出しが終わった後、tracker.count の最終的な値を出力してください。

チートシート

テーブル内の関数は、慣習的に self と名付けられる最初のパラメータとしてテーブルを受け取ることで、テーブルのデータにアクセスできます:

local counter = {
    value = 0
}

function counter.increment(self)
    self.value = self.value + 1
end

counter.increment(counter)  -- 引数としてテーブルを渡す
print(counter.value)  -- 出力: 1

self パラメータを使用すると、関数はテーブル名をハードコーディングすることなく、テーブルのフィールドを読み取ったり変更したりできます:

function counter.reset(self)
    local old = self.value
    self.value = 0
    return old
end

print(counter.reset(counter))  -- 出力: 1
print(counter.value)           -- 出力: 0

関数は self の後に追加のパラメータを受け取ることができます:

function counter.add(self, amount)
    self.value = self.value + amount
end

counter.add(counter, 5)

自分で試してみよう

-- 入力を読み込む
local amount1 = tonumber(io.read())
local amount2 = tonumber(io.read())

-- TODO: 以下にコードを記述してください
-- 'count' フィールドを 0 で初期化した 'tracker' という名前のテーブルを作成します
-- self.count に amount を加算する関数 tracker.addAmount(self, amount) を追加します
-- テーブルを第1引数として tracker.addAmount を2回呼び出します


-- 最終的なカウントを出力します
print(tracker.count)
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Object Oriented Programmingのすべてのレッスン