Arguments that I pass to a lua script are nil - lua

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).

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

Lua (require) invoke an not intended print of required file name

When require is called in testt.lua which is one of two files the return is movee and movee.lua.
movee are for the most part a class to be required, but should be able to accept to be called direct with parameter.
movee.lua
local lib = {} --this is class array
function lib.moveAround( ... )
for i,direction in ipairs(arg) do
print(direction)
end
end
function lib.hello()
print("Hello water jump")
end
lib.moveAround(...)
return lib
testt.la
local move = require("movee")
Expected result is not to call lib.moveAround or print of file name when require is called.
Your expectations are incorrect. Lua, and most scripting languages for that matter, does not recognize much of a distinction between including a module and executing the Lua file which provides that module. Every function statement is a statement whose execution creates a function object. Until those statements are executed, those functions don't exist. Same goes for your local lib = {}. And so on.
Now, if you want to make a distinction between when a user tries to require your script as a module and when a user tries to execute your script on the command line (or via just loadfile or similar), then I would suggest doing the following.
Check the number of arguments the script was given. If no arguments were given, then your script was probably required, so don't do the stuff you don't want to do when the user requires your script:
local nargs = select("#", ...)
if(nargs > 0) then
lib.moveAround(...)
end
Solved by replacing
lib.moveAround(...)
with
local argument = {...}
if argument[1] ~= "movee" and argument[2] ~= "movee" then
lib.moveAround(...)
end
require("movee")
will execute the code within movee.lua
lib.moveAround(...)
is part of that code. Hence if you require "movee" you call lib.moveAround
If the expected result is not to call it, remove that line from your code or don't require that file.

LuaJ does not supply command line arguments correctly

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

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.

Lua Arguments and Numbers

function OnChat(PlayerId, Type, Message)
if Message == "!usecarepackage" then
if ReadKS1 == "CP" or ReadKS2 == "CP" or ReadKS3 == "CP" then
InputConsole("msg %s has requested a care package!", Get_Player_Name_By_ID(pID))
local pos = Get_Position(Get_GameObj(pID))
pos:AssignY(pos:GetY()+1)
building = Create_Object("SignalFlare_Gold_Phys3", pos)
Attach_Script(building, "Test_Cinematic", "caredrop.txt")
if building == nil then
InputConsole("ppage %d Cannot spawn Care Package here.", pID)
elseif math.random(50, 64) == 50 then
Attach_Script(building, "z_Set_Team", Get_Team(pID))
Attach_Script(building, "M00_No_Falling_Damage_DME")
--Add in rest of numbers and corresponding streak, such as UAV if math.random = 50
end
elseif ReadKS1 ~= "CP" or ReadKS2 ~= "CP" or ReadKS3 ~= "CP" then
InputConsole("ppage %d You are not allowed to use that with your current streak selection", pID)
end
end
return 1
end
I know this is scruffy code, but I'm receiving a "Bad argument #2 to 'format' (number expected, got no value)". This relates to this piece of code which prefixes all other pieces:
function InputConsole(...)
Console_Input(string.format(unpack(arg)))
end
Finally, this is for the game Command and Conquer Renegade (should you wish to look up API etc). Any help in what I'm doing wrong would be much appreciated.
The likely problem with this code is the use of the deprecated arg feature in your function InputConsole(). Lua 5.0 used arg as a way to access the actual arguments to a function declared as variadic using the ... token in the argument list.
Edit: But likely doesn't mean correct.
The actual problem looks like the switch in idiom from PlayerId to pID. The former is the named parameter of the function OnChat(), while the latter is a global variable used in the function body without further initialization. Uninitialized globals are nil, so nil is passed to InputConsole() and the error message is telling you the truth.
Old answer that didn't solve it
Lua 5.1 deprecated that usage, and Lua 5.2 removed it entirely.
I'm not sure from the code fragments provided which version of Lua is actually used in this game, but the symptom is consistent with missing the automatically generated arg table.
I would write the function like this:
function InputConsole(...)
Console_Input(string.format(...))
end
But you could also add local arg = {...} as the first line of the function and get much the same effect as provided by Lua 5.0 at the expense of creating (and discarding) the temporary table. The differences are subtle, and mostly have to do with the treatment of nil in tables.
For clarity, I would prefer name the first argument, as it is not really optional.
function InputConsole(fmt, ...)
Console_Input(string.format(fmt, ...))
end
And if you can count on that argument being a string, that could be simplified further to
function InputConsole(fmt,...)
Console_Input(fmt:format(...))
end
If its stringiness is of concern, just say fmt = tostring(fmt) or possibly assert(type(fmt)=="string") before the call to Console_Input().

Resources