return type of who_user in scilab - variables

I work with scilab, but during a project, scilab has to deal with a large number of variables.
I was wondering if i can do the following
var_list = who_user();
for _var_ = var_list do
if _var_ is global then
writetofile(human_readablefile, _var_)
end
end
clear()
of course this is a pseudocode, and i have a few questions before i implement it.
I can not get var_list = who_user() working. so i believe the function does not return anything. I am reluctant to hack into the code of the "who_user" macro itself. Is there any other way to get the list of user variables in another variable?
Is there a way to find the global variables out of them?
If not, then what are some memory management techniques in scilab?

I am able to answer your first query:
From a slight modification of the who_user function itself:
function nams = who_user1()
//get user variables
[nams,mem]=who('get'); //get all variables
p=predef(); //number of system variable
st=stacksize()
nams=nams(1:$-p+1);mem=mem(1:$-p+1);
//modifiable system variables
excluded=['demolist','scicos_pal','%scicos_menu',..
'%scicos_short','%helps','%helps_modules','MSDOS','who_user','%scicos_display_mode', ...
'%scicos_help'];
ke=grep(nams,excluded)
nams(ke)=[];mem(ke)=[];
n=size(nams,1);
if n==0 then return,end
//format names on n*10 characters
ll=length(nams)+2;m=int((ll-1)/10)+1;
for k=1:max(m)
ks=find(m==k);
if ks<>[] then nams(ks)=part(nams(ks),1:(k*10));end
end
endfunction
This function should give you the list you desire (I have modified the name to who_user1).
You can find out whether a specific variable is global or not by using the isglobal() function, but you need to pass a variable to isglobal(), not the string that is the name of the variable. The function I've listed above returns a vector of strings.
An alternative approach you could try would be to rewrite the above function to return the variables (rather than their names) directly using varargout and then testing them for being globals.

Related

Evaluate a local variable inside a Julia macro

I'm writing a Julia macro that takes an expression and serializes it, so that I can run it somewhere else. The macro therefore takes the expression and replaces all symbols with variables. The expression is then serialized and evaluated somewhere else.
My problem is related to evaluating variables that are not in the global scope. I.e. the following works fine, as a is defined in the global scope:
macro myprintf(ex)
print(eval(ex))
end
# works
a = 2
#myprintf a
This throws an error as the macro doesn't see a, which is defined in the local scope of the loop (run in a new session):
macro myprintf(ex)
print(eval(ex))
end
# UndefVarError: a not defined
for j=1:3
a = 2
#myprintf a
end
Is there any way I can access a inside the macro if it is defined in a local scope such as a loop? I'm aware that I'm not necessarily using macros as intended as I am calling eval on the expression inside the macro definition. The overall idea is that I want to serialize the expression that's passed to the macro and evaluate it somewhere else later (e.g. in a different Julia session).
eval only works in global scope. But then I don't see how much use there is in replacing the variables by evaluated literals, resulting in an expression of literals.
Anyway, a different approach to the original problem could be mimick what R does: constructing thunks out of an expression plus its environment at the place where it was called. To recreate that in Julia, you'd have to
Figure out the free variables in the expression
Create an environment data structure of their values
Wrap the original expression in a closure such that it takes the local variables from the environment
Put everything into a new object
Example:
for j=1:3
a = 2
#saveexpr a + 2
end
should expand to something like
for j=1:3
a = 2
SerializedExpr(
(; a),
function (env)
let (a,) = env
a + 2
end
end,
:(a + 2))
end
If saving the closure is not feasible in your use case, I guess you have to either implement your own evaluator, or use something like JuliaInterpreter.jl.

Why Are My Tables Returning NIL and Not Populating?

I'm new to Lua and trying to understand the concept of OOP in Lua. To do so, I've tried creating an object and creating methods and "private variables". My issue is when I try to use "setters" or "getters", it's indicating that my tables are returning NIL which means I'm either having a scoping issue or something else I can't figure out.
The kicker is I'm using an example from an online Lua coding tutorial, and when I run the tutorial it works flawlessly. However, when I run mine, I get NIL or nothing outputs whenever I try to "get" or return a value from one of the member functions.
I'm using a couple of different environments:
ZeroBrain
Sublime Text
Lua for Windows
Do you know why my code is not returning populated tables?
newPlayer = function(n, h, a, r)
player = {}
n = n or ""
h = h or 100
a = a or 100
r = r or 0
function player:getPlayerName()
return n
end
function player:getPlayerHealth()
return h
end
function player:getPlayerArmor()
return a
end
function player:getPlayerRank()
return r
end
function player:setPlayerName(arg)
n = arg
end
function player:setPlayerHealth(arg)
h = arg
end
function player:setPlayerArmor(arg)
a = arg
end
function player:setPlayerRank(arg)
r = arg
end
function player:connect(arg)
print(string.format(" %s joined" , arg))
end
return player
end
player1 = newPlayer("John", 100, 100, 1000)
player1.getPlayerName()
Your code does not contain "populated tables" to return.
Your newPlayer function does create a table, and it does return it. It creates a number of functions within that table. But that's all newPlayer does: creates a table and puts some functions in it.
The data accessed by those functions is not part of the table. n, h, a, and r (BTW, please use better variable names) are all local variables. Your inner functions will access the specific stack containing those variables, but the variables themselves will not be magically associated with the table.
Your principle problem is almost certainly with the setters. And it comes from a combination of this:
function player:setPlayerName(arg)
with this:
player1.getPlayerName()
When you create a function using a : character between a table name and the function's name, you are using syntactic sugar for a function which implicitly takes as its first argument a value called self. As the name suggests, this is supposed to represent the object which this function is being called upon. So your function creation code is equivalent to:
function player.setPlayerName(self, arg)
Since you create all of your functions with :, all of your functions take at least one parameter.
The : syntax can also be used when calling such functions. If you did player1:getPlayerName(), this would cause the table you accessed to find the getPlayerName function to be used as the first argument in the function call. So that line would be equivalent to player1.getPlayerName(player1).
Obviously, these two syntaxes are mirrors of one another: functions created with : take a parameter that is expected to refer to the table it is being called on, and functions called with : will be given the table which was accessed to get that function.
But... your code didn't stick to the symmetry. You created the functions with :, but you call them with .
Now, you get functions are able to get away with this because... well, none of your values are actually part of the table. So your get functions just return the local value that they adopted from their creating context.
The set functions pose a problem. See, they take a parameter. But because the function was declared with :, they really take two parameters, the first being the implicit self.
Now, : syntax is just syntactic sugar; it's just a convenient way to do what you could have done yourself. So it is in theory OK to call a function with . even if you created it with :. But if you do so, you must pass the table as the first parameter. Though your code doesn't show it, I strongly suspect you didn't do that.
If you called player1.setPlayerName("foo"), what will happen is that the implicit self parameter will get the value "foo", and the arg parameter will be nil. And you will assign that nil value to the n local variable. So subsequent calls to player1.getPlayerName() will return nil.
Basically, what's going on here is that you're combining two different ways of creating objects in Lua. You stored your private data in a way that external code cannot access (ie: local upvalues), but that data is now no longer part of the table itself. Which means that, although you dutifully create those functions with : syntax to indicate that they take a self table, they never actually use that table. And because they never use the table, it's a lot harder to figure out what's going wrong.
Basically, the key here is to be symmetrical. If you create a function with :, then you should either call it with : or make sure to pass it the object table as the first parameter.
Broadly speaking, the standard way to create private members is by convention, not by forbidding it. That is, you agree not to mess with any members of a table other than those with certain names. Python convention is to pretend that names starting with _ don't exist, and Lua programs sometimes use that.
Upvalues are an interesting solution for private variables, but they do come with problems. If you want to invent a member variable, you have to do it in a centralized place rather than wherever you might need one. Even if the variable is optional, you have to create a named local at the top of the function.
TLDR of Nicol's answer, see my answer to another question:
function player:setPlayerArmor(arg)
a = arg
end
The : syntax is syntactic sugar. It creates an implicit 'self' argument when declared, and when used. If you declare it one way and use it another, the arguments won't be what you're expecting. Say your player has 100 health. Look at this result:
player1.setPlayerHealth(55, 66)
print(player1.getPlayerHealth())
-- will display '66', not '55' because `:` declares implicit 'self' argument
This displays 66 because the setPlayerHealth function has an implicit 'self' parameter because it was declared with :. If you instead called it
with the ::
player1:setPlayerHealth(55, 66)
print(player1:getPlayerHealth())
-- will display '55' because `:` passes player1 as self
function player:setHealth1(arg)
-- implicit 'self' argument refers to player1 when called on player1
end
-- is the same as
function player.setHealth2(self, arg)
-- with `.` notation, you need to add the 'self' argument explicitly
end
player1.setHealth1(31) -- self argument will be 31 and arg will be nil
player1.setHealth2(32) -- self argument will be 32 and arg will be nil
player1:setHealth1(33) -- self argument will be player1 and arg will be 33
player1:setHealth2(34) -- self argument will be player1 and arg will be 34

Julia: Variable not defined

The variable scope behavior seems quite strange. The code block
tp = 1
function test2()
println(tp)
end
works perfectly well while
function test()
if tp==0
tp=tp-1
end
end
gives the exception "tp not defined". What is wrong?
This is tricky due to the way variables are implicitly defined as local or global, and the fact that definitions later in a function can affect their scoping in the whole function.
In the first case, tp defaults to being a global variable, and it works as you expected. However, in the second case, you assign to tp. This, as is noted in the scope of variables section of the manual:
"An assignment x = y introduces a new local variable x only if x is neither declared global nor introduced as local by any enclosing scope before or after the current line of code."
So, by assigning to tp, you've implicitly declared it as a local variable! It will now shadow the definition of your global… except that you try to access it first. The solution is simple: explicitly declare any variables to be global if you want to assign to them:
function test()
global tp
if tp==0
tp=tp-1
end
end
The behavior here is finely nuanced, but it's very consistent. I know it took me a few reads through that part of the manual before I finally understood how this works. If you can think of a better way to describe it, please say something!

Lua - How do I dynamically call a module?

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.

Read dynamic variable names in Lua

i'd like to know if there is any possibility to read out dynamic variable names?
Since the programm that passes the variables to my script calls them just "in1, in2, in3" etc.
Hopefully there is any way to make a loop, because it is pretty annoying to handle every input separately...
Here is what i've tried so far, but it just gives me an error.
for i=1,19,2 do
myvar[i] = ["in"..i]
end
I'm quite new to Lua, but i hope the solution is not that difficult :D
Edit:
Oh I'll try to give you some more information. The "Main" Program is no not written in Lua and just set theese "in1 ... " variables. It is a kind of robotic programmic software and has a lot of funktions build in. Thats the whole thing so i can not simply use other variable names or an array. So it is not a function or anything else related to Lua...
Here is a little Screenshot http://www.bilderload.com/daten/unbenanntFAQET.jpg
At the moment the Lua script just passes the the first input.
It depends on what you mean by "dynamic variable names."
The names of local variables do not exist. Local variables are any variable declared as a function parameter or with the local keyword. Local variables are compiled into offsets into the Lua stack, so their names don't exist. You can't index something by name to get them.
Global variables are members of the global table. Therefore, these ways to set a global variable are equivalent:
globalVar = 4
_G.globalVar = 4
_G["globalVar"] = 4
Since the programm that passes the variables to my script calls them just "in1, in2, in3" etc.
The program that passes variables to your script doesn't get to name them. A variable is just a placeholder for a value. It has no ownership of that value. When your function gets arguments, your function gets to name them.
You haven't said much about the structure of your program, so I can't really give good advice. But if you just want to take some number of values as parameters and access them as inputs, you can do that in two ways. You can take a table containing values as a parameter, or you can take a varargs:
function MyFunc1(theArgs)
for i, arg in ipairs(theArgs) do
--Do something with arg.
end
end
function MyFunc2(...)
for i, arg in ipairs({...}) do
--Do something with arg.
end
end
MyFunc1 {2, 44, 22} --Can be called with no () because it takes a single value as an expression. The table.
MyFunc2(2, 44, 22)
Whoever wrote the code that spits out these "dynamic variables" didn't do a good job. Having them is a bad habit, and might result in data loss, cluttering of the global name space, ...
If you can change it, it'd be much better to just output a table containing the results.
That said, you're not to far off with your solution, but ["in"..i] is no valid Lua syntax. You're indexing into nothing. If those variables are globals, your code should read:
for i=1,19,2 do
myvar[i] = _G["in"..i]
end
This reads the values contained by your variables out of the global table.
Try this
myvar={ in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11,
in12, in13, in14, in15, in16, in17, in18, in19 }
if the variables are passed as global variables, or this
myvar = {...}
if the variables are passed as arguments to the script.