オブジェクトの加算
CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 26/70。
__tostringや__eqのようなメタメソッドを使うと、オブジェクトの動作をカスタマイズできることはすでに学びました。ここではこれを算術演算に拡張し、まずは加算から始めます。
__add metamethod は、2つのオブジェクト間で + operator を使用したときに何が起こるかを定義します。Lua が a + b を確認すると、いずれかの operand の metatable にある __add を探します。
local Vector = {}
Vector.__index = Vector
function Vector:new(x, y)
local obj = {x = x, y = y}
setmetatable(obj, Vector)
return obj
end
function Vector.__add(v1, v2)
return Vector:new(v1.x + v2.x, v1.y + v2.y)
end__add はコロンではなく dot で定義されていることに注意してください。both operands を引数として受け取り、元のどちらかを変更するのではなく、新しいオブジェクト を should return します。これにより、操作の予測可能性と安全性が保たれます。
local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b
print(c.x, c.y) -- 出力: 4 6重要なポイントは、__add がオブジェクト内だけでなく、メタテーブル自体(ここでは Vector)に存在していなければならないということです。すべてのインスタンスのメタテーブルとして Vector を設定しているため、それらはすべて自動的にこの動作を共有します。
チャレンジ
簡単+演算子を使った加算をサポートするVectorクラスを作成しましょう。これは、演算子のオーバーロードへの最初の一歩です。オブジェクトをLua組み込みの演算子で自然に扱えるようにします。
コードを2つのファイルに分けて整理します。
Vector.lua:xとyのcomponentsを持つVectorクラスを定義します。:new(x, y)constructorを含め、2つのベクトルを加算するとcombined componentsを持つ新しいベクトルが作成されるように__addmetamethodをImplementします。__addはdot syntax(colonではありません)を使用し、引数としてboth operandsをreceivesすることをRememberしてください。main.lua:Vector moduleをRequireし、ベクトルのinstancesをcreateして、それらを加算すると正しいresultが得られることを示します。
4つの入力を受け取ります。
- First vectorのx component
- First vectorのy component
- Second vectorのx component
- Second vectorのy component
mainファイルで、指定されたcomponentsを使って2つのベクトルをcreateし、+ operatorを使ってそれらを加算し、resulting vectorのxとyのvaluesをseparate linesにPrintします。
たとえば、入力が3、4、1、2の場合、Outputは次のようになります。
4
6First vector (3, 4)にSecond vector (1, 2)を加えると、新しいベクトル (4, 6)になります。
自分で試してみよう
-- Vectorモジュールを読み込む
local Vector = require('Vector')
-- 入力を読み込む
local x1 = tonumber(io.read())
local y1 = tonumber(io.read())
local x2 = tonumber(io.read())
local y2 = tonumber(io.read())
-- TODO: 入力値を使って2つのVectorインスタンスを作成する
-- TODO: +演算子を使って2つのベクトルを加算する
-- TODO: 結果のベクトルのxとyの値を別々の行に出力する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Luaオンラインコンパイラ