Аргументы требовать, чтобы функция терялась / исчезала в Lua? - PullRequest
0 голосов
/ 27 января 2019

Хотя я на самом деле не знаю Lua, это довольно неожиданное и странное поведение.

Допустим, у меня есть my_module.lua:

local function dump(o) -- SO:9168058
  if type(o) == 'table' then
    local s = '{ '
    for k,v in pairs(o) do
       if type(k) ~= 'number' then k = '"'..k..'"' end
       s = s .. '['..k..'] = ' .. dump(v) .. ','
    end
    return s .. '} '
  else
    return tostring(o)
  end
end


local mymodule = {}

function mymodule.myfunction(indict)
  print(dump(indict))
end

return mymodule

Хорошо, теперь я запускаю это:

lua5.3 -e "mm=require('my_module'); mm:myfunction({aa=12})"

Это не должно быть сложным - я «импортирую» модуль и вызываю в нем функцию с аргументом, который является объектом (таблица / ассоциативный массив / словарь {aa=12}).Затем я просто пытаюсь напечатать этот аргумент из функции.Тем не менее, я получаю это:

$ lua5.3 -e "mm=require('my_module'); mm:myfunction({aa=12})"
{ ["myfunction"] = function: 0x5619aeddf770,} 

Итак, ответ на print(dump(indict)) внутри myfunction, где indict - аргумент, переданный myfunction, Lua печатает .... "myfunction"????!

Я даже не могу обдумать это - как это может произойти?

И как я могу передать объект в качестве аргумента функции, такой, что когда явывести аргумент из функции, вывести объект, который является аргументом, а не саму функцию ??!

Кстати, то же самое происходит, даже если я просто передам число вместо объекта, скажем:

lua5.3 -e "mm=require('my_module'); mm:myfunction(42)"

РЕДАКТИРОВАТЬ: сделал небольшую отладку - вот с этим:

function mymodule.myfunction(indict)
  print(indict)
  print(dump(indict))
end

... Я получаю эту распечатку при использовании числового аргумента:

$ lua5.3 -e "mm=require('my_module'); mm:myfunction(42)"
table: 0x55f15a7a07a0
{ ["myfunction"] = function: 0x55f15a7a07e0,} 

... поэтому он просто нигде не видит это число, но функция видит себя в качестве первого аргумента.

Это напомнило мне, как в классе Python вы должны писать методыкак функции с «я» в качестве первого аргумента, поэтому я попытался это:

function mymodule.myfunction(self, indict)
  print("self", self, "indict", indict)
  print(dump(indict))
end

... который печатает:

$ lua5.3 -e "mm=require('my_module'); mm:myfunction(42)"
self    table: 0x560510b5a7d0   indict  42
42

... или в случае передачи объекта:

$ lua5.3 -e "mm=require('my_module'); mm:myfunction({aa=12})"
self    table: 0x55d51c9d5800   indict  table: 0x55d51c9d5880
{ ["aa"] = 12,} 

... ну, это больше похоже на это ...

Может кто-нибудь объяснить, откуда это взялось - почемумне нужно добавить аргумент "self" в этом случае?

1 Ответ

0 голосов
/ 27 января 2019

В lua вызов a:b(x) передает ссылку на объект a в качестве первого (self) параметра в функцию b.

Поскольку определение вашего модуля:

function mymodule.myfunction(indict)

и оператор вызова mm:myfunction, объект / таблица mm передается в качестве первого параметра (здесь indict).

Либо измените определение функции на

function mymodule:myfunction(indict)

если вы хотите сохранить вызов как mm:myfunction или вызвать функцию как mm.myfunction.


Поведение подробно обсуждается в книге PiL о концепции ООП.

Эффект двоеточия заключается в добавлении дополнительного скрытого параметра в определение метода и добавление дополнительного аргумента в вызове метода. двоеточие является только синтаксическим средством, хотя и удобным; там здесь нет ничего нового.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...