←  Ask a Pro

ComputerCraft | Programmable Computers for Minecraft

»

Api/Function failing.

Waterspark63's Photo Waterspark63 30 Aug 2018

So I am working on a password check for my computer, and I keep getting a 'attempt to index ? (a nil value)', I have a function thats being called when that appears:

function CheckPassword()
term.clear()
printCentered(math.floor(h/2) -4, " ___________________ ")
printCentered(math.floor(h/2) -3, "|   Login Screen	|")
printCentered(math.floor(h/2) -2, "|___________________|")
printCentered(math.floor(h/2) -1, "")
write("User: "..name)
printCentered(math.floor(h/2) +0, "")
write("Pass: ")
local input2 = read()
if input2 == password then
  term.clear()
  sleep(1)
  printCentered(math.floor(h/2) +0, "Password Accepted.")
  printCentered(math.floor(h/2) +1, "Welcome back Water.")
  sleep(1)
  term.clear()
  shell.run("cd", "/home/water/desktop/")
  shell.run("menu")
end

I saw on another post that apparently you can't use shell.run in a function, they said to use os.run instead, how would I use it in this situation?
Post: http://www.computerc...ellrun-problem/

e
dit: name and password are declared outside the function
Edited by Waterspark63, 30 August 2018 - 05:12 AM.
Quote

osmarks's Photo osmarks 30 Aug 2018

You can use shell.run in functions. Anyway, this would be more helpful with the rest of the code. Also, please indent.
Quote

Nothy's Photo Nothy 30 Aug 2018

Could you post the full code, please?
Quote

Bomb Bloke's Photo Bomb Bloke 30 Aug 2018

View PostWaterspark63, on 30 August 2018 - 05:11 AM, said:

I keep getting a 'attempt to index ? (a nil value)'

That error will be accompanied by a number which indicates the line that triggered it. It's rather difficult to troubleshoot your code if you don't at least point that line out.

View PostWaterspark63, on 30 August 2018 - 05:11 AM, said:

I saw on another post that apparently you can't use shell.run in a function

That's not what was said - rather, you can't use it from within the code of an API. Functions and APIs aren't at all the same thing! If you're not writing something you intend to process through os.loadAPI(), then that limitation isn't relevant.
Edited by Bomb Bloke, 30 August 2018 - 10:51 AM.
Quote

EveryOS's Photo EveryOS 30 Aug 2018

However, if you are writing an OS (and it appears you are), I would recommend not using shell.run or os.loadAPI

BTW, if you loadfile-d that file, than that may be the problem
Quote

Waterspark63's Photo Waterspark63 30 Aug 2018

Well, the function is in a api, anyway, heres the full code, and I have modified it a bit, but still the same problem, and it says its the line with shell.run("cd", "/home..etc..."):
And EveryOS, then how do you recommend doing it?
Function/API File:
local w,h = term.getSize()
function printCentered (y,s)
  local x = math.floor((w - string.len(s)) / 2)
  term.setCursorPos(x,y)
  term.clearLine()
  print(s)
end

local file = fs.open("/system/settings/users/water-usersettings", "r")
local settings = textutils.unserialize(file.readAll())
file.close()

function CheckPassword()
  term.clear()
  printCentered(math.floor(h/2) -4, " ___________________ ")
  printCentered(math.floor(h/2) -3, "|   Login Screen	|")
  printCentered(math.floor(h/2) -2, "|___________________|")

  printCentered(math.floor(h/2) -1, "")
  write("User: "..settings[1])
  printCentered(math.floor(h/2) +1, "")
  write("Pass: ")
  local input2 = read()
  if input2 == settings[2] then
	term.clear()
	sleep(1)

	printCentered(math.floor(h/2) +0, "Password Accepted.")
	printCentered(math.floor(h/2) +1, "Welcome back Water.")
	sleep(1)
	term.clear()

	shell.run("cd", "/home/"..settings[1].."/desktop/")
	shell.run("menu")
  end
end

The 'login' file:
local w,h = term.getSize()
function printCentered (y,s)
local x = math.floor((w - string.len(s)) / 2)
term.setCursorPos(x,y)
term.clearLine()
print(s)
end

shell.run("cd", "/")
os.loadAPI("/system/software/utils/mainutils")
term.clear()

printCentered(math.floor(h/2) +0, "Loading Login Screen...")
sleep(2)

printCentered(math.floor(h/2) -4, " ___________________ ")
printCentered(math.floor(h/2) -3, "|   Login Screen	|")
printCentered(math.floor(h/2) -2, "|___________________|")

printCentered(math.floor(h/2) +0, "")
write("User: ")
inputlogin = read()
local file = fs.open("/home/userlist", "r")
local users = textutils.unserialize(file.readAll())
file.close()

for i=1,#users do
  if users[i] == inputlogin then
	os.loadAPI("/home/"..users[i].."/userutils")
	userutils.CheckPassword()
  else
	term.clear()
	sleep(1)
	printCentered(math.floor(h/2) +0, "Username "..inputlogin.." was not found!")
	sleep(1)
	shell.run("/system/software/user/login")
  end
end


Edited by Waterspark63, 30 August 2018 - 02:36 PM.
Quote

EveryOS's Photo EveryOS 30 Aug 2018

I'm generally a fan of loadfile
--Instead of shell.run
loadfile("blah/blah", _G)(param1, param2, ...)
--Instead of os.loadAPI
local blah = loadfile("blah/blah", _G)()

Your problem could probably be fixed with this code:
_G["shell"] = shell
Paste that at the beginning of your login file
Quote

Nothy's Photo Nothy 30 Aug 2018

shell is not available in APIs you load with os.loadAPI()
Quote

Waterspark63's Photo Waterspark63 30 Aug 2018

Thank you EveryOS, your idea worked. (_G["shell"] = shell)
Quote

EveryOS's Photo EveryOS 30 Aug 2018

You are welcome

I still recommend you switch to loadfile
Quote

Lyqyd's Photo Lyqyd 01 Sep 2018

View PostWaterspark63, on 30 August 2018 - 04:01 PM, said:

Thank you EveryOS, your idea worked. (_G["shell"] = shell)

This is a bad idea. There is a very good reason that the shell "API" isn't available to global-level things like APIs, and that's because there's no way to know which shell is the right one to use. It probably won't hurt in this specific use case, but it must be stated that this is extremely bad practice. Any API that really, truly, needs access to the shell functions should have the appropriate instance of the shell table passed to it by the caller, and should make no attempt to store that instance.

Using loadfile instead of built-in functions is also silly when it isn't strictly necessary.
Quote

EveryOS's Photo EveryOS 05 Sep 2018

View PostLyqyd, on 01 September 2018 - 08:52 PM, said:

View PostWaterspark63, on 30 August 2018 - 04:01 PM, said:

Thank you EveryOS, your idea worked. (_G["shell"] = shell)

This is a bad idea. There is a very good reason that the shell "API" isn't available to global-level things like APIs, and that's because there's no way to know which shell is the right one to use. It probably won't hurt in this specific use case, but it must be stated that this is extremely bad practice. Any API that really, truly, needs access to the shell functions should have the appropriate instance of the shell table passed to it by the caller, and should make no attempt to store that instance.

Using loadfile instead of built-in functions is also silly when it isn't strictly necessary.

Require was not available in earlier CC versions, and os.loadAPI has many quirks I don't like, e.g. it is global, and you can't enter parameters, and I prefer to return a table rather than modifying _ENV
Edited by EveryOS, 05 September 2018 - 03:01 PM.
Quote

Lupus590's Photo Lupus590 05 Sep 2018

View PostEveryOS, on 05 September 2018 - 03:00 PM, said:

Require was not available in earlier CC versions, and os.loadAPI has many quirks I don't like, e.g. it is global, and you can't enter parameters, and I prefer to return a table rather than modifying _ENV

http://www.computerc...-computercraft/
Quote

EveryOS's Photo EveryOS 05 Sep 2018

Then you need extra files
Quote

Lyqyd's Photo Lyqyd 06 Sep 2018

View PostEveryOS, on 05 September 2018 - 03:00 PM, said:

Require was not available in earlier CC versions, and os.loadAPI has many quirks I don't like, e.g. it is global, and you can't enter parameters, and I prefer to return a table rather than modifying _ENV

That's fine, but you personally not liking the "quirks" is not justification for proselytizing against using built-in functionality or intended design. If a question specifically asks for support using loadfile(), fine; advocating it without prompting is not helpful or useful advice.
Quote