lua - differece of : and . when define function? - lua

hope you having great day , i'm test some stuff with lua, and i got some error
i have this codes in Object.lua
local Object = {name = "Object"}
Object.__index = Object
function Object.new()
local t = setmetatable({}, Object)
return t
end
function Object:keys(table)
local keyset={}
local n=0
for k,v in pairs(table) do
n=n+1
keyset[n]=k
end
return keyset
end
return Object
and i call Object.keys in "Other" script like this
local Object = require("lua.app.common.utils.Object")
local t = {
[1] = a,
[2] = b,
[3]= c
}
Object.keys(t)
and this cause error with
Exception has occurred: bad argument #1 to 'for iterator' (table expected, got nil),
because the parameter 'table' is passed as nil ( i don't know why thuogh debug mode just says its a nil)
on the other hand, if i fix object.keys(table) to object:keys(table), everything works fine, why this error happening?

Declaring the method keys with a colon adds an implicit self parameter as the first argument which requires you to call the method in the same way, using the colon.
Calling the method with the period notation expects you to supply the self parameter but because you only pass in t this is interpreted as self and then nil is added for your table parameter.
Declaring the method with a colon you actually have this
function Object:keys(self, table)
but calling it with the period means you have done this
Object.keys(t, nil)
hence the "table expected, got nil" error

Related

Dynamic reference to Lua table method, param passed in is null

I'm creating a dynamic table method reference and trying pass a single param to the method. The dynamic method reference does work and the table method is called just as expected, however the completely not nil param I'm passing to the method is nil inside the method. Can you point out my error in these 2 lines?...
Here is a small working example that demonstrates. On first line in the Consider:Move method, mons is nil
local Consider = {}
function Consider:Move( mons )
print( 'Mons ' .. mons.type .. ' considering Move...')
actionChosen.score = 0
return actionChosen
end
local mons = { type = 'Blue' }
local actionPref = 'Move'
local considerAction = Consider[actionPref]
print( 'MonsterAI:chooseAction mons: ', mons.type )
local actionTest = considerAction( mons )
Functions defined using the colon operator hides an additional first self argument. function Consider:Move(mons) is syntactic sugar for function Consider.Move(self, mons).
Calling the function like considerAction(mons) sets the hidden self argument instead of the desired one.
You might want to pass the Consider table as self:
considerAction(Consider, mons)
Or, alternatively, define the function using the dot operator if you don't need self:
function Consider.Move(mons)
print('Mons ' .. mons.type .. ' considering Move...')
end

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.

lua table global/local var getting confused

I have a lua table which I used to share values between files. But I am getting confused in the following case
utility.lua file
M = {}
M.host_url = '192.168.0.1'
function M.myFunc()
print(M.host_url )
end
return M
in my main.lua
utility = require('utility')
utility.myFunc() -- this gives me 'a nil value' error
I get an error (nil value) for the host_url?
In M.myFunc doing only print action that function nothing will be return.in your utility file returning whole array see he below code that will clear your doudt.
In main.lua
utility = require('util')
value = utility.host_url
print(value)

accessing lua self member got nil

I was trying to access a member of 'self', see following:
function BasePlayer:blah()
--do blah
end
function BasePlayer:ctor(tape) --constructor.
self.tape = tape --'tape' is a lua table, and assigned to 'self.tape'.
dump(self.tape) --i can dump table 'self.tape',obviously it's not nil.
self.coreLogic = function(dt) --callback function called every frame.
echoInfo("%s",self) --prints self 'userdata: 0x11640d20'.
echoInfo("%s",self.tape) -- Here is my question: why self.tape is nil??
self:blah() --even function too??
end
end
So my question is, in my callback function 'coreLogic', why 'self.tape' is nil but self is
vaild?
And functions can't be called either.
I'm really confused:S
When you define a function using the :, the implicit parameter is created on its own. When you are defining the function coreLogic, you'd need to pass it as the first argument:
self.coreLogic = function( self, dt )
and that would be the same as:
function self:coreLogic(dt)
self in itself doesn't exist.
Basically,
function BasePlayer:blah()
is same as writing:
function BasePlayer.blah( BasePlayer )

_ENV & classes in Lua are not being compatible

_ENV currently hates using classes. I'm attempting to create a Latin kind of Lua, and some things can't precisely be made with _ENV but it's a lot more efficient. setfenv was being uncooperative as well.
The subsequent code keeps returning the old attempt to call a nil value error. It specifies line 20, in which loadstring() is being checked, and line 23, where in the main chunk it is calling the __latin() function.
function __latin(code)
__predecessor = [===[
function typographia(value)
print(value);
end
chorda = {};
chorda.__index = chorda;
function chorda.sub(chorda, cChorda, fChorda)
return string.sub(chorda, cChorda, fChorda);
end
function chorda:sub(chorda, cChorda, fChorda)
return string.sub(chorda, cChorda, fChorda);
end
--[[ define values --]]
_ENV = {salve="Salve, munde!",typographia=typographia,print=print,chorda=chorda,chorda.sub=chorda.sub}; ]===];
__finalizer = __predecessor .. " " .. code;
local status, err = pcall(loadstring(__finalizer));
print(err);
if (err == nil) then loadstring(__finalizer)(); end
end
__latin('typographia(salve); chorda.sub(salve, 1, 3);');
You're getting "attempt to call a nil value" because loadstring returns nil (so you're calling pcall with nil). loadstring returns nil because the code you're compiling (__predecessor) contains invalid Lua:
_ENV = {
chorda.sub = chorda.sub -- can't do this
}
FYI: The loadstring/pcall stuff is irrelevant to your problem. Had you stripped it out before posting, you would have found this error yourself.

Resources