Reputation: 15551
Method/1
Dog = {}
function Dog:new()
local newObj = {sound = 'woof'}
return setmetatable(newObj, { __index = self })
end
Method/2
Dog = {}
function Dog:new()
local newObj = {sound = 'woof'}
self.__index = self
return setmetatable(newObj, self)
end
Most of the times I have seen people using the self.__index = self
method, which to me seems clumsy. Why pass the whole Dog
object with all the additional methods which doesn't constitute a metatable to setmetatable
? Method/1 is good for setting the new objects's metatable.__index
to the Dog
object, it is also cleaner.
Some additional code to provide context, it works with both methods
function Dog:makeSound()
print('I say ' .. self.sound)
end
mrDog = Dog:new()
mrDog:makeSound()
Upvotes: 2
Views: 397
Reputation: 48619
If you want an __eq
metamethod, you must have just one metatable shared between all instances or it will not work. Your method #1 will not work in this case.
But the metatable does not need to be Dog
, it can be a dedicated metatable:
Dog = {}
local DogMeta = {__index = Dog}
function Dog:new(name)
local newObj = {sound = 'woof', name = name}
return setmetatable(newObj, DogMeta)
end
function DogMeta.__eq(dog1, dog2)
return dog1.name == dog2.name
end
Upvotes: 1
Reputation: 122383
Method/2 is a little more optimized than Method/1 because it doesn't need to create an extra table as its metatable. It uses itself as the metatable.
Since you said that you think Method/1 is cleaner in your question, feel free to use it. I don't think the performance difference between the two would matter in most cases. Readability is almost always more important.
Upvotes: 1
Reputation: 20838
While both approaches achieve the same end behavior, someone might prefer method 2 because it better conforms with the "recycle resource over creation" policy. Method 2 will always use one table Dog
as the metatable, regardless of how many Dog Objects you create. Method 1, OTOH, will create a new anonymous table just to act as a meta for every Dog object created.
However, method 1 is probably easier to read and reason about for newcomers to the language since it doesn't mix the concern of metatables and object definition together.
Upvotes: 1