Если быть точным, obj:method(1, 2, 3)
совпадает с
do
local _obj = obj
_obj.method(_obj, 1, 2, 3)
end
Почему локальная переменная? Потому что, как отмечали многие, obj:method()
только один раз индексирует _ENV
, чтобы получить obj
. Обычно это просто важно при рассмотрении скорости, но рассмотрим следующую ситуацию:
local tab do
local obj_local = { method = function(self, n) print n end }
tab = setmetatable({}, {__index = function(idx)
print "Accessing "..idx
if idx=="obj" then return obj_local end
end})
end
tab.obj.method(tab.obj, 20)
--> Accessing obj
--> Accessing obj
--> 20
tab.obj:method(10)
--> Accessing obj
--> 10
Теперь представьте, что метаметод __index
сделал больше, чем просто напечатал что-то. Представьте, что он увеличил счетчик, записал что-то в файл или удалил случайного пользователя из вашей базы данных. Есть большая разница между этим дважды или только один раз. В этом случае существует четкая разница между obj.method(obj, etc)
и obj:method(etc)
.