So I'm trying to create an arrayList in lua following this module
https://github.com/SnakeSVx/spacebuild/blob/master/lua/includes/modules/arraylist.lua#L26
So first I started with
l = ArrayList:Create()
now I tried to create the list itself
l.list = List:Create()
However that's not the right way to do it. The method goes like this
function list:Create( thetype, isfunc )
self:SetCheckType(thetype, isfunc)
self.table = {}
end
To create an object with that module, use the function documented for creating objects:
local l = ArrayList.Create()
Create is a non-method function in the namespace created by the module ("ArrayList"). It's definition and documentation begin on line 364.
Most of the other functions in module are methods. So, you would pass an instance to them using Lua's method syntax (instance:method(...))
l:Add(item, index)
Related
I have a question that is similar to, but different than this one. I have a function within a module, and I would like to see what variables are defined inside the function namespace. In the other post, they said to use varinfo, but that seems to only work in the Main namespace. For example if I run this
module Test
function hello()
a = 1
varinfo()
return a
end
end
import .Test
Test.hello()
I get this error
WARNING: replacing module Test.
ERROR: UndefVarError: varinfo not defined
Is there a way to get a list of variables within a given namespace? What I am looking for is a function that when called, outputs all the available variables (a in my example) as well as available modules within the namespace.
PS. I would like to add, that varinfo is incredibly limiting because its output is a Markdown.MD, which cannot be iterated over. I would prefer a function that outputs variables and values in some sort of list or dictionary if possible.
varinfo is showing only the global variables.
If you want the local variables, you need to use the Base.#locals macro:
module Test
function hello()
a = 1
println(Base.#locals)
return a
end
end
And now you can do:
julia> Test.hello()
Dict{Symbol, Any}(:a => 1)
1
Is this what you want?
module Test
function hello()
a = 1
println(Main.varinfo(#__MODULE__; all=true, imported=true))
return a
end
end
Here it goes my code
ModuleName.FunctionName.VariableName
I'm wondering if this is applicable, we all know that to load a a function in another module you have to use this code:
ModuleName.FunctionName
I was wondering If my given code is applicable.
You can use variables in another module, but the syntax is not like ModuleName.FunctionName.VariableName because functions have no fields.
As an example, consider this simple module foo.lua:
local M = {}
function M.func()
print("calling func")
end
M.var = 42
return M
Note that similar to func(), the variable var must be global, or it's private to the module.
You can use the variable var similar to the way to use the function func():
local foo = require "foo"
foo.func()
print(foo.var)
Output:
calling func
42
There is two ways you can achieve this.
1 :
-- message.lua
local M = {}
function M.message()
print("Hello")
end
return M
You can call above module into other file.
-- test.lua
local msg = require "message"
msg.message()
2 :
--message.lua
msg = "message"
You can call above module by dofile
-- test.lua
dofile ("/home/django/lua/message.lua") -- you should provide complete path of message.lua
print(msg)
Functions don't have fields, but tables do. So you can do
ModuleName.FunctionName -- a function in ModuleName
ModuleName.VariableName -- a variable in ModuleName
ModuleName.TableName.FieldName -- a field from a TableName which is in ModuleName
Note FieldName could itself reference a table, and VariableName could be a function, table, string, number, coroutine, etc.
Here's some much-simiplified Lua code I'm working with. I need to know how to dynamically call another module ('zebra'):
avar = require "avar"
bvar = require "bvar"
function create(zebra)
print(zebra.new())
end
print(create(avar))
And here are two modules:
local Avar = {}
function Avar.new()
return "avar"
end
return Avar
local Bvar = {}
function Bvar.new()
return "new"
end
function Bvar.old()
return "old"
end
return Bvar
If I try to pass in the string "avar" to my 'create' function, it doesn't work. If I pass in the word 'avar' with no quotes, it does work, however, I don't understand what avar with no quotes is? It seems to be a blank table? Not sure how to pass a blank table as an argument in my main program.
But maybe I'm totally on the wrong path. How do I dynamically call modules?
You can require any time:
function create(zebraModuleName)
zebraType = require(zebraModuleName)
print(zebraType .new())
end
print(create("avar"))
print(create("bvar"))
avar without the quotes is a global variable you created. It is initialized to the value returned by the require function1, which is the value returned by the module you are invoking. In this case, its a table with the new field that happens to be a function.
1 Importing a modules in Lua is done via regular functions instead of a special syntax. The function call parenthesis can be ommited because parens are optional if you write a function call with a single argument and that argument is a string or a table.
Other than that, there are also some other things you are confusing here:
The table you are storing on avar is not empty! You can print its contents by doing for k,v in pairs(avar) do print(k,v) end to see that.
The avar, bvar and create variables are global by default and will be seen by other modules. Most of the time you would rather make them local instead.
local avar = -- ...
local bvar = -- ...
local function create (zebra)
-- ...
end
The create function clearly expects a table since it does table indexing on its argument (getting the new key and calling it). The string doesn't have a "new" key so it won't work.
You aren't really dynamically calling a module. You are requiring that module in a regular way and it just happens that you pass the module return value into a function.
create always returns nil so there is no point in doing print(create(avar)). You probablu want to modify create to return its object instead of printing it.
You can use standard require from lua language or build your own loader using metatables/metamethods.
1. create a global function:
function dynrequire (module)
return setmetatable ({},{
__index = function (table,key)
return require(module..'.'..key)
end
})
end
2. Create your project tree visible to package.path
./MySwiss/
\___ init.lua
\___ cut.lua
\___ glue.lua
\___ dosomething.lua
3. Make your module dynamic
you only need to put this line on your MySwiss/init.lua (as if you were namespacing a PHP class):
return dynrequire('MySwiss')
4. Require your module and use subproperties dynamically
On your script you only need to require MySwiss, and the folder file (or subfolders with dynrequire('MySwiss.SubFolderName').
var X = require('MySwiss')
X.glue()
Note that MySwiss doesn't have glue key. But when you try access de glue key the metamethod __index try to require submodule. You can the full project tree using this technique. The only downside is the external dependencies not packed this way.
This question already has answers here:
Difference between . and : in Lua
(3 answers)
Closed 8 years ago.
I'm still playing around with lua modules and I've found the following "interesting" issue that occurs depending on how you create your methods / functions inside a module.
Note the following code in a file called test_suite.lua:
local mtests = {} -- public interface
function mtests:create_widget(arg1)
print(arg1)
-- does something
assert(condition)
print("TEST PASSED")
end
return mtests
Using the above code, arg1 is always nil, no matter what I pass in when calling create_widget(). However, if I change the definition of the function to look like this:
function mtests.create_widget(arg1) -- notice the period instead of colon
print(arg1)
-- does something
assert(condition)
print("TEST PASSED")
end
then, the system displays arg1 properly.
This is how I call the method:
execute_test.lua
local x = require "test_suite"
x.create_widget(widgetname)
Can you tell me what the difference is? I've been reading: http://lua-users.org/wiki/ModuleDefinition
But I haven't come across anything that explains this to me.
Thanks.
All a colon does in a function declaration is add an implicit self argument. It's just a bit of syntactic sugar.
So if you're calling this with (assuming you assign the mtests table to foo), foo.create_widget(bar), then bar is actually assigned to self, and arg1 is left unassigned, and hence nil.
foo = {}
function foo:bar(arg)
print(self)
print(arg)
end
Calling it as foo.bar("Hello") prints this:
Hello
nil
However, calling it as foo:bar("Hello") or foo.bar(foo, "Hello") gives you this:
table: 0xDEADBEEF (some hex identifier)
Hello
It's basically the difference between static and member methods in a language like Java, C#, C++, etc.
Using : is more or less like using a this or self reference, and your object (table) does not have a arg1 defined on it (as something like a member). On the other way, using . is just like defining a function or method that is part of the table (maybe a static view if you wish) and then it uses the arg1 that was defined on it.
. defines a static method / member, a static lib, Which means you can't create a new object of it. static methods / libs are just for having some customized functions like printing or download files from the web, clearing memory and...
: Is used for object members, members that are not static. These members change something in an object, for example clearing a specified textbox, deleting an object and...
Metamethod functions(Functions that have :) can be made in lua tables or C/C++ Bindings. a metamethod function is equal to something like this on a non-static object:
function meta:Print()
self:Remove()
end
function meta.Print(self)
self:Remove()
end
Also, with . you can get a number/value that doesn't require any call from a non-static or static object. For example:
-- C:
int a = 0;
-- Lua:
print(ent.a)
-- C:
int a()
{
return 0;
}
-- Lua:
print(ent:a())
same function on a static member would be:
print(entlib.a())
Basically, each non-static object that has a function that can be called will be converted to : for better use.
My script registers itself for a callback using
require "cmodule"
index = 1
cmodule.RegisterSoftButtonDownCallback(index, "callbackFunc")
where callbackFunc is the name (a string) of the callback function. Now I turned this script into a module, but the callback is not called anymore, I assume because the callback function is not in the scope of the cmodule. How can I solve this? (Lua newbie)
cmodule is a device driver that has Lua bindings.
Edit: My complete solution based in the answer from BMitch below:
require "cmodule"
local modname = "myModule"
local M = {}
_G[modname] = M
package.loaded[modname] = M
local cmodule = cmodule
local _G = _G
setfenv(1,M)
function callbackFunc()
-- use module vars here
end
_G["myModule_callbackFunc"] = callbackFunc
index = 1
cmodule.RegisterSoftButtonDownCallback(index, "myModule_callbackFunc")
You need to have something defined in the global space for a string to be evaluated back to a function call.
Depending on how they implemented RegisterSoftButtonDownCallback, you may be stuck defining the function itself, rather than the table/field combination like myModule.callbackFunc. To minimize the namespace pollution, if you can't use myModule.callbackFunc, then I'd suggest myModule_callbackFunc=myModule.callbackFunc or something similar. So your code would look like:
require "cmodule"
index = 1
myModule_callbackFunc=myModule.callbackFunc
cmodule.RegisterSoftButtonDownCallback(index, "myModule_callbackFunc")
For a better fix, I would work with the cmodule developers to get their program to accept a function pointer rather than a string. Then your code would look like:
require "cmodule"
index = 1
cmodule.RegisterSoftButtonDownCallback(index, myModule.callbackFunc)