モジュールスクリプトでは、「:」を使う場合と「.」を使う場合があります。私自身、間違った認識をしていた時期がありましたので、このページで詳しくまとめてみたいと思います。

簡単に説明すると、「:」 は メソッド呼び出し に使われ、「.」 は 通常の関数呼び出し に使われますが
もう少し詳しく解説しておきます。

1. メソッド(:)とは?

「:」 を使うと、関数が「そのオブジェクトに関連づけられたメソッド」として動作します。このとき、呼び出された関数の第1引数として、そのオブジェクト(self)が自動的に渡されます。

具体例

local TestModule = {}

function TestModule:sayHello()
    print("Hello, my name is " .. self.name)
end

return TestModule

上記のスクリプトでは、sayHello 関数は TestModule オブジェクトに関連づけられたメソッドです。

使用例

local TestModule = require(script.TestModule)

TestModule.name = "Roblox"
TestModule:sayHello()     -- 出力: Hello, my name is Roblox

ここで 「:」 を使うことで、TestModule 自身(self)が関数の第1引数として渡されています。

2. 通常の関数(.)とは?

一方で、「.」 を使うと、関数が「ただの普通の関数」として動作します。この場合、オブジェクト(self)は自動的に渡されません。

具体例

local TestModule = {}

function TestModule.sayHello()
    print("Hello!")
end

return TestModule

上記では、sayHello 関数は TestModule に関連づけられてはいますが、self は使用されません。

使用例

local TestModule = require(script.TestModule)

TestModule.sayHello() -- 出力: Hello!

ここで . を使うことで、オブジェクトに依存しない関数として呼び出されています。

「: 」と「 .」の主な違いを比較

ポイント:(メソッド).(通常の関数)
動作の目的オブジェクトに依存する関数を呼び出す独立した関数を呼び出す
self の扱い自動的に渡される渡されない
使い方の例TestModule:sayHello()TestModule.sayHello()
コードの書き方function TestModule:sayHello()function TestModule.sayHello()

まとめ

  • 「:」 は、関数がオブジェクトに依存して動作する場合(例えば、オブジェクトのプロパティを使いたい場合)に使います。このとき self が便利に扱えます。
  • 「.」 は、オブジェクトに依存しない通常の関数を定義・呼び出す場合に使います。

例えば、オブジェクトの状態(プロパティ)を変更したり参照したい場合は、「:」 を使ったほうがよいでしょう。一方で、計算やユーティリティ関数のように、特定のオブジェクトに依存しない場合は「 .」 を使うのが適切です。

selfとは?

self とは、Luaでメソッドを呼び出す際に使われる特別なキーワードです。これは、そのメソッドを呼び出した オブジェクト自身を表す参照 として使われます。言い換えれば、「そのメソッドが属するオブジェクトそのもの」を指します。

1. self が使われる場面

主に「 :」 を使ってメソッドを呼び出すときに self が自動的に渡されます。

例:
local Object = {}

function Object:sayHello()
    print("Hello, I am " .. self.name)
end

上記では、sayHelloObject の一部(メソッド)であり、selfObject 自身を指します。

2. self を使う理由

普通の関数(. で定義された関数)には、関数の中でその関数が属するオブジェクトへの自動的な参照はありません。一方、self を使うことで、関数がどのオブジェクトに関連しているかを把握できるようになります。

比較例

通常の関数の場合(. を使う)

local Object = {}

function Object.sayHello()
    print("Hello, I am " .. Object.name)
end

Object.name = "Roblox"
Object.sayHello()    -- 出力: Hello, I am Roblox

このコードは動きますが、関数の中で Object を直接指定する必要があります。このようにハードコーディングすると、別のオブジェクトに対応する際に不便です。

メソッドの場合(: と self を使う)

local Object = {}

function Object:sayHello()
    print("Hello, I am " .. self.name)
end

Object.name = "Roblox"
Object:sayHello() -- 出力: Hello, I am Roblox

この場合、self は自動的に Object を参照します。もし別のオブジェクトにメソッドを渡しても問題なく動作します。

local AnotherObject = { name = "Another" }
AnotherObject.sayHello = Object.sayHello
AnotherObject:sayHello()     -- 出力: Hello, I am Another

3. self を用いた実用的な例

self の便利さを理解するために、オブジェクト指向プログラミングの簡単な例を見てみましょう。

例: キャラクター管理システム

local Character = {}

function Character:new(name)
    local newObj = { name = name, health = 100 }
    setmetatable(newObj, self)
    self.__index = self
    return newObj
end

function Character:takeDamage(amount)
    self.health = self.health - amount
    print(self.name .. " took " .. amount .. " damage! Remaining health: " .. self.health)
end

return Character

使用例

local Character = require(script.Character)

local player1 = Character:new("Player1")
local player2 = Character:new("Player2")

player1:takeDamage(20)   -- 出力: Player1 took 20 damage! Remaining health: 80
player2:takeDamage(30)   -- 出力: Player2 took 30 damage! Remaining health: 70

このコードでは、self によってどのキャラクターがダメージを受けているかを動的に追跡できます。

4. self を使用しないとどうなる?

もし self を使わない場合、以下の問題が発生する可能性があります。

問題例: 共通データが壊れる

local Character = { health = 100 }

function Character.takeDamage(amount)
    Character.health = Character.health - amount
    print("Remaining health: " .. Character.health)
end

local player1 = Character
local player2 = Character

player1.takeDamage(20)     -- 出力: Remaining health: 80
player2.takeDamage(30)     -- 出力: Remaining health: 50

ここでは、player1player2 が同じ Character テーブルを共有しているため、一方の操作がもう一方にも影響してしまいます。


5. self の正体を理解する

技術的に言うと、self は単なる関数の最初の引数です。

以下の2つの書き方は同じ意味です:

function Object:sayHello()
    print(self.name)
end

-- 実際にはこれと同じ
function Object.sayHello(self)
    print(self.name)
end

つまり、「:」 は単に 最初の引数に自動的にそのオブジェクトを渡す記法 なのです。

6. self のまとめ

  • 何を指す?
    self は関数を呼び出したオブジェクトそのもの。
  • いつ使う?
    オブジェクトに関連するデータやプロパティを操作するとき。
  • どう便利?
    • メソッドがどのオブジェクトで呼ばれたかを自動的に把握できる。
    • 再利用性や柔軟性が向上する。
    • コードがすっきりし、ハードコーディングを避けられる。

By schilverberch

ROBLOXでゲームを作ろう! 一緒にプログラミングを学びましょう。

コメントを残す