オブジェクトの比較 (<, >)
CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 29/70。
算術や連結以外にも、比較メタメソッドを使用して、オブジェクト同士の比較方法を定義できます。__ltメタメソッドは「より小さい」(<code><) operator を処理します。
Lua が a < b を評価するとき、メタテーブル内の __lt を探します。このメタメソッドは、比較ロジックに基づいて true または false を返す必要があります。
local Item = {}
Item.__index = Item
function Item:new(name, price)
local obj = {name = name, price = price}
setmetatable(obj, Item)
return obj
end
function Item.__lt(a, b)
return a.price < b.price
end__ltを定義したので、これで項目を直接比較できます。
local apple = Item:new("Apple", 2)
local laptop = Item:new("Laptop", 999)
print(apple < laptop) -- 出力: true
print(laptop < apple) -- 出力: falseここが巧妙なところです。Lua は __lt から 演算子を automatically 導出します。a > b と書くと、Lua は単に代わりに b < a を評価します。つまり、__lt だけを定義すれば、両方向の比較を無料で利用できます。
チャレンジ
簡単価格に基づいて<code><演算子と演算子で比較できるProductクラスを作成しましょう。ショッピングカート内の商品を並べ替えたり、リストから最も安い選択肢を見つけたりするような場面に最適です。
コードを2つのファイルに分けて整理します。
Product.lua:nameフィールドとpriceフィールドを持つProductクラスを定義します。:new(name, price)コンストラクターを含め、商品のpriceで比較する__ltメタメソッドを実装します。__ltを定義すると演算子も自動的に使えるようになることを覚えておきましょう。そこはLuaが処理してくれます。main.lua:ProductモジュールをRequireし、入力からProductのインスタンスを作成して、どちらの価格が高いか、または安いかを比較します。
4つの入力が与えられます。
- 最初の商品のname
- 最初の商品のprice
- 2番目の商品のname
- 2番目の商品のprice
mainファイルで、与えられたnameとpriceを使って2つのProductを作成します。次に3回比較を行い、それぞれの結果を別々の行にPrintします。
- 最初のProductは2番目のProductより小さいか?(
trueまたはfalseをprint) - 最初のProductは2番目のProductより大きいか?(
trueまたはfalseをprint) - 価格が安いProductのnameをPrint
たとえば、入力がApple、2、Laptop、999の場合、Outputは次のようになります。
true
false
AppleApple(price 2)はLaptop(price 999)より小さいため、最初の比較結果はtrueです。AppleはLaptopより大きくないため、2番目の結果はfalseです。また、Appleのpriceのほうが低いため、安いProductとしてPrintされます。
自分で試してみよう
-- Productモジュールを読み込む
local Product = require('Product')
-- 入力を読み取る
local name1 = io.read()
local price1 = tonumber(io.read())
local name2 = io.read()
local price2 = tonumber(io.read())
-- TODO: Product:new()を使用して2つのProductインスタンスを作成する
-- TODO: <演算子を使用して製品を比較し、true/falseを出力する
-- TODO: >演算子を使用して製品を比較し、true/falseを出力する
-- TODO: より安い製品の名前を出力する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Luaオンラインコンパイラ