LuaJ does not supply command line arguments correctly - lua

I tried the utility method provided by luaj to call a lua file with command line args (this one http://lua-users.org/wiki/SourceCodeFormatter)
Globals globals = JsePlatform.standardGlobals();
String script ="src/codeformatter.lua";
File f = new File(script);
LuaValue chunk = globals.loadfile(f.getCanonicalPath());
List<String> argList = Arrays.asList("--file","test.lua");
JsePlatform.luaMain(chunk, argList.toArray(new String[argList.size()]));
However i always get attempt to call nil where the code tries to access the arg table ( while i < table.getn(arg) do) - i tried other examples and they all result in the same error - luaj does not seem to set the "arg" table correctly - even a simply print arg[1] will not work.

LuaJ does not support table.getn anymore because it got removed in lua 5.1 - replace every occurances of table.getn with #varname - and init the args array with ocal args={...} at the top made it work.
Still, the code formatter does not really do what i expected it todo

There are two issues:
calls to table.getn(arg) should be replaced with #arg
the chunk's environment is not set up properly by luaj 3.0.1 so arg isn't set
However, as a workaround, you can capture the inputs using the varargs "..." syntax by adding a line at the top of codeformatter.lua such as
arg = {...}
Here is a code snippet to illustrate:
Globals globals = JsePlatform.standardGlobals();
LuaValue chunk = globals.load(
"arg = {...};" +
"print(#arg, arg[1], arg[2])");
JsePlatform.luaMain(chunk, new String[] {"--file","test.lua"});
Produces output:
2 --file test.lua

Related

Struggling with calling lua functions from the command line

I have the following code:
dofile(arg[1])
function1 = arg[2]
argument = arg[3]
returned = _G[function1](argument)
print(returned)
It is designed to take three command-line arguments and run a function from a file.
So, i run the command lua libs.lua "printStuff.lua" "printStuff" "\"Hello, World\"", and i always end up with this:
"Hello, World"
nil
I don't understand why i always get "nil".
Here are the contents of printstuff.lua:
function printStuff(stuff)
print(stuff)
end
That is to be expected. What's going on here:
You're executing the file specified by the first argument, printstuff.lua, which will leave a function printStuff in the global table _G.
You're indexing the global table with the second argument, printStuff, obtaining that function
You're calling the function you just obtained with the third command line argument, "Hello World!", as parameter, which prints it, and storing the result of that in the global variable returned. The function printStuff doesn't return anything (there's no return in there, and even if there was, print doesn't return anything either), so you're assigning nil to returned.
You're printing returned, which is nil
Side note: I'd use the vararg ... instead of the arg table for improved readability:
local file, func, param = ...
dofile(file); print(func(param))
Why not simply...
-- xlua.lua
-- Example: lua xlua.lua os date "%H:%M:%S"
-- Or: lua xlua.lua _G print "Hello World"
-- Or: lua xlua.lua dofile /path/to/someusefull.lua "Arg for someusefull.lua"
local result = _G[arg[1]][arg[2]](arg[3])
-- 5. Only put out whats not nil
if (result ~= nil) then
print(result)
end

Arguments that I pass to a lua script are nil

I am writing a Lua 5.3 program and it requires arguments to be passed to it. I use the arg table to get the first argument: arg[1], but the 1st argument, according to the script, is nil even though I have passed an argument to the file.
Here's the code that I've written:
local strin = arg[1]:sub(2,arg[1]:len()-1) -- to remove the quote marks
local i = 0
for W in strin:gmatch(".") do
i = i + 1
if W == " " or W == "\t" then strin = strin:sub(i+1) else break end
end
print(strin)
I pass the argument to the file like this:
C:\Users\WhiteKid\Documents\Scripts>RemoveWhiteSpace.lua " hello world!"
It thinks arg[1] is a nil value when it is not. Is there a different way of getting the arguments passed to a lua script in Lua 5.3?
Since you are calling the .lua script directly (C:\Users\WhiteKid\Documents\Scripts>RemoveWhiteSpace.lua " hello world!"), you seem to have an association with a lua interpreter. You need to make sure you pass %1 or %* to the interpreter you are calling in that association. Alternatively, try calling the Lua interpreter and passing the script name and the parameters and it should work as you expect.
Also, you should check if arg[1] is present and check if the quotes are also there (as they may be removed before the parameters get to the script, so you should not always expect them).

How to get the output of python script executed from a ruby method

I am trying to run a python script from ruby method. I am running this method as a rake task within a Rails app. I am using the solution mentioned here:
def create
path = File.expand_path('../../../../GetOrders', __FILE__)
output = `"python2 " + path + "/parse.py"`
print output
str = JSON.parse(output)
print str
end
EDIT: This works:
output = `python2 #{path}/parse.py`
EDIT2:
Using the python script i am trying to pass a list of dictionaries to the ruby function. The python script looks something like:
import xml.etree.ElementTree as ET
import json
def parse():
tree = ET.parse('response.xml')
root = tree.getroot()
namespaces = {'resp': 'urn:ebay:apis:eBLBaseComponents'}
order_array = root.find("resp:OrderArray", namespaces=namespaces)
detailsList = []
for condition:
details["key1"] = value1
details["key2"] = value2
detailsList.append(details)
output = json.dumps(detailsList)
return output
print parse()
Could someone explain what i am doing wrong and how can I fix this. Thanks
When you do this:
output = `python2 #{path}/parse.py`
output will be assigned the standard output of the python script, but that script isn't writing anything to standard output; the json data that's the return value of the parse() call is simply discarded. You seem to be expecting the execution of the script to have a "return value" that's the return value of the script's last expression, but that's not how processes work.
You probably want to replace the parse() call at the end of the script with print parse().
You are calling this exact line on the shell:
"python2 -path- /parse.py"
which the shell interprets as a single command: python2 (with a space at the end).
Try using string interpolation, which works with the backtick operator:
output = `python2 #{path}/parse.py`
Imagine typing this exact string:
"python2 " + path + "/parse.py"
into your shell (e.g. bash). It would look for a program named "python2 " and give it four arguments
+
path
+
/parse.y
You can't put arbitrary Ruby code inside a backtick string the same way you can't put arbitrary code in normals strings. You must use string interpolation.

Print list of ALL environment variables

I would like to print a list of all environment variables and their values. I searched the Stackoverflow and the following questions come close but don't answer me:
How to discover what is available in lua environment? (it's about Lua environment not the system environment variables)
Print all local variables accessible to the current scope in Lua (again about _G not the os environment variables)
http://www.lua.org/manual/5.1/manual.html#pdf-os.getenv (this is a good function but I have to know the name of the environment variable in order to call it)
Unlike C, Lua doesn't have envp** parameter that's passed to main() so I couldn't find a way to get a list of all environment variables. Does anybody know how I can get the list of the name and value of all environment variables?
Standard Lua functions are based on C-standard functions, and there is no C-standard function to get all the environment variables. Therefore, there is no Lua standard function to do it either.
You will have to use a module like luaex, which provides this functionality.
This code was extracted from an old POSIX binding.
static int Pgetenv(lua_State *L) /** getenv([name]) */
{
if (lua_isnone(L, 1))
{
extern char **environ;
char **e;
if (*environ==NULL) lua_pushnil(L); else lua_newtable(L);
for (e=environ; *e!=NULL; e++)
{
char *s=*e;
char *eq=strchr(s, '=');
if (eq==NULL) /* will this ever happen? */
{
lua_pushstring(L,s);
lua_pushboolean(L,0);
}
else
{
lua_pushlstring(L,s,eq-s);
lua_pushstring(L,eq+1);
}
lua_settable(L,-3);
}
}
else
lua_pushstring(L, getenv(luaL_checkstring(L, 1)));
return 1;
}
You can install the lua-posix module. Alternatively, RedHat installations have POSIX routines built-in, but to enable them, you have to do a trick:
cd /usr/lib64/lua/5.1/
# (replace 5.1 with your version)
ln -s ../../librpmio.so.1 posix.so
# (replace the "1" as needed)
lua -lposix
> for i, s in pairs(posix.getenv()) do print(i,s,"\n") end
The trick is in creating a soft-link to the RPM's "io" directory and to naming the soft-link the same name of the library LUA will attempt to open. If you don't do this, you get:
./librpmio.so: undefined symbol: luaopen_librpmio
or similar.
local osEnv = {}
for line in io.popen("set"):lines() do
envName = line:match("^[^=]+")
osEnv[envName] = os.getenv(envName)
end
this would not work in some cases, like "no valid shell for the user running your app"
An easy 2 liner:
buf = io.popen("env", '*r')
output = buf:read('*a')
print(output) -- or do whatever

lua how require works

I'm using a graphics library that lets you program in Lua. I have a need for the A* pathfinding library so I found one online. It's just 1 lua file that does the pathfinding and 1 example file. In the example file it uses the object like:
-- Loading the library
local Astar = require 'Astar'
Astar(map,1) -- Inits the library, sets the OBST_VALUE to 1
I run the script and everything works. So now I add the Astar.lua file to the path location where my graphics engine is running and do the same thing and I get the error on the Astar(map, 1) line:
"attempt to call local 'AStar' (a number value)
Any ideas why I would be getting that error when I'm doing the same thing as the example that comes with this AStar lib?
Here is a little of the AStar file
-- The Astar class
local Astar = {}
setmetatable(Astar, {__call = function(self,...) return self:init(...) end})
Astar.__index = Astar
-- Loads the map, sets the unwalkable value, inits pathfinding
function Astar:init(map,obstvalue)
self.map = map
self.OBST_VALUE = obstvalue or 1
self.cList = {}
self.oList = {}
self.initialNode = false
self.finalNode = false
self.currentNode = false
self.path = {}
self.mapSizeX = #self.map[1]
self.mapSizeY = #self.map
end
So note that when I run this from my graphics engine it's returning 1, but when run from the example that it came with it's returning a table, which is what it should be returning. So not sure why it would only be returning 1.
How is Astar getting added to the package.loaded table for the example script, as opposed to your code?
QUICK LUA SYNTACTIC SUGAR REVIEW:
func 'string' is equivalent to func('string')
tabl.ident is equivalent to tabl['ident']
When you run a script using require('Astar'), this is what it does:
checks if package.loaded['Astar'] is a non-nil value.
If it is, it returns this value. Otherwise it continues down this list.
Runs through filenames of the patterns listed in package.path (and package.cpath), with '?' replaced with 'Astar', until it finds the first file matching the pattern.
Sets package.loaded['Astar'] to true.
Runs the module script (found via path search above- for the sake of this example we'll assume it's not a C module) with 'Astar' as an argument (accessible as ... in the module script).
If the script returns a value, this value is placed into package.loaded['Astar'].
The contents of package.loaded['Astar'] are returned.
Note that the script can load the package into package.loaded['Astar'] as part of its execution and return nothing.
As somebody noted in the comments above, your problem may come from loading the module using 'AStar' instead of 'Astar'. It's possible that Lua is loading this script using this string (since, on the case-insensitive Windows, a search for a file named "AStar.lua" will open a file called "Astar.lua"), but the script isn't operating with that (by using a hard-coded "Astar" instead of the "AStar" Lua is loading the script under).
You need to add return Astar at the end of Astar.lua.

Resources