オブジェクトの比較 (<, >)
CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 29/70。
算術演算や連結以外にも、比較メタメソッドを使ってオブジェクト同士の比較方法を定義できます。__ltメタメソッドは「より小さい」(<)演算子を処理します。
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から自動的に導出します。a > bと記述すると、Luaは単にb < aを評価します。つまり、__ltだけを定義すれば、両方向の比較を無料で利用できます。
チャレンジ
簡単価格に基づいて<演算子と>演算子で比較できるProductクラスを作成しましょう。ショッピングカート内の商品を並べ替えたり、リストから最も安い選択肢を見つけたりするような場面に最適です。
コードは2つのファイルに分けて整理します。
Product.lua:nameフィールドとpriceフィールドを持つProductクラスを定義します。:new(name, price)コンストラクターを含め、商品の価格を比較する__ltメタメソッドを実装します。__ltを定義すると>演算子も自動的に使えるようになることを覚えておきましょう。Luaが処理してくれます。main.lua:Productモジュールをrequireし、入力から商品インスタンスを作成して比較し、どちらの価格が高いか、または低いかを判定します。
4つの入力が与えられます。
- 1つ目の商品の名前
- 1つ目の商品の価格
- 2つ目の商品の名前
- 2つ目の商品の価格
メインファイルで、与えられた名前と価格を使って2つの商品を作成します。その後、3回比較を行い、それぞれの結果を別々の行に出力します。
- 1つ目の商品は2つ目の商品より小さいですか?(
trueまたはfalseを出力) - 1つ目の商品は2つ目の商品より大きいですか?(
trueまたはfalseを出力) - 価格が安い商品の名前を出力
たとえば、入力がApple、2、Laptop、999の場合、出力は次のようになります。
true
false
AppleApple(価格2)はLaptop(価格999)より小さいため、1つ目の比較結果はtrueです。AppleはLaptopより大きくないため、2つ目の結果はfalseです。また、Appleの価格のほうが安いため、安い商品の名前として出力されます。
自分で試してみよう
-- 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オンラインコンパイラ