I'm trying to make a Pokemon Red/Blue Chaos Edition, but like everyone else asking question on this site, I've encountered a bug that I cannot fix. I am using version 2.2.2 (x64) of BizHawk. The error is as follows:
NLua.Exceptions.LuaScriptException: [string "main"]:12: invalid arguments to method call
https://pastebin.com/pWmByXum
I did some research, and came to the conclusion that it's trying to run line 12 as a function even though I have none.
rng is being defined as a local variable inside the if block. It is therefore not available outside of that block when it is used as an argument to the call on line 12. At that point it would be nil. Move the declaration of rng to above the if block:
local rng = nil
Then in both places in fhe if block when you assign a value, just write:
rng = ...
instead of
local rng = ...
rng will then get assigned a value, but be available outside of the if block
Related
How to output the contents of a function?
function a()
print("Hello,World")
end
print(func_toString(a))
I hope the result of func_toString(a) could be
function a()
print("Hello,World")
end
or just
print("Hello,World")
It is assumed that the source code is executed directly without precompiling or embedding.
How to do this?
well, it's not completely impossible, the code in some cases can be read from a lua file, for example:
function a()
print("Hello,World")
end
local function get_source_code(f)
local t = debug.getinfo (f)
if t.linedefined < 0 then print("source",t.source); return end
local name = t.source:gsub("^#","")
local i = 0
local text = {}
for line in io.lines(name) do
i=i+1
if i >= t.linedefined then text[#text+1] = line end
if i >= t.lastlinedefined then break end
end
return table.concat(text,"\n")
end
print( get_source_code(a) )
maybe that will be enough.
This is not possible from within the running Lua program.
Lua provides the debug library to inspect functions and variable. This allows you to obtain the source (the path or string where the function is defined) and the line range on which the function is defined. In the vast majority of cases this might actually be enough: Just find the first occurrence of function(...) on the first line and the first occurrence of end on the last line, then string.sub the relevant portion. This is however rather error prone; consider e.g.
function a() function b() end end
a()
func_toString(a)
since both functions are on the same line, you can't distinguish them - the debug library only provides you line info, nothing more. You could try to distinguish them by their signature since hacks exist to obtain the method signature, but that would fail here as well since both functions have the same signature. You could try gsubing them out based on their names, but remember that functions can be anonymous in Lua.
Lua also provides the string.dump function to obtain the bytecode of a function. I highly doubt that this is of any use to you; theoretically you could decompile it to get back a "Lua" representation of what the function does, but it would hardly be recognizable or readable.
In Lua, calling a function with excess arguments will simply discard those. Is there a possibility with the debug library to access these discarded arguments? (I'm not looking for variadic functions)
function test()
local info = debug.getinfo(1, "u")
print(info.nparams) -- just 0 :(
-- how to access the discarded arguments?
end
test(42, "Hello World!", 3.14)
Edit: As Luiz-Henrique informed me in the comments, this is not possible in standard Lua. He also asked for more context, so I'm going to repeat the problem that I was trying to solve to answer another question. In this other question the OP wanted to access the name that module has inside package.preload from within the loader function but without taking it as an argument as it is passed by require. I don't know why but this led me to the question whether it is possible to access discarded arguments.
package.preload["test"] = function()
local info = debug.getinfo(1, "u")
print(info.nparams) -- just 0 :(
-- how to access the name without taking it as an argument
return {}
end
require("test")
Let's say that I call some functions indirectly, via a variable. For example:
obj = {
on_init = function()
print "hello."
end,
on_destroy = function()
print "bye."
end,
on_do_something = function()
print "doing something."
error("Hi de hi, hi de ho!")
end,
}
local event = "do_something"
local func = obj["on_" .. event]
func()
All works fine.
However, the problem is that when the called function raises an exception (as in the code above) the error message isn't quite clear. It is thus:
lua: test.lua:13: Hi de hi, hi de ho!
stack traceback:
[C]: in function 'error'
test.lua:13: in function 'func'
test.lua:20: in main chunk
It says "in function 'func'". I'd prefer it to say "in function 'on_do_something'" instead.
I'd imagine this scenario to be very common. Is there a solution for this?
I tried calling the function thus:
obj["on_" .. event]()
But then the error message says "in function '?'", which isn't helpful either.
(I tried this code on Lua 5.1, 5.2 and LuaJIT without notable differences.)
This is a limitation of the heuristics used by Lua to provide names for functions.
In Lua, all functions are anonymous. A given function can be the value of several variables: global, local, and table fields. The Lua debug system, which is used in error handling, tries to find a reasonable name for a value based on where it came from by looking into the bytecode being executed.
See
Why is 'name' nil for debug.getinfo(1).
You have a few options. The debug module will try to produce something useful. For instance, you might be able to get the file name and line number where it was defined, if this is your own code. See
http://www.lua.org/pil/23.1.html for the list of what is available via debug module. Or, you might be able to define the functions in the module, then add them to the table:
-- module something
function a()
...
end
tt = {
fn1 = a,
...
}
Depending on where you trap the error (error handler installed via debug hook?), you could check if filename is the module where your table of functions is defined, and if it is, then use the debug module to print appropriate info based on your table structure etc; if it is not, just print the default traceback etc.
I am new to lua,i just don't know why,does it related to environment or the libarary?it drive me crazy, i being search the answer for hours.
function gradient()
local maxStep = 10;
local starColor="41B0F7";
local endColor ="1622DF";
local sb = tonubmer(string.sub(starColor,1,2),16);
return sb;
end
print(gradient());
There are two things going on here:
Lua standard library functions like tonumber are global variables.
If you try to access a global variable that does not exist (in this case, tonu*bm*er) you get nil ny default.
I recommend using a linting tool like LuaInspect to detect these typos before they bite you.
Here is the function
calc.lua:
function foo(n)
return n*2
end
Here is my LuaJavaCall
L.getGlobal("foo");
L.pushJavaObject(8);
int retCode=L.pcall(1,1,0); // nResults)//L.pcall(1, 1,-2);
String errstr = L.toString(-1); // Attempt to perform arithmetic on local variable 'n'
Update: as indicated below I needed to use L.pushNumber(8.0) instead of L.pushJavaObject()
Try using L.pushNumber instead of L.pushJavaObject like this:
L.getGlobal("foo");
L.pushNumber(8.0);
int retCode = L.pcall(1,1,0);
String errstr = L.toString(-1);
Lua probably sees JavaObject as a type of 'userdata' in which case there are no predefined operations for it; Lua won't know what to do with a JavaObject * 2 since you didn't define how to handle it.
OTOH, Lua does know how to handle a number since that's a builtin primitive type. For the code snippet you presented, pushing a number would be the least painful way to get it working instead of writing extra code that tells Lua how to work with numbers wrapped inside a JavaObject.