オブジェクトの減算
CoddyのLuaジャーニー「Object Oriented Programming」セクションの一部 — レッスン 27/70。
__add が + 演算子を処理するのと同様に、__sub メタメソッドは - 演算子の振る舞いを定義します。そのパターンは全く同じで、2つのオペランドを受け取り、新しいオブジェクトを返す関数を定義します。
local Color = {}
Color.__index = Color
function Color:new(r, g, b)
local obj = {r = r, g = g, b = b}
setmetatable(obj, Color)
return obj
end
function Color.__sub(c1, c2)
return Color:new(c1.r - c2.r, c1.g - c2.g, c1.b - c2.b)
endRGBカラーを扱う際、減算によって負の値が生じることがあります。実際のアプリケーションでは、結果を有効な範囲(0-255)にクランプしたい場合がありますが、コアとなるメタメソッドの構造は同じままです。
local bright = Color:new(200, 150, 100)
local dim = Color:new(50, 30, 20)
local result = bright - dim
print(result.r, result.g, result.b) -- 出力: 150 120 80覚えておいてください:__sub は(コロンではなく)ドットを使って定義してください。これは、Luaが両方のオペランドを引数として直接呼び出すメタメソッドだからです。
チャレンジ
簡単- 演算子を使用して減算をサポートする Color クラスを作成しましょう。色はRGB値で表され、ある色から別の色を引くと、各成分の差を持つ新しい色が作成されます。
コードは2つのファイルに分けて構成します:
Color.lua: 赤、緑、青の値を表すr、g、b成分を持つ Color クラスを定義します。:new(r, g, b)コンストラクタを含め、2つの色を引くと成分ごとの差を持つ新しい色が作成されるように__subメタメソッドを実装してください。__subはドット構文を使用し、両方のオペランドを引数として受け取ることに注意してください。main.lua: Color モジュールをロードし、提供された入力から色のインスタンスを作成し、それらを減算して、結果のRGB値を表示します。
6つの入力を受け取ります:
- 1つ目の色の赤成分
- 1つ目の色の緑成分
- 1つ目の色の青成分
- 2つ目の色の赤成分
- 2つ目の色の緑成分
- 2つ目の色の青成分
メインファイルで、与えられたRGB値を使用して2つの色を作成し、- 演算子を使用して1つ目の色から2つ目の色を減算し、結果の色の r、g、b 値を別々の行に出力してください。
例えば、入力が 200, 150, 100, 50, 30, 20 の場合、出力は以下のようになります:
150
120
801つ目の色 (200, 150, 100) から2つ目の色 (50, 30, 20) を引くと、新しい色 (150, 120, 80) になります。
チートシート
__sub メタメソッドは、- 演算子の動作を定義します。2つのオペランドを受け取り、新しいオブジェクトを返します。
function Color.__sub(c1, c2)
return Color:new(c1.r - c2.r, c1.g - c2.g, c1.b - c2.b)
end__sub はドット(コロンではなく)を使用して定義します。これは、Luaが両方のオペランドを引数として直接呼び出すメタメソッドであるためです。
local bright = Color:new(200, 150, 100)
local dim = Color:new(50, 30, 20)
local result = bright - dim
print(result.r, result.g, result.b) -- 出力: 150 120 80自分で試してみよう
-- Colorモジュールを読み込む
local Color = require('Color')
-- 入力値を読み込む
local r1 = tonumber(io.read())
local g1 = tonumber(io.read())
local b1 = tonumber(io.read())
local r2 = tonumber(io.read())
local g2 = tonumber(io.read())
local b2 = tonumber(io.read())
-- TODO: 与えられたRGB値を使用して2つのColorインスタンスを作成する
-- TODO: - 演算子を使用して、1つ目の色から2つ目の色を引く
-- TODO: 結果の色であるr、g、bの値をそれぞれ別の行に出力する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。