Getting access to parameter inside a string being executed with 'load' - lua

I would like to know if there's a way for the 'load' function to get a variable value from a local variable instead of a global variable ?
Say that I've got a string like this 'trade.version == 2' that I want to execute with the 'load' function inside a function taking the trade as parameter.
function doTest( trade, test )
-- inside the string 'test', I would like that any reference to 'trade'
-- refer to the function parameter instead of a global variable
if ( assert(load("return "..test))() ) then
-- do something
end
end
a_userdata = { version = 2 }
-- Calling the function above
doTest( a_userdata , "trade.version == 2" )
[string "return trade.version == 2"]:1: attempt to index global 'trade' (a nil value)
stack traceback:
[string "return trade.version == 2"]:1: in main chunk
stdin:2: in function 'doTest'
stdin:1: in main chunk
[C]: in ?
As a workaround, I have defined a global variable and it's working pretty fine.
But I would like to avoid this global variable.
Thank you very much

function doTest( trade, test )
-- inside the string 'test', I would like that any reference to 'trade'
-- refer to the function parameter instead of a global variable
if assert(load("local trade = ...; return "..test))(trade) then
-- do something
print('Yes, version equals to 2')
end
end
a_userdata = { version = 2 }
-- Calling the function above
doTest( a_userdata , "trade.version == 2" )

Related

call function into function in lua

i have code in my lua file and i edit that to look like this
function getUserinfo(user_id)
function call_back_user_info(status , result)
t = {["first_name"]= result.first_name_, ['have_access']= result.have_access_, ["last_name"]=result.last_name_,["user_name"]=result.username_}
return t
end
getUser(user_id,call_back_user_info)
end
i need to return t table value when i call getUserinfo function.but it is get me a nil value !
note :getUser function puts data in to call_back_user_info
how i can resolve this problem? thank
You can't do a "long return" which returns from an outer function from inside of an inner function.
But what you can do is create a local variable which is closed over, like this:
function getUserinfo(user_id)
local t
function call_back_user_info(status , result)
t = {["first_name"]= result.first_name_,
['have_access']= result.have_access_,
["last_name"]=result.last_name_,
["user_name"]=result.username_}
end
getUser(user_id,call_back_user_info)
return t
end

why passing an argument to lua class method get nill

I have a method that builds a Tree from a parent list pointer in lua.
In particular I have this lua table
parents = {2,3,13,5,12,7,11,9,10,11,12,13,14,0}
Along with two functions:
Function 1 (creates the node):
function create_node(parent, i, created, root)
if created[i] ~= nil then
return
end
print(i)
-- print(parent)
-- Create a new node and set created[i]
local new_node = Tree()
new_node.idx = i
created[i] = new_node
-- If 'i' is root, change root pointer and return
if parent[i] == 0 then
root[1] = created[i] -- root[1] denotes root of the tree
return
end
-- If parent is not created, then create parent first
if created[parent[i]] == nil then
create_node(parent, parent[i], created, root )
end
print(i)
-- Find parent pointer
local p = created[parent[i]]
print (p)
if #p.children <=2 then
print(p.idx)
print(created[i].idx)
p.add_child(created[i])
end
end
Function 2 (creates the tree recursively):
I have stopped the loop at one to test the first path from leaf to root i.e 1-2-3-13-14
function read_postorder_parent_tree(parents)
n = #parents
-- Create and array created[] to keep track
-- of created nodes, initialize all entries as None
created = {}
root = {}
for i=1, 1 do
create_node(parents, i, created, root)
end
return root[1]
end
The create_note method uses the below Tree class:
local Tree = torch.class('Tree')
function Tree:__init()
self.parent = nil
self.num_children = 0
self.children = {}
end
function Tree:add_child(c)
print(c)
c.parent = self
self.num_children = self.num_children + 1
self.children[self.num_children] = c
end
Everything works fine but when I call p.add_child(created[i]) the argument is nil why? (why c is nil?) I have already checked that created[i] and p are not nil. How can i solve this and/or why this happening?
This is the error that I get:
./Tree.lua:16: attempt to index local 'c' (a nil value)
stack traceback:
./Tree.lua:16: in function 'add_child'
main.lua:120: in function 'create_node'
main.lua:109: in function 'create_node'
main.lua:109: in function 'create_node'
main.lua:109: in function 'create_node'
main.lua:134: in function 'read_postorder_parent_tree'
main.lua:153: in function 'main'
main.lua:160: in main chunk
[C]: in function 'dofile'
...3rto/torch/install/lib/luarocks/rocks/trepl/scm-1/bin/th:150: in main chunk
[C]: at 0x00405d50
If you define a function in an object-oriented way, you must also call it in the same way.
function Tree:add_child(c)
This declares a function in an object-oriented way using the colon operator. To help you understand what that means, it can be rewritten like this:
Tree.add_child = function(self, c)
As you can see, an implicit self parameter is created to reflect the object the function was called on. However, you call the function via the standard way:
p.add_child(created[i])
Now you can see that what you really did was pass created[i] as self, not as c, which then of course happens to be nil. The standard way to call such a function is also via the colon operator:
p:add_child(created[i])
This implicitly passes p as self to the actual function, and now p will contain the actual argument.

Store function to indexed arrays and call him with undefault param

I'm trying to create and indexed array of functions to call him with changed params, like this:
local function wubba(lubba)
return lubba
end
local dub = {
["wubba"] = {func = wubba(lubba)}
}
print(dub["wubba"].func("hi"))
But in all my tries i got errors, i can't figure out how to do it. Anyone can help me?
lua: wubba.lua:9: attempt to call field 'func' (a nil value)
stack traceback:
wubba.lua:9: in main chunk
[C]: in ?
Solved, just not to store with params:
local dub = {
["wubba"] = {func = wubba}
}

lua's loadstring() not working with tables

I have some text and I'm trying to load it via load string. The following works:
local m = loadstring("data = 5")()
But when the data is a table it doesn't work and gives the error "attempt to call a nil"
local m = loadstring("data = { 1 = 10}")()
The table declaration in lua require integer keys to be put inside square brackets:
data = {
[1] = value,
}
The enclosing of keys in square brackets is always allowed, valid and possible. It can be skipped iff your key follows the pattern: [A-Za-z_][A-Za-z0-9_]* (which is the same as a valid variable name in lua)
If you had added an assert you would have got a more helpful message:
local m = assert (loadstring("data = { 1 = 10}"))()
Result:
stdin:1: [string "data = { 1 = 10}"]:1: '}' expected near '='
stack traceback:
[C]: in function 'assert'
stdin:1: in main chunk
[C]: ?
And to actually answer the question, unless the table key happens to follow Lua variable naming rules, you have to put it inside square brackets, eg.
local m = assert (loadstring("data = { [1] = 10}"))()
m is still nil when I do this
What does that matter? The loadstring is done.
Just do this:
assert (loadstring("data = { 1 = 10}"))()
print (data [1])
You don't need the variable m. The loadstring puts a table into data - that is the important thing.

Metatables, attempt to call method 'rename' (a nil value)

This is my first time using metatables, I did a simple script to test in Lua demo but it always give me "attempt to call method 'rename' (a nil value)", why?
peds = {}
function peds.new ( name )
local tb = { name = name }
setmetatable ( tb, { __index = peds } )
return tb
end
function peds.rename ( name )
self.name = name
return self.name == name
end
local ped = peds.new ( "max" )
ped:rename ( "randomname" )
There's two (possible) problems in your code, depending on how you are setting things up.
If you are just typing the above into a REPL, then when you declare local ped = ... it immediately goes out of scope and becomes inaccessible. So the expression ped:rename is invalid, although it should report "ped is nil" not "rename is nil".
If you are saving the above to a script and loading it using load_file or something, you will still get a problem, because this function signature isn't right:
function peds.rename ( name )
should be:
function peds.rename ( self, name )
Similar to how it works in C++, in lua, when you make an object method, you have to take the hidden self parameter first, and when you call ped:rename( "random name" ) that's just syntactic sugar for ped.rename(ped, "random_name"). If the self parameter doesn't exist then it's not going to work, or may even say "function not found / rename is nil" because the signatures don't match up.

Resources