Lua class not working - lua

I have a simple class implementation in Lua.
test = {}
test.__index = test
function test:new()
local o = {}
setmetatable(o, self)
return o
end
function test:setName(name)
self.name = name
print name
end
local name = test:new()
name:setName("hello")
I keep getting this error when I run it:
lua: test.lua:12: '=' expected near 'name'
I not sure what or why this happening, any help would be greatly appreciated.

Change print name to print(name). print is just a regular function and function calls need parentheses unless they are called with a single argument that is either a string literal or a table literal.

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?

How to have function as field value in a lua table, when the function is declared at a later point?

I have the following scenario in which the position of code shall not change. How to modify this code to fix the error without moving the function and table variable. I am a Lua newbie, just 4 days
function a()
print("function a");
end
ftable = {
["a"] = a,
["b"] = b
};
function b()
print("function b");
end
ftable["a"](); -- prints 'function a'
ftable["b"](); -- attempt to call field 'b' (a nil value)
Update : Using the following mechanism its possible to do this.
function a()
print("function a");
end
ftable = {
["a"] = a,
["b"] = "b"
};
function b()
print("function b");
end
ftable["a"](); -- prints 'function a'
_G[ftable["b"]]();
Lua's table declaration and function definition (and function calling syntax) is very flexible. You can use the field key as an identifier instead of the index syntax, provided that the key is a string and is also a valid identifier ({ a = a } and ftable.a()). This seems to be the case with your a and b keys. You can also make the field assignment with the function definition statement (function ftable.b…).
function a()
print("function a")
end
ftable = {
a = a
}
function ftable.b()
print("function b")
end
ftable.a() -- prints 'function a'
ftable.b() -- prints 'function b'
Of course, you could also move "function a" down and code it like "function b". that would leave ftable = { } at the top.
One difference from your code. The global variable b is no longer set to the function. In most cases, this would be considered an advantage.
I would also like to re-iterate what #lhf said,
There are no declarations in Lua, only definitions.
A function definition (in the general case) is an expression. When evaluated, it produces a function value. Various types of statements can assign the value to a variable or field, as does function ftable.b()….
You can't do that. There are no declarations in Lua, only definitions. You need to define variables before using them.
What you can do is to register the names of the functions in ftable and then fix the values before using them:
ftable = {
["a"] = true,
["b"] = true,
}
...
for k,v in pairs(ftable) do ftable[k]=_G[k] end
This code assumes that your functions are defined globally.

How to create a simple importable class in Lua?

I'd like to create MyClass class in Lua in a separate file myclass.lua which I can import and use later.
It should be working the following way:
local MyClass = require 'myclass'
tab = {1,2,3}
m = MyClass(tab)
However, following the code in Lua docs I can't make it work and am getting errors attempt to call global 'MyClass' (a table value).
The code I have written so far for myclass.lua:
local MyClass = {}
MyClass.__index = MyClass
function MyClass.__init(tab)
self.tab = tab or {}
setmetatable({},MyClass)
return self
end
return MyClass
There is a plethora of examples how to write classes in Lua but I don't think I understand the difference and as a result getting lost in the implementation details. Is there a more or less conventional way to do it?
In Lua, you cannot usually call a table like you would call a function. For example, this code will produce an error of "attempt to call local 't' (a table value)".
local t = {}
t()
There is a way of making this work by using metatables, however.
local hello = {}
local mt = {} -- The metatable
mt.__call = function ()
print("Hello!")
end
setmetatable(hello, mt)
hello() -- prints "Hello!"
When you try and call a table as you would a function, Lua first checks to see whether the table has a metatable. If it does, then it tries to call the function in the __call property of that metatable. The first argument to the __call function is the table itself, and subsequent arguments are the arguments that were passed when the table was called as a function. If the table doesn't have a metatable, or the metatable doesn't have a __call function, then an "attempt to call local 't'" error is raised.
Your example code has three problems:
You are trying to use __init instead of __call. Lua doesn't have an __init metamethod.
__call takes different parameters than the ones you are using. The first parameter to the __call function is the table itself. You can either use function MyClass.__call(self, tab), or use the colon syntax, function MyClass:__call(tab), which implicitly adds the self parameter for you. These two syntaxes are functionally identical.
You haven't set a metatable for the MyClass table. While you are setting a metatable for MyClass's objects, that doesn't mean that a metatable is automatically set for MyClass itself.
To fix this, you could do something like the following:
local MyClass = {}
setmetatable(MyClass, MyClass)
MyClass.__index = MyClass
function MyClass:__call(tab)
local obj = {}
obj.tab = tab or {}
setmetatable(obj, MyClass)
return obj
end
return MyClass
This sets MyClass to use itself as a metatable, which is perfectly valid Lua.
The system of metatables is very flexible, and allows you to have just about any class/object scheme you want. For example, if you want, you can do everything inline.
local MyClass = {}
setmetatable(MyClass, {
__call = function (class, tab)
local obj = {}
obj.tab = tab or {}
setmetatable(obj, {
__index = MyClass
})
return obj
end
})
return MyClass
As well as being concise, this also has the advantage that people can't change the class's metamethods if they have access to the class table.
There is no __init metamethod available for a table. When you do the following:
m = MyClass(tab)
it looks for the MyClass.__call method definition. Just update your myclass.lua as:
local MyClass = {}
MyClass.__index = MyClass
function MyClass:__call(tab)
self.tab = tab or {}
setmetatable({},MyClass)
return self
end
return MyClass

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.

lua interpreter, having to import file twice for full functionality

so i have a lua file analogous to this:
x = { __index = x}
constructor = function()
local o = {}
return setmetatable(o,x)
end
function x:print()
print("hello world")
end
i type the following into the interpretr:
dofile "file.lua"
a = constructor()
a:print() --error attempt to call method 'print' (a nil value)
dofile "file.lua"
a = constructor()
a:print() -- hello world
the method works the second time i import the file but not the first. why is this?
I have tried changing the order (putting the constructor function last) and it was the same.
The first time x is nil. It gets defined and then used the second time.
You need to write x = {}; x.__index = x.

Resources