Bind function with self in single line in Lua - lua

I would like to have a function pointer (don't know what the term is in Lua) that has the self pointer baked in.
A concept example
x = {text = "hello there"}
function x.hello(self)
print(self.text)
end
--- This is where I'm stuck
function_pointer = ???
function_pointer() -- Expected behaviour is to call x:hello() but how
Is there any way possible to bake the self pointer into a function (pointer)? Like that?

Another (easy/lazy) way is to construct the table itself as a function for its content.
This is done with setmetatable() and the __call Metamethod.
x = setmetatable({text = "Hello there"}, {__call = function(self) print(self.text) end})
x() -- Hello there
-- A pointer will be...
fp = getmetatable(x).__call
fp(x) -- Hello There
PS: You are totally free to choose the Name for self
x = setmetatable({text = "Hello there"}, {__call = function(this) print(this.text) end})
...especially the 'Basic People' will using this ;-)
It is only the first Element in the Chain of Arguments...
local func = function(...) print(({...})[1].text) end -- Anonymous "self"
x = setmetatable({text = "Hello there"}, {__call = func})

Related

Lua `local a = {b=func1}`

I am new to lua and encountered the following piece of code
function X()
local function Y() ... end
local var1 = {var2=Y}
...
return blah
end
What does local var1 = {var2=Y} do/mean here?
Thanks!
Jumped the gun on this one. Seems like it simply declares an associative array (table) with key as "var2" and value as Y. Equivalent to the following:
local function Y() ... end
local var1 = {}
var1['var2'] = Y
More details here: How to quickly initialise an associative table in Lua?

In Lua, how does a = Account:new{balance = 0} work or is it a typo?

On the Lua website https://www.lua.org/pil/16.1.html , there is this section of code
function Account:new (o)
o = o or {} -- create object if user does not provide one
setmetatable(o, self)
self.__index = self
return o
end
a = Account:new{balance = 0}
a:deposit(100.00)
Shouldn't the line a = Account:new{balance = 0} be written as a = Account:new(balance = 0) with the brackets being replaced with parentheses because it is a function?
Account:new { balance = 0 } is syntactic sugar for Account:new({ balance = 0 }).
This is, if the only argument passed to a function is a table constructor, or string literal, then the parenthesis can be omitted.
The most common place you'll see this is in lines with require:
local env = require 'env'
This is discussed in §3.4.10 – Function Calls of the Lua Reference Manual:
A call of the form f{fields} is syntactic sugar for f({fields}); that is, the argument list is a single new table. A call of the form f'string' (or f"string" or f[[string]]) is syntactic sugar for f('string'); that is, the argument list is a single literal string.

Is it possible to define functions globally in Lua's table

How to define functions into lua's table? I try this code but doesn't work.
I want to use table:myfunc().
local myfunc
myfunc = function(t)
local sum = 0
for _, n in ipairs(t) do
sum = sum + n
end
return sum
end
mytable = {
1,2,3,4,5,6,7,8,9
}
print(myfunc(mytable)) -- 45
I think myfunc has not problem.
table.myfunc = myfunc
print(mytable:myfunc())
-- lua: main.lua:18: attempt to call method 'myfunc' (a nil value)
-- stack traceback:
-- main.lua:18: in main chunk
-- [C]: ?
print(mytable) shows table: 0x9874b0, but it is not defined function to the table?
mytable.myfunc = myfunc
print(mytable:myfunc()) -- 45
This worked. Is it the only prefer way to do this?
there are plenty of ways to define a function within a table.
I think the problem with your first code is that you have this:
table.myfunc = myfunc
where it should be:
mytable.myfunc = myfunc
In your case mytable.myfunc is nil as you never assigned a value to it
You could just write
local mytable = {}
function mytable.myfunction()end
or
mytable.myfunction = function()end
or
mytable["myfunction"] = function()end
or define myfunc separately and assign it to mytable.myfunc later like you did
If you want to access other table members from your function I recommend defining the function like that:
function mytable:myfunc()end
which is syntactic sugar for
function mytable.myfunc(self)end
If you do so you can access mytable's member trough the keyword self
In your case it would end up like:
function mytable:myfunc()
local sum = 0
for _, n in ipairs(self) do
sum = sum + n
end
return sum
end
So you don't need the function parameter t anymore and you can run the desired mytable:myfunc()
Otherwise you would have to write mytable:myfunc(mytable).
table.myfunc = myfunc
print(mytable:myfunc())
This cannot work, because mytable has no member called myfunc, table does.
you would either have to write
table.myfunc = myfunc -- assign myfunc to TABLE (not the same as mytable)
print(table.myfunc(mytable)) -- as with most other functions in table
or
mytable.myfunc = myfunc -- assign myfunc to MYTABLE
print(mytable:myfunc()) -- syntactic sugar for print(mytable.myfunc(mytable))
also, you can just define the function as either
function mytable:myfunc() -- syntactic sugar for mytable.myfunc(self)
-- do something
-- use "self" to access the actual table
end
or
function table.myfunc(t)
-- do something
end

Does the 'for in ' loop call function in Lua?

There is a piece of code confuses me in Programming in Lua
local iterator -- to be defined later
function allwords ()
local state = {line = io.read(), pos = 1}
return iterator, state
end
function iterator (state)
while state.line do -- repeat while there are lines
-- search for next word
local s, e = string.find(state.line, "%w+", state.pos)
if s then -- found a word?
-- update next position (after this word)
state.pos = e + 1
return string.sub(state.line, s, e)
else -- word not found
state.line = io.read() -- try next line...
state.pos = 1 -- ... from first position
end
end
return nil -- no more lines: end loop
end
--here is the way I use this iterator:
for i ,s in allwords() do
print (i)
end
It seems that the 'for in ' loop call the function iterator implicitly with argument state:
i(s)
Anyone can tell me ,what happened?
Yes. Quoting Lua Manual
The generic for statement works over functions, called iterators. On each iteration, the iterator function is called to produce a new value, stopping when this new value is nil.
The generic for statement is just a syntax sugar:
A for statement like
for var_1, ···, var_n in explist do block end
is equivalent to the code:
do
local f, s, var = explist
while true do
local var_1, ···, var_n = f(s, var)
if var_1 == nil then break end
var = var_1
block
end
end

What is the difference between local function myFunction and local myFunction = function()

I know this question seems simple, but I want to know the difference between two ways of creating functions in Lua:
local myFunction = function()
--code code code
end
Or doing this
local function myFunction()
--code code code
end
The difference happens if the function is recursive. In the first case, the "function" name is not yet in scope inside the function body so any recursive calls actually refer to whatever the version of "myFunction" that was in scope before you defined your local variable (most of the times this meas an empty global variable).
fac = "oldvalue"
local fac = function()
print(fac) --prints a string
end
To be able to write recursive functions with the assignment pattern, one thing you can do is predeclare the variable:
local myFunction
myFunction = function()
-- ...
end
Predeclaring variables also happens to be the only way to define a pair of mutually recursive local functions:
local even, odd
even = function(n) if n == 0 then return true else return odd(n-1) end end
odd = function(n) if n == 0 then return false else return even(n-1) end end
The difference is that according to the manual:
The statement
local function f () body end
translates to
local f; f = function () body end
not to
local f = function () body end
(This only makes a difference when the body of the function contains references to f.)
The main reason is that the scope of a variable (where the variable is visible) starts AFTER the local statement, and if a function was recursive, it would not reference itself, but a previous local or a global named f.

Resources