Returning a class in Lua - lua

I'm trying to create a plugin but I can't seem to access the returned player class from outside the GetPlayer() function.
This is the GetPlayer Fuction:
function GetPlayer(Player_To_Find) -- This is the function we use to verify the user exists, It will return the user class if the user exists
LOG("Finding " .. Player_To_Find) --False if they do not exist
local Found = false
local FindPlayer = function(TargetPlayer)
if (TargetPlayer:GetName() == Player_To_Find) then
Found = true
print("Found " .. TargetPlayer:GetName())
return TargetPlayer
end
end
cRoot:Get():FindAndDoWithPlayer(Player_To_Find, FindPlayer)
if Found == true then return TargetPlayer else return false end
end
If I try to call the TargetPlayer class after it has returned using this snippet:
TargetPlayer=GetPlayer(Target)
if TargetPlayer ~= false then
LOG(TargetPlayer:GetName())
It will fail with the error:
attempt to index global 'TargetPlayer' (a nil value)
Can anyone point me in the right direction, It's taken me a long time and I've come up blank.

The parameter TargetPlayer is only in scope in the function body. The TargetPlayer in the last line of GetPlayer refers to a global variable, which is presumably nonexistent and therefore nil.
Declare a local variable in the GetPlayer function, set it in the body of the FindPlayer function, and return it at the end of the of GetPlayer (also don't return false if a player can't be found, return nil, which semantically means "nothing").

Related

Can anyone tell me that the error "calling xxxx on bad self" shows

I use lua in Unity. When I call the function **TryDisableHeadWear **, there are some error I can't understand.
calling 'GetSurfaceName' on bad self (string expected, got nil)
function def:TryDisableHeadWear()
if not self:CheckSurfaceName(self._hat_go) then
self._hat_go:SetActive(false)
end
end
function def:CheckSurfaceName(obj)
local surface_name = self:GetSurfaceName(obj)
return head_wear_surface[surface_name] ~= nil
end
local reg = "(%w+)"
function def:GetSurfaceName(obj)
if not obj then return end
local root_obj = self:GetSurfaceObj(obj)
local surface_obj_name = root_obj and root_obj.name
return surface_obj_name and string.match(surface_obj_name, reg)
end
function def:GetSurfaceObj(obj)
if string.find(obj.name, "Surface") then
return obj
else
local parent = obj.transform.parent
if not parent then return end
return self:GetSurfaceObj(parent.gameObject)
end
end
Can anyone tell me what the error means?
I try to call the function in normal environment. I get no error and everything goes well. But where are some error report in firebase that means the code above has bugs

Attempt to index a boolean value error when calling this function

I get the attempt to index a boolean value error when calling this function:
M.on_attach = function(client, bufnr)
if client.name == "tsserver" then
client.resolved_capabilities.document_formatting = false
end
lsp_keymaps(bufnr)
lsp_highlight_document(client)
end
Can anyone help me?
Edit:
I get the error on the second line here:
local opts = {
on_attach = require("s3m.lsp.handlers").on_attach,
capabilities = require("s3m.lsp.handlers").capabilities,
}
require("s3m.lsp.handlers") returns true which is a boolean value. with require("s3m.lsp.handlers").on_attach you index that nil value which is an invalid operation in Lua.
For this to make sense your required script must return a value. In your case M
require returns true if the script is loaded successfully but does not return a non-nil value. Please read the manual to avoid such errors.

Attempt to index field (nil value)

Whenever I try to use Body.pos, it always says that it is a nil value. But it is assigned a value in the new function, so it should not be nil.
My code:
Vector={
x=nil,y=nil
,new=function (self,x,y)
o={}
setmetatable(o,self)
self.__index=self
o.x=x or 1
o.y=y or 1
return o
end
-- utility functions here
}
Body={
pos=nil
,vel=nil
,acc=nil
,mass=nil
,new=function (self,pos,vel,acc,mass)
o={}
setmetatable(o,self)
self.__index=self
o.pos=pos or Vector:new()
o.vel=vel or Vector:new()
o.acc=acc or Vector:new()
o.mass=mass or 1
return o
end
,applyForce=function (self,v)
self.acc:add(v:scale(1/self.mass))
end
,applyGravity=function (self)
self.acc:add(GRAVITY_VECTOR)
end
,step=function (self)
self.vel:add(self.acc)
self.pos:add(self.vel)
self.acc:scale(0)
end
}
Trial code:
b=Body:new()
print(b.pos.x) -- shows error that pos is nil
Vector:new() does not return nil, but still Body.pos is always nil. I don't know what I am doing wrong here.
EDIT: Added Vector implementation
The issue is your OOP implementation. The metatable o needs to be set as a local variable.
In your code o is a global variable hence why you always reset it when you create a new object.
Vector={
-- ...
,new=function (self,x,y)
local o={}
-- ...
end
-- ...
}
Body={
-- ...
,new=function (self,pos,vel,acc,mass)
local o={}
-- ...
return o
end
-- ...
}
b=Body:new()
print(b.pos.x) -- 1
Basically any variable that isn't declared as local is automatically put into the global scope.
Additionally I recommend using a linter (e.g. luacheck) to automatically detect issues like this.

Lua : return table trough function is nil

I get the error: source_file.lua:5: attempt to call a nil value (global 'getCard')
i try to catch the right table in questCards which Index=name is the same as the given string from objName
questCards={{['name']='test1',['creatureName']='test3'},{['name']='test2',['creatureName']='test4'}}
obj='test1'
card=getCard(obj)
card['creatureName']=nil --Only for test purpose
if card['creatureName']==nil then
--do Somthing
end
function getCard(objName)
for k,v in pairs(questCards) do
if v['name']==objName then
return v
end
end
end
The error message is telling you that getCard is not defined at the point where it is called.
You need to define getCard before calling it.

attempt to index local 'self' using MOAICoroutine in Lua

I am just starting with MOAI and I am trying to create a traditional game loop using MOAICoroutine. The problem is that when I pass it the function that is part of a "class" that is built using 30log, it returns an error. It seems to continue to function, but I would like to fix the error. My guess is that the MOAICoroutine is calling the function using the dot notation rather than the syntactical sugar method with a colon. Here is the code:
class = require "30log.30log"
GameSystem = class ()
function GameSystem:__init(Name, Title)
self.Name = Name
self.Title = Title
self.Ready = false
end
function GameSystem:Run()
if self:Init() then
self.Thread = MOAICoroutine.new ()
self.Thread:run(self.Start)
--self:Start()
return true
else
print("Init failed.")
return false
end
end
function GameSystem:Init()
print("Initializing Game System")
if not self:InitTimer() then return false end
if not self:InitWindow(640,480) then return false end
if not self:InitViewport() then return false end
if not self:InitGraphics() then return false end
if not self:InitSound() then return false end
if not self:InitInput() then return false end
self.Ready = true
return true
end
function GameSystem:Start()
print("Starting Game System")
while self.Ready do
self:UpdateTimer()
self:UpdateGraphics()
self:UpdateSound()
self:UpdateInput()
coroutine.yield()
end
end
function GameSystem:InitTimer()
return true
end
function GameSystem:InitWindow(width, height)
print("Initializing Window")
return true
end
function GameSystem:InitViewport()
print("Initializing Viewport")
return true
end
function GameSystem:InitGraphics()
print("Initializing Graphics")
return true
end
function GameSystem:InitSound()
print("Initializing Sound")
return true
end
function GameSystem:InitInput()
print("Initializing Input")
return true
end
function GameSystem:UpdateTimer()
--print("Updating Timer")
return true
end
function GameSystem:UpdateGraphics()
--print("Updating Graphics")
return true
end
function GameSystem:UpdateSound()
--print("Updating Sound")
return true
end
function GameSystem:UpdateInput()
--print("Updating Input")
return true
end
Is the 30log class code causing this problem? I have tried various things. I am pretty sure the self it is trying to access is the first argument i.e. mytable.myfunction(self, myarg). Any ideas to fix this nil value reference. The error actually occurred on the second line inside the Start function (while self.Ready do).
function GameSystem:Run()
if self:Init() then
self.Thread = MOAICoroutine.new ()
self.Thread:run(self.Start)
My guess is that the MOAICoroutine is calling the function using the dot notation rather than the syntactical sugar method with a colon.
How would it be calling the function using dot notion (or colon notation)? What would be on the left side of the period or colon? You haven't passed it an object, only a function. The fact that it's caller was storing that function in a table is completely unknown to it. It just receives a function, and calls it.
If you want your coroutine to start with a method call, do that in the function you pass to coroutine.start:
self.Thread = MOAICoroutine.new ()
self.Thread:run(function() self:Start() end)
The point is that:
function GameSystem:Start()
end
Is exactly equivalent to:
function GameSystem.Start(self)
end
Is exactly equivalent to:
GameSystem.Start = function(self)
end
Is equivalent to:
function Foobar(self)
end
GameSystem.Start = Foobar
If I call:
print(Foobar)
print(GameSystem.Start)
print(someGameSystemInstance.Start)
print receives the same value. In Lua, a function is a function is a function, it's not "tainted" in some way by being stored in a table, such that a third party with a reference to the function can know that you want it to be called as a method to some particular 'class instance.

Resources