Menu
Coddy logo textTech

文字列のフォーマット

CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 16/70。

オブジェクトを直接 printすると、Lua は table: 0x55a... のような役に立たない情報を表示します。単なるメモリアドレスです。__tostring metamethod を使うと、オブジェクトを印刷したりテキストに変換したりするときに、どの文字列で表すかを正確に定義できます。

classパターンでは、classテーブルに__tostringをfunctionとして追加します。class自体がinstancesのmetatableとして機能するため、Luaはこのfunctionを自動的に見つけて使用します。

local Player = {}
Player.__index = Player

function Player:new(name, level)
    local instance = {}
    setmetatable(instance, self)
    instance.name = name
    instance.level = level
    return instance
end

function Player:__tostring()
    return "Player: " .. self.name .. " (Level " .. self.level .. ")"
end

これで、Player インスタンスを print すると、Lua は自動的に __tostring method を呼び出します。

local hero = Player:new("Luna", 5)
print(hero)  -- 出力: Player: Luna (Level 5)

__tostring はコロン構文を使用し、self を受け取るため、すべてのインスタンスデータにアクセスできます。この関数は文字列を返す必要があります。オブジェクトにとって意味のある方法でフォーマットし、任意の属性を組み合わせて読みやすい表現にできます。

challenge icon

チャレンジ

簡単

自分自身を紹介する方法を知っている Book クラスを作ってみましょう!本を直接出力すると、Lua はわかりにくいメモリアドレスの代わりに、きれいに整形された文字列を表示します。これはすべて __tostring metamethod のおかげです。

コードを2つのファイルに分けて整理します。

  • Book.lua: 標準的な prototype パターンを使って Book クラスを Define します。それぞれの本には titleauthor を保存します。:new(title, author) Constructor を含め、本を出力したときに読みやすい形式で情報が表示されるように __tostring metamethod を Implement します。
  • main.lua: Book module を Require し、本の instances を作成して直接出力し、独自の文字列フォーマットが実際に動作することを確認します。

__tostring method は、次の正確な形式の文字列を返す必要があります。

"[title]" by [author]

出力文字列では title が double quotes で囲まれていることに注意してください。

4つの入力を受け取ります。

  1. 1冊目の本の Title
  2. 1冊目の本の author
  3. 2冊目の本の Title
  4. 2冊目の本の author

main ファイルで、提供された inputs を使って2冊の本を作成し、それぞれの本を直接出力します(method を呼び出すのではなく、単に print(book) を使います)。各本はそれぞれ1行に表示される必要があります。

たとえば、入力が The HobbitJ.R.R. Tolkien1984George Orwell の場合、出力は次のようになります。

"The Hobbit" by J.R.R. Tolkien
"1984" by George Orwell

__tostring は string を return する必要があり、さらにクラス table が instances の metatable として機能するため、本を出力すると Lua は自動的に __tostring function を見つけて使用することを Remember してください。

自分で試してみよう

-- Bookモジュールを読み込む
local Book = require('Book')

-- 入力を読み取る
local title1 = io.read()
local author1 = io.read()
local title2 = io.read()
local author2 = io.read()

-- TODO: Book:new()を使って2つの本のインスタンスを作成する


-- TODO: 各本を直接出力する(print(book)を使うだけ)

quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Luaオンラインコンパイラ