Account = { balance = 0 } function Account.withdraw (v) Account,balance = Account.balance - v endこれはテーブル内にメソッド的なものを定義した例ですが、これだと
a = Account Account = nil a.withdraw(10) ---> エラーとなってしまいます。
function Account.withdraw ( self, v ) self.balance = self.balance - v end
function Account:withdraw( v ) ---> 「.」ではなく、「:」を使うと、1番目の引数にselfを書いたことと同じこととみなされる。 self.balance = self.balance - v end
a = Account Account = nil a.withdraw(a, 10) --> 通常記法。第1引数にテーブル(オブジェクト)自身を渡す。 a:withdraw(10) --> シンタックスシュガー。第1引数にオブジェクト自身を渡していることになる。
Account = { balance = 0 } function Account:new (o) --「:」に注意 o = o or { } setmetatable(o, self) self.__index = self return o end function Account:deposit (v) self.balance = self.balance + v end a = Account:new{ balance = 0 } a:deposit(100)としたとすると、
Account:new { balance = 0 }などといったように使用すると、メタテーブルの__indexに対して
Account.__index = Accountとなる。
b = Account:new() print(b.balance) -- b.balance は b自体には存在しないので、Account.balance を見ることとなる。一方、これにたいして、
b:deposit(10)などと呼び出した場合は、Account.deposit(b, 10)が呼び出される形となり、b.blanace = b.balance + 10 されるので、
Account = { balance = 0 } function Account:new (o) o = o or { } setmetatable(o, self) self.__index = self return o end function Account:deposit(v) self.balance = self.balance + v end function Account:withdraw(v) if v > self.balance then error ("んな金ねーぉ") end self.balance = self.balance - v endここで、このAccountを継承するSpecialAccountクラスを作成する
SpecialAccount = Account:new() -- この段階ではまだインスタンス s = SpecialAccount:new{limit = 1000.00} -- new を実行した時、selfのパラメータがSpecialAccountとなり、self.__indexもSpecialAccountとなった。これにより、sのメタテーブルはSpecialAccountとなり、sはSpecialAccountのインスタンスであるかのように振舞える。
s:deposit(100)を呼び出すと、