Clearly I have some mixed up, but I figured that by using something like this in "main.lua":
local module = require("module")
local var = "I should be global?"
printthis()
with module.lua containing something like:
function printthis()
print(var)
end
that printthis(var) would work fine, because now the module.lua code is inside main.lua, no? Instead, printthis has no idea what var is. I read it's good practice to use "local" on Lua variables when possible, but in this case, do I have to make var global or is there a way for module.lua's printthis() function to read var properly?
No. That's not at all how it works.
The Lua interpreter provides one global table, referred to as _G normally, unless you're doing something kinky.
function printthis()
print(var)
end
This translates to, in reality
_G.printthis = function()
_G.print(_G.var);
end
And your code in main is equal to
local module = _G.require("module")
local var = "I should be global?"
_G.printthis()
But when you call printthis- where did _G.var get set? Nowhere. So the variable is nil, like all other accesses to a table where there is nothing at that key.
It might be inconvenient, but it's a much better idea in the long run to pass arguments than to set global variables instead. Once you come to change anything about the program, it's going to be completely impossible to make any changes, as the logic has no structure and you have no idea what happens where without reading every single line of code and understanding it at once. In addition, you can only use each key in one place, because it's a global table- so I sure hope nobody else wanted to use "var" as a variable name and you don't mind your code silently failing because you got a global name wrong.
The other two answers gloss over an important thing: lexical scoping.
This means, roughly, that code can access local variables that are defined where the code is defined. That probably sounds vague, so I'll give an example:
local cheese = 'sandwich'
print(cheese) -- prints sandwich
do -- this begins an anonymous block
local cheese = 22
print(cheese) -- prints 22
end
print(cheese) -- prints sandwich
So what we have here is two different variables: the outer one is "shadowed" by the inner one.
Now, onto functions:
do
local hotdog = 'hot'
function nonsense()
print(hotdog)
end
end
print(hotdog) -- prints nil, since there is no variable called hotdog here
nonsense() -- prints hot
Functions can see the local variables from where they are defined, not from where they are called. This is very important and very useful, once you get the hang of it.
I'm no expert in lua, but shouldn't var be passed as variable. Something like this:
function printthis(var)
print(var)
end
You're missing your var in function header. And you're passing your var in main.lua as an argument to printthis() function.
Related
I have a really basic question about something that I've never paid much attention to until now:
I noticed that when creating a function (in JS or Python) that uses a variable from the outer scope, the function is not defined using the value of the variable but rather the variable itself. So if I change the value of the variable the function will use the new value.
This is what I mean
let a = 10;
function printA(){
console.log(a);
}
printA(); // => 10
a = 20;
printA(); // => 20
a = 10
def printA():
print(a)
printA() # => 10
a = 20
printA() # => 20
I thought this was only going to work of objects because of the way you can modify an object inside a function but not primitive variables because there's no way to change their value without reasigning them. I guess this is a different story.
What I'm trying to understand is: when typing a variable name is typing its memory address what I'm really doing? Does this happen with all languages?
when I create a function like printA() that uses a variable that is not an argument, is the variable bound forever to the function by its address?
The variable a is "captured" by the function. The specifics of how that happens are usually implementation details and may result in the compiler/interpreter producing code that doesn't much resemble the original.
For instance, in C# (I know, not one of the languages you mentioned, but it's the one I'm most familiar with), the compiler will create a separate hidden class which actually contains fields for the variables that are captured by a lambda or nested function. It then accesses these fields rather than plain variables.
by its address
Variables don't typically have an address. For instance, every time you call a method, it will typically have an "activation record" of some kind created, that will typically contain its variables. But note that these records are not at some fixed location, which is how you can have parallel execution of methods, recursion, etc, without interference. (Some older BASICs did have fixed activation records, which is why they didn't allow for recursion). These activation records may typically be placed on some kind of stack.
But as I say, for captured variables, the compiler will typically need to do even more so that those variables aren't just stored in an activation record, and so that their lifetime is no longer tied to a single call.
I'm trying to figure out a way to get all functions in a Lua script. This script has been compiled into a function through loadfile. For example, I'd want to get every function defined in the script below.
function example1()
end
local function example2()
end
local library = {}
function library:example3()
end
(function()
-- Functions like this too.
end)
The names aren't important, I'm just looking for a way to get the actual functions so I can use them in debug.getinfo and get information like the lines they were defined in. I have LuaJIT, if that makes this any easier. Is something like this even possible? Thanks in advance.
I guess the file declares its functions as global, or it would be really easy to track what is returned.
If that's the case, you can cycle through all the global items with a generic for loop, and only take the functions from them:
allFuncs = {}
for key, item in pairs(_G) do
if type(item) == "function" then
allFuncs[#allFuncs + 1] = item
end
end
(_G is the table holding all the global variables)
Then you will have a list (allFuncs) holding all the functions declared, but be aware that it will also contain default functions like setmetatable or xpcall.
It's easy to modify the code to not make this happen, but only use this for testing / learning:
function allFuncs()
local funcsTab = {}
for key, item in pairs(_G) do
if type(item) == "function" then
funcsTab[#funcsTab + 1] = item
end
end
return funcsTab
end
defaultFuncs = allFuncs()
--then you load your file: other functions get declared
--we create another table containg the default + the new functions
myFuncs = allFuncs()
--then you subtract the first table from the second
for i = 1, #myFuncs do
for o = 1, #defaultFuncs do
if myFuncs[i] == defaultFuncs[o] then
table.remove(myFuncs, i)
end
end
end
This is if your file doesn't return anything and declares its functions as globals.
If the file declares them as local and then returns a table containing them, just use the first piece of code replacing _G with that returned table.
This is not likely to be possible without syntax or bytecode analysis as each function definition is an assignment (just has different forms in your examples). See the bytecode inspector and a related discussion here. For the syntax analysis you can use metalua or something like lua-loose-parser. Keep in mind that even those tools won't give you the entire list of functions as some functions may be defined dynamically using loadstring (or similar methods).
If you only have access to the result of loadfile, then you best bet is to use the bytecode analyzer.
This is possible using jit.attach in LuaJIT.
You can attach callbacks to a number of compiler events with
jit.attach. The callback can be called:
when a function has been compiled to bytecode ("bc");
when trace recording starts or stops ("trace");
as a trace is being recorded ("record");
or when a trace exits through a side exit ("texit").
http://wiki.luajit.org/JIT-Compiler-API#jit-attach
jit.attach(function(f)
local funcInfo = jit.util.funcinfo(f)
end, "bc")
First, here the way i'm calling the function :
eval([functionName '(''stringArg'')']); % functionName = 'someStringForTheFunctionName'
Now, I have two functionName functions in my path, one that take the stringArg and another one that takes something else. I'm getting some errors because right now the first one it finds is the function that doesn't take the stringArg. Considering the way i'm calling the functionName function, how is it possible to call the correct function?
Edit:
I tried the function which :
which -all someStringForTheFunctionName
The result :
C:\........\x\someStringForTheFunctionName
C:\........\y\someStringForTheFunctionName % Shadowed
The shadowed function is the one i want to call.
Function names must be unique in MATLAB. If they are not, so there are duplicate names, then MATLAB uses the first one it finds on your search path.
Having said that, there are a few options open to you.
Option 1. Use # directories, putting each version in a separate directory. Essentially you are using the ability of MATLAB to apply a function to specific classes. So, you might set up a pair of directories:
#char
#double
Put your copies of myfun.m in the respective directories. Now when MATLAB sees a double input to myfun, it will direct the call to the double version. When MATLAB gets char input, it goes to the char version.
BE CAREFUL. Do not put these # directories explicitly on your search path. DO put them INSIDE a directory that is on your search path.
A problem with this scheme is if you call the function with a SINGLE precision input, MATLAB will probably have a fit, so you would need separate versions for single, uint8, int8, int32, etc. You cannot just have one version for all numeric types.
Option 2. Have only one version of the function, that tests the first argument to see if it is numeric or char, then branches to perform either task as appropriate. Both pieces of code will most simply be in one file then. The simple scheme will have subfunctions or nested functions to do the work.
Option 3. Name the functions differently. Hey, its not the end of the world.
Option 4: As Shaun points out, one can simply change the current directory. MATLAB always looks first in your current directory, so it will find the function in that directory as needed. One problem is this is time consuming. Any time you touch a directory, things slow down, because there is now disk input needed.
The worst part of changing directories is in how you use MATLAB. It is (IMHO) a poor programming style to force the user to always be in a specific directory based on what code inputs they wish to run. Better is a data driven scheme. If you will be reading in or writing out data, then be in THAT directory. Use the MATLAB search path to categorize all of your functions, as functions tend not to change much. This is a far cleaner way to work than requiring the user to migrate to specific directories based on how they will be calling a given function.
Personally, I'd tend to suggest option 2 as the best. It is clean. It has only ONE main function that you need to work with. If you want to keep the functions district, put them as separate nested or sub functions inside the main function body. Inside of course, they will have distinct names, based on how they are driven.
OK, so a messy answer, but it should do it. My test function was 'echo'
funcstr='echo'; % string representation of function
Fs=which('-all',funcstr);
for v=1:length(Fs)
if (strcmp(Fs{v}(end-1:end),'.m')) % Don''t move built-ins, they will be shadowed anyway
movefile(Fs{v},[Fs{v} '_BK']);
end
end
for v=1:length(Fs)
if (strcmp(Fs{v}(end-1:end),'.m'))
movefile([Fs{v} '_BK'],Fs{v});
end
try
eval([funcstr '(''stringArg'')']);
break;
catch
if (strcmp(Fs{v}(end-1:end),'.m'))
movefile(Fs{v},[Fs{v} '_BK']);
end
end
end
for w=1:v
if (strcmp(Fs{v}(end-1:end),'.m'))
movefile([Fs{v} '_BK'],Fs{v});
end
end
You can also create a function handle for the shadowed function. The problem is that the first function is higher on the matlab path, but you can circumvent that by (temporarily) changing the current directory.
Although it is not nice imo to change that current directory (actually I'd rather never change it while executing code), it will solve the problem quite easily; especially if you use it in the configuration part of your function with a persistent function handle:
function outputpars = myMainExecFunction(inputpars)
% configuration
persistent shadowfun;
if isempty(shadowfun)
funpath1 = 'C:\........\x\fun';
funpath2 = 'C:\........\y\fun'; % Shadowed
curcd = cd;
cd(funpath2);
shadowfun = #fun;
cd(curcd); % and go back to the original cd
end
outputpars{1} = shadowfun(inputpars); % will use the shadowed function
oupputpars{2} = fun(inputparts); % will use the function highest on the matlab path
end
This problem was also discussed here as a possible solution to this problem.
I believe it actually is the only way to overload a builtin function outside the source directory of the overloading function (eg. you want to run your own sum.m in a directory other than where your sum.m is located.)
EDIT: Old answer no longer good
The run command won't work because its a function, not a script.
Instead, your best approach would be honestly just figure out which of the functions need to be run, get the current dir, change it to the one your function is in, run it, and then change back to your start dir.
This approach, while not perfect, seems MUCH easier to code, to read, and less prone to breaking. And it requires no changing of names or creating extra files or function handles.
I have code that looks like this:
var variableX:uint = something;
if (variableX > 1)
{
var variableY:uint = foo;
}
else
{
var variableY:uint = bar;
}
When compiled in FlashDevelop, the compiler gives the following warning:
Warning: Duplicate variable definition.
Being a beginner with AS3 and programming I don't like compiler warnings. The compiler is looking at me through squinted eyes and saying "Ok, buddy, I'll let you off this time. But I'm warning you!" and then doesn't tell me what's so wrong about what I'm doing.
What should I be aware of when I do something like this? I mean I could obviously define the variable outside of if and then this wouldn't be a problem, but maybe there's something more to this? Or is the compiler just giving a helpful nudge saying "hey, you might have accidentally created two different variables with the same name" ?
You're correct in your assessment of the warning. It's just letting you know there was already a variable in scope with that name and that you're about to redefine it. This way you don't accidentally overwrite a variable. Although they may not appear to be in the same scope if you check out variable hoisting on this page you'll see what the deal is: http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f9d.html
An interesting implication of the lack of block-level scope is that
you can read or write to a variable before it is declared, as long as
it is declared before the function ends. This is because of a
technique called hoisting , which means that the compiler moves all
variable declarations to the top of the function. For example, the
following code compiles even though the initial trace() function for
the num variable happens before the num variable is declared:
My personal tendency is to just bring the definition up top myself to avoid having extra warnings that make me miss more important issues. Been out of AS3 for a while but in large projects people let things go and you end up with 100s-1000s of warnings and relevant ones get buried.
I'm going back to the basics here but in Lua, you can define a table like so:
myTable = {}
myTable [1] = 12
Printing the table reference itself brings back a pointer to it. To access its elements you need to specify an index (i.e. exactly like you would an array)
print(myTable ) --prints pointer
print(myTable[1]) --prints 12
Now functions are a different story. You can define and print a function like so:
myFunc = function() local x = 14 end --Defined function
print(myFunc) --Printed pointer to function
Is there a way to access the body of a defined function. I am trying to put together a small code visualizer and would like to 'seed' a given function with special functions/variables to allow a visualizer to 'hook' itself into the code, I would need to be able to redefine the function either from a variable or a string.
There is no way to get access to body source code of given function in plain Lua. Source code is thrown away after compilation to byte-code.
Note BTW that function may be defined in run-time with loadstring-like facility.
Partial solutions are possible — depending on what you actually want to achieve.
You may get source code position from the debug library — if debug library is enabled and debug symbols are not stripped from the bytecode. After that you may load actual source file and extract code from there.
You may decorate functions you're interested in manually with required metadata. Note that functions in Lua are valid table keys, so you may create a function-to-metadata table. You would want to make this table weak-keyed, so it would not prevent functions from being collected by GC.
If you would need a solution for analyzing Lua code, take a look at Metalua.
Check out Lua Introspective Facilities in the debugging library.
The main introspective function in the
debug library is the debug.getinfo
function. Its first parameter may be a
function or a stack level. When you
call debug.getinfo(foo) for some
function foo, you get a table with
some data about that function. The
table may have the following fields:
The field you would want is func I think.
Using the debug library is your only bet. Using that, you can get either the string (if the function is defined in a chunk that was loaded with 'loadstring') or the name of the file in which the function was defined; together with the line-numbers at which the function definition starts and ends. See the documentation.
Here at my current job we have patched Lua so that it even gives you the column numbers for the start and end of the function, so you can get the function source using that. The patch is not very difficult to reproduce, but I don't think I'll be allowed to post it here :-(
You could accomplish this by creating an environment for each function (see setfenv) and using global (versus local) variables. Variables created in the function would then appear in the environment table after the function is executed.
env = {}
myFunc = function() x = 14 end
setfenv(myFunc, env)
myFunc()
print(myFunc) -- prints pointer
print(env.x) -- prints 14
Alternatively, you could make use of the Debug Library:
> myFunc = function() local x = 14 ; debug.debug() end
> myFunc()
> lua_debug> _, x = debug.getlocal(3, 1)
> lua_debug> print(x) -- prints 14
It would probably be more useful to you to retrieve the local variables with a hook function instead of explicitly entering debug mode (i.e. adding the debug.debug() call)
There is also a Debug Interface in the Lua C API.