オブジェクトの減算
CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 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)になります。
自分で試してみよう
-- 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の値をそれぞれ別の行に出力する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Luaオンラインコンパイラ