Как работи setmetatable() и защо метатаблицата е необходима в свързания списък в lua

Научавам как метатаблиците на Lua работят в OOP и съм объркан от кода, който прочетох от урока за обектна ориентация в lua-users wiki. Може ли някой да помогне с обяснението на следните въпроси? Благодаря.

Въпрос 1: Обяснението на wiki: Тук добавяме метатаблица към таблицата на класа, която има метаметода __call, който се задейства, когато дадена стойност се извиква като функция. Правим го да извиква конструктора на класа, така че нямате нужда от .new, когато създавате екземпляри.

(1) Как се извиква __call в примера, така че да се извика конструкторът?
(2) "cls" препраща ли към "MyClass?"

setmetatable(MyClass, {
  __call = function (cls, ...)
  return cls.new(...)
end,
})

Въпрос 2: Какво означава {} от следния код?

function MyClass.new(init)
  local self = setmetatable({}, MyClass)
  self.value = init
  return self
end 

**Ето пълния код:

local MyClass = {}
MyClass.__index = MyClass

setmetatable(MyClass, {
  __call = function (cls, ...)
  return cls.new(...)
end,
})

function MyClass.new(init)
  local self = setmetatable({}, MyClass)
  self.value = init
  return self
end

function MyClass:set_value(newval)
  self.value = newval
end

function MyClass:get_value()
  return self.value
end

local instance = MyClass(5)
-- do stuff with instance...

person LED Fantom    schedule 12.12.2014    source източник
comment
Тази заявка за търсене съдържа малко информация за Lua metatables: google.com/?gws_rd= ssl#q=lua+metatables   -  person Anderson Green    schedule 12.12.2014


Отговори (1)


Въпрос 1:

setmetatable(MyClass, {
  __call = function (cls, ...)
  return cls.new(...)
end,
})

Това задава метатаблицата на MyClass на таблица, която дефинира метаметода __call. Поради това можете да "извикате" MyClass (newObj = MyClass(<args>)). В метаметода cls се отнася до извиканата таблица, в този случай се отнася до MyClass.

Въпрос 2:

function MyClass.new(init)
  local self = setmetatable({}, MyClass)
  self.value = init
  return self
end

{} е синтаксис за табличен литерал, който създава нова таблица (в този случай празна). Таблицата MyClass е зададена като метатаблица за нова таблица. След това тази нова таблица се присвоява на себе си.

Повече за метатаблиците можете да намерите тук: https://www.google.com/?gws_rd=ssl#q=lua+metatables, както е предложено от Anderson Green в коментарите.

person InputUsername    schedule 14.12.2014