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

Api Intermediate

Started by Yevano, 03 September 2013 - 05:37 PM
Yevano #1
Posted 03 September 2013 - 07:37 PM
This is a tutorial in the Ask a Pro Renewal Project series.

In this tutorial, you will learn how to expose data in APIs, when you should expose this data, and how to use local variables in your code to hide data. If you haven't yet, you should first look at the API Basics tutorial. You should also have at least basic knowledge of Lua. For the Programming in Lua manual, go here.

So, what does it mean to expose data? Well, as you saw in the last tutorial, we were able to expose our own function to the code that wants to use it. We aren't restricted, however, to just functions, nor do we even have to expose functions. Take the color API as an example, which exposes constant values that correspond to different colors. Below is the first few lines of the API.

white = 1
orange = 2
magenta = 4
lightBlue = 8
yellow = 16
lime = 32
pink = 64
gray = 128
lightGray = 256
cyan = 512
purple = 1024
blue = 2048
brown = 4096
green = 8192
red = 16384
black = 32768


We are then able to access these variables just like we would functions. For example, we can open the Lua interpreter and run the lines below.

colors.pink
colors.red
colors.cyan




This type of data exposing is good especially when you want the user code to be aware of certain constants, setting options in the API, and exposing some status about the API. But what if we don't think the user code should be allowed to get access to variables in the API? Local variables are a way of hiding data from outside code. Let's edit our old program from the API Basics tutorial to demonstrate this. Here it is if you don't have it handy.


function sayHello()
	print("Hello from testAPI!")
end

Suppose we want to make it so that the user can only call our sayHello function seven times. Any more and we spit back an error. We'll have to keep track of how many times the function is called, but the variable we'll need to use doesn't really need to be exposed to outside code, especially since the user could break our rule by changing the variable to a different number. We'll hide it by making it a local variable.


local timesLeft = 7
function sayHello()
	print("Hello from testAPI!")
	if timesLeft == 0 then
		error("Attempted to call sayHello more than 7 times!")
	end
	timesLeft = timesLeft - 1
end

We can test that this works by loading the API and then calling sayHello more than 7 times. To demonstrate that we can't see the timesLeft variable, we'll try printing it and see what we get.


os.loadAPI("testAPI")
print("The value of timesLeft is " .. tostring(testAPI.timesLeft))
for i = 1, 8 do
	testAPI.sayHello()
end
os.unloadAPI("testAPI")

Write this to a file and save it. When you run it, you should get this as output.



As you can see, testAPI.timesLeft gives us nil since it's hidden as a local variable. It doesn't exist inside the loaded API table.

Let's backtrack. In this tutorial you learned:
  • How to expose data in APIs.
  • When to expose data and when to keep it hidden.
  • How to use local variables to hide data.
Next tutorial should be up soon. Trying to get the formatting on these images right, as well. Fixed.
Molinko #2
Posted 05 September 2013 - 10:45 PM
Nice tutorial! Its funny because although i have made several programs and attempted apis i have only had success with dofile for some reason… Perhaps you could help…


-- code in api
local button = {} -- my class with methods
function newButton()
    local instance = {}
	 --- yada yada
end
-- in my program:
os.loadAPI("api/fileNameHere")
-- no i didnt actually name my file that :3
api/fileNameHere.newButton()--> outpus attempt to call nil...
Lyqyd #3
Posted 06 September 2013 - 12:38 AM
Nice tutorial! Its funny because although i have made several programs and attempted apis i have only had success with dofile for some reason… Perhaps you could help…


-- code in api
local button = {} -- my class with methods
function newButton()
	local instance = {}
	 --- yada yada
end
-- in my program:
os.loadAPI("api/fileNameHere")
-- no i didnt actually name my file that :3
api/fileNameHere.newButton()--> outpus attempt to call nil...

This isn't really the right place for this sort of question (you should use the Ask a Pro section), but you might be interested in reading through the code for my Touchpoint API to see how to set up something like what you're looking for.