This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Larry84's profile picture

shell.resolve not working

Started by Larry84, 10 September 2016 - 07:48 AM
Larry84 #1
Posted 10 September 2016 - 09:48 AM
Hi there,
I'm trying to make an API that prints a string based on the language you select using tables. For doing this it uses a language pack file, so I wanted to use shell.resolve, given that it isn't essential I think it's pretty useful. But it gives me a "attempt to index ? (a nil value)" error on line 1. I've also tried to use it in another program and it just works fine. Can someone help me?

Here it is the code:
Spoiler

languagePath=shell.resolve("lanPack")  --The path of the language pack. Default is "lanPack".

---------------IMPORTANT!!!! READ THIS!!!!----------------
--The language pack is meant to have a format like this:--
--                                                      --
-- language={										   --
--   {"name of 1st language","string 1","string 2"},	--
--   {"name of 2nd language","string 1","string 2"}	 --
-- }													--
--													  --
-- Watch out for commas! Parenthesis have to be braces! --
-- You can print the strings using "lanPrint(key)" and  --
-- "lanPrintCentered(key)", where the key is a number   --
--	 starting from 2 and raising progressively.	   --
--  In the example, lanPrint(2) will print "string 1"   --
--	   and lanPrint(3) will print "string 2".		 --
--	 You can put in as many strings as you want.	  --
------------------Thanks for attention--------------------

if fs.exists(languagePath) then  --Controls if the language pack path is correct. If not,
  os.loadAPI(languagePath)	   --creates a new empty file and returns an error.
  languages=lanPack.languages
else
  lanPack=fs.open("lanPack","w")
  lanPack.write("languages={\n  {}\n}")
  lanPack.close()
  error("The language pack ("..languagePath..") file didn't exist. Now the API have created one empty.")
end

function getTableLength(tab)  --Returns the total amount of keys stored in a table.
  local count = 0
  for _ in pairs(tab) do count = count + 1 end
  return count
end

function selector(yIn,yOut) --Gets the start y, the end y and makes a ">" selector.
  term.setCursorPos(1,yIn)  --You need to put the text you want to choose from one space from the left border (x=2)
  write(">")				--Returns the number of the choice(Eg, returns 1 if you select the first, 2 for the second...)
  enter=false
  while not enter do
	x,yAct=term.getCursorPos()
	ev,key=os.pullEvent("key")
	if key==28 then
enter=true
return yAct-yIn+1
	elseif key==200 then
if not ((yAct-1)<yIn) then
   term.setCursorPos(1,yAct)
   write(" ")
   yAct=yAct-1
   term.setCursorPos(1,yAct)
   write(">")
end
	elseif key==208 then
if not ((yAct+1)>yOut) then
   term.setCursorPos(1,yAct)
   write(" ")
   yAct=yAct+1
   term.setCursorPos(1,yAct)
   write(">")
end
	end
  end
end

function selectLanguage()  --Makes a list of the aviable languages (the first string) and makes a selection
  x,y=term.getCursorPos()  --using the selector() function.
  for key in pairs(languages) do
	print(" "..tostring(languages[key][1]))
  end
  sel=selector(y,(getTableLength(languages)+y-1))
  language=languages[sel]
end

function getLanguage()  --Just returns the name of the language selected.
  return language[1]
end

function lanPrint(n)  --Prints the string associated to the key used in the parameter.
  print(language[n])  --Usually a progressive number.
end

function lanPrintCentered(n) --Prints the string associated to the key used in the parameter.
  str=language[n]			--This time it also align the text centraly
  w,h=term.getSize()
  x=(w-math.floor(#str))/2
  oldx,y=term.getCursorPos()
  term.setCursorPos(x,y)
  print(str)
end
I would also be happy if you have any other suggestions about the program in any way. Thanks
Lyqyd #2
Posted 10 September 2016 - 01:15 PM
APIs aren't run as children of a specific shell instance, so they won't have the shell (or multishell) tables in their environment. You could copy the function out of the shell program, but a better option is probably to have your API create and return instances that programs can use to load up a specific language pack, so multiple programs could use your API at the same time for different language packs.
Larry84 #3
Posted 10 September 2016 - 03:38 PM
So, I should just make the API print the strings… The current language would be stored in a variable into the program that uses the API… But in this way every function in the API should have an argument that defines the path of the language pack.
Lyqyd #4
Posted 10 September 2016 - 03:51 PM
I'd go the route of having your API construct a table with various methods in it. The API would have a function to create and return this table, and one argument would be the path to the language pack. This table would have the language pack data loaded into it, and have functions placed into it that the program calling the API can use to get the translated strings. The program would then just call the constructor function in the API and then call the functions in the table the API returned. You could read through the vector API that comes with ComputerCraft for a simple example.
Larry84 #5
Posted 10 September 2016 - 04:39 PM
Thanks a lot. I had never seen it before, and I'll certainly look through it. Thanks again!