Menu
Coddy logo textTech

文字列のフォーマット

CoddyのLuaジャーニー「Object Oriented Programming」セクションの一部 — レッスン 16/70。

オブジェクトを直接出力すると、Luaはtable: 0x55a...のような、あまり役に立たない情報(単なるメモリアドレス)を表示します。__tostringメタメソッドを使用すると、オブジェクトが出力されたりテキストに変換されたりする際に、そのオブジェクトをどの文字列で表現するかを正確に定義できます。

クラスパターンでは、クラステーブルに関数として __tostring を追加します。クラス自体がインスタンスのメタテーブルとして機能するため、Lua は自動的にこの関数を見つけて使用します:

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 メソッドを呼び出します:

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

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

challenge icon

チャレンジ

簡単

自己紹介ができる Book クラスを作成しましょう!本を直接プリントしたときに、Lua が謎めいたメモリ番地ではなく、きれいにフォーマットされた文字列を表示するようにします。これはすべて __tostring メタメソッドのおかげです。

コードは2つのファイルに分けて構成します:

  • Book.lua: 標準的なプロトタイプパターンを使用して Book クラスを定義します。各本には titleauthor を保存する必要があります。:new(title, author) コンストラクタを含め、本をプリントしたときに読みやすい形式で情報が表示されるように __tostring メタメソッドを実装してください。
  • main.lua: Book モジュールを require し、本のインスタンスを作成して、カスタム文字列フォーマットが動作することを確認するためにそれらを直接プリントします。

__tostring メソッドは、以下の正確な形式で文字列を返す必要があります:

"[title]" by [author]

出力文字列の中で、タイトルが二重引用符(ダブルクォーテーション)で囲まれていることに注意してください。

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

  1. 1冊目の本のタイトル
  2. 1冊目の本の著者
  3. 2冊目の本のタイトル
  4. 2冊目の本の著者

メインファイルで、提供された入力を使用して2つの本を作成し、各本を直接プリントしてください(メソッドを呼び出すのではなく、単に print(book) とします)。各本はそれぞれの行に表示される必要があります。

例えば、入力が The HobbitJ.R.R. Tolkien1984George Orwell の場合、出力は以下のようになります:

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

__tostring は文字列を返す必要があること、そしてクラステーブルがインスタンスのメタテーブルとして機能するため、本をプリントするときに Lua が自動的に __tostring 関数を見つけて使用することを忘れないでください。

チートシート

__tostring メタメソッドは、オブジェクトがプリントされたりテキストに変換されたりする際に、どのように文字列として表現されるかを定義します。

__tostring がない場合、オブジェクトをプリントするとそのメモリアドレスのみが表示されます。

print(someObject)  -- Output: table: 0x55a...

クラスのメソッドとして __tostring を追加し、文字列表現をカスタマイズします。

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

インスタンスをプリントすると、Lua は自動的に __tostring を呼び出します。

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

主なポイント:

  • メソッドが self を受け取れるように、コロン構文 (:) を使用します
  • 必ず文字列を返す必要があります
  • self を通じてインスタンスのデータにアクセスします
  • クラステーブルがメタテーブルとして機能するため、Lua は自動的に __tostring を見つけます

自分で試してみよう

-- 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腕試し

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

Object Oriented Programmingのすべてのレッスン