Это не ошибка интерпретатора, это разработанное поведение языка.o={}
создает глобальную переменную, которую программист здесь не ожидает."Почему это так?"это частый вопрос к создателю языка. много усилий , чтобы упростить управление этим поведением.
o = {}
без local
создает глобальную переменную. Глобальная переменная доступна и используется всеми функциями в программе, если вы не используете причудливые методы определения объема среды.Использование глобальной переменной внутри функции открывает двери для различных побочных эффектов, вы должны быть осторожны с побочными эффектами.
Я удалил часть синтаксического сахара, и добавленный выше код можно эквивалентно записать следующим образом:
Object.new = function(table_before_colon,arg)
highlander = {} --global variable, there can be only one
setmetatable(highlander,table_before_colon);
table_before_colon.__index = table_before_colon;
highlander:load(arg) -- table_before_colon.__index.load(highlander,arg)
return highlander
end
local Ship = Object:new()
--global highlander == Ship
--Ship.new points to Object.new
function Ship:load(arg)--equivalent to: Ship.load=function(self,arg)
--code that sets fields of the `self` object and is called from within new
self.x = arg.x or 0 -- equivalently highlander.x=arg.x or 0
end
Теперь наличие глобальной переменной не имело бы значения, если бы с ней ничего не произошло в период с начала new
до возвращения new
.Но, очевидно, ваш другой код похож на этот:
local OtherObject = Object:new()
--otherObject == highlander
OtherObject.load = function(new_other_obj,arg)
--highlander == new_other_obj
new_other_obj.ship1 = Ship:new({x=50, y=self.y1, s=2, tint={0, 0.5, 1}})
--highlander == new_other_obj.ship1
new_other_obj.ship2 = Ship:new({x=750, y=self.y2, s=-2, tint={1, 0.5, 0}})
--highlander == new_other_obj.ship2
end
Итак, OtherObject.load
вызывает другие функции, и эти функции также получают доступ и изменяют ту же глобальную переменную.
local some_object = OtherObject:new()
возвращает глобальную переменную в том виде, как она есть в конце вызова, для которой в последний раз задается ship2
внутри вызова Ship:new
внутри вызова OtherObject.load
внутри вызова OtherObject:new
.