オブジェクトの比較 (<, >)
CoddyのLuaジャーニー「Object Oriented Programming」セクションの一部 — レッスン 29/70。
算術演算や連結だけでなく、比較メタメソッドを使用してオブジェクト同士の比較方法を定義することもできます。__lt メタメソッドは、「未満」(<code><)演算子を処理します。
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 を定義するだけで、追加の手間なく両方の比較方向を利用できるようになります。
チャレンジ
簡単価格に基づいて <code>< および 演算子を使用して比較できる Product クラスを作成しましょう。これは、ショッピングカート内のアイテムを並べ替えたり、リストの中から最も安いオプションを見つけたりするようなシナリオに最適です。
コードは2つのファイルに分けて構成します:
Product.lua:nameとpriceフィールドを持つ Product クラスを定義します。:new(name, price)コンストラクタを含め、価格で製品を比較するための__ltメタメソッドを実装してください。__ltを定義すると、自動的に演算子も使用可能になることを覚えておいてください。Luaがそれを処理してくれます!main.lua: Product モジュールをロードし、入力から製品インスタンスを作成し、それらを比較してどちらが高いか安いかを判定します。
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)より小さいため、最初の比較は true になります。Apple は Laptop より大きくないため、2番目は false になります。そして、Apple の方が価格が低いため、安い方の製品として出力されます。
チートシート
__lt メタメソッドは、カスタムオブジェクトに対する「未満」(<code><)演算子を処理します。
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) -- Output: true
print(laptop < apple) -- Output: falseLuaは __lt から 演算子を自動的に導き出します。a > b と記述すると、Luaは代わりに b < a を評価します。__lt を定義するだけで、両方の比較方向が利用可能になります。
自分で試してみよう
-- 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: より安い製品の名前を表示する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。