13 posts
Posted 26 April 2012 - 04:25 PM
Just as the subject says, attempting to access "shell.getRunningProgram()" returns an error:
"nameofapi:#: attempt to index ? (a nil value)"
This happens even if trying to print out the currently running program, though printing a nil value should just print a blank line. :)/>/>
In my eyes, the only point of having a command to return the currently running program would be to wrap it under an API function for use in MANY programs (which was my intent here).
Here's an example of how to replicate the problem:
program code:
os.loadAPI("nameOfAPI")
nameOfAPI.printMe()
api code:
function printMe()
print(shell.getRunningProgram())
end
Run the program and you get the error. Pretty simple
~Plystire
13 posts
Posted 26 April 2012 - 06:23 PM
I would like to further this by adding the following:
The above problem occurs as well if "shell.getRunningProgram()" is called from inside of a function that was executed via "os.run"… haven't tested with "shell.run", but I assume it would act the same.
To clarify:
Program called "myProgram" has "shell.getRunningProgram()" called inside of it. Another program called "myStarter" issues "os.run(vars, 'myProgram')". The above error is then encountered, even though running "myProgram" from the command prompt returns no such error.
~Plystire
1604 posts
Posted 26 April 2012 - 07:02 PM
This is not a bug. It's a "problem" in the way CraftOS is made. The shell "API" it's not a normal API, it's loaded on the shell program into the environment used to run programs. Any program called with shell.run() will have the shell API because it sets it's environment to the shell one. APIs are loaded in the global environment, so there's no shell in there.
It's something like this:
The shell environment contains the global environment, wich contains the APIs. So the APIs can't "see" the shell "API", as well as the programs run with os.run(), cause they run in the global environment.
Hope this helps understand the way the CraftOS shell works.
13 posts
Posted 26 April 2012 - 09:51 PM
Well… if we have aboard for posting "problems that aren't bugs", I'd be happy to post there.
I thought I would bring this up, because the expected result didn't happen. I run a program, and it runs fine… I have a program run the program and suddenly it doesn't run fine… :)/>/>
I needed to use the os.run() so that I could pass environment variables to the program.
Unless I misread your explanation, could I simply use "os.loadAPI("rom/programs/shell)" in my API/program to ensure that it has access to the shell "API"?
~Plystire
1604 posts
Posted 26 April 2012 - 10:27 PM
No, you can't, because it's a program, not an API. I never tried, but I think it would just run the shell, and when it exits it would load it as an API, but an empty API, cause it has no global vars to load on the API.
13 posts
Posted 26 April 2012 - 11:13 PM
I just looked into the shell program and none of the functions are declared as local, so wouldn't those be accessible still? Or am I missing something here? >_>
~Plystire
1604 posts
Posted 26 April 2012 - 11:24 PM
They aren't declared as local because they are on the shell table:
local shell = {}
function shell.run()
...
end
wich is the same as doing
local shell = { ["run"] = function() ... end }
So they are local because they are in a local table. Even if the table where global, you would have to call the API like shell.shell.<function>(), since the functions are in a table inside the API.