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

Code revision

Started by Kaaz, 27 April 2012 - 07:11 AM
Kaaz #1
Posted 27 April 2012 - 09:11 AM
A few days ago I started to get interested in computercraft.
So I looked up some information about LUA. I've programmed in various languages before.
I noticed that LUA isn't really a OO-language, however I'd like to have an OO-approach

I've started to write some code to get familiar with lua.
But before I start to write something for real, I'd like to know if I'm heading in the right direction.

The code I wrote has the effect I want, but it looks redundant.

TL;DR:
Could anyone look at my concept, and point me in the right direction to make it more elegant?

Code: http://pastebin.com/JH0BCFy3


Cheers,

Kaaz
Advert #2
Posted 27 April 2012 - 11:00 AM
I haven't looked over it thoroughly, but here are my .03$:

First and foremost, Lua isn't an acronym (i.e it's written 'Lua').

TL;DR: I would say that you're heading in the wrong direction! I'll explain why below.

You're doing stuff very inefficiently, and your 'class'es aren't re-usable (i.e you can't use them for something else without a butload of code).

1) You are creating new functions for each object: This will cost you more as the are created, but less as you call their functions (but you can do this with metatables, too).

From looking at your code, you don't seem to need to be doing this; You could use a metatable with a crafty index function instead.

An example of what this would look like is at 3).

2) Instead of doing:

local getX = function()
-- You could do:
local function getX()
Which I'd argue is more readable (although they are technically equivalent).

I'll also put this in here, since these two are somewhat minor points:
A (micro) optimization: Instead of using obj.x/y/z, you could use obj[1/2/3]: This is faster and more memory efficient, since you would be accessing an array, instead of hashing and finding the value.

3) Now that I've explained some things, I'll show you what I'd say is a better way to create one of your classes, and you can derive your other classes from it:

I'll update this in a few minutes once I'm done cooking it, but I'll leave this post here for now so you can read it :)/>/>

Edit: Here: http://ideone.com/4lmsa

Feel free to ask any questions, since I may have derped somewhere.
Kaaz #3
Posted 27 April 2012 - 12:56 PM
First off, thanks for your time. This helps me understand Lua much better.
I'm gonna need some time processing this.

I do have a question though.
Is there a way to force a parameter to be a certain datatype. For instance in java I would do

public void Derp ( String bleh, Location target )
Also, is there a method/operator similar to java's instanceof operator? And how does this work with inhiritance?

That being said, you made me realise that in physics a vector also contains a direction. So I need to think about who's responsible for what.

edit:
One odd thing I've noticed is that array's seem to start at a key value of 1
Advert #4
Posted 27 April 2012 - 01:11 PM
You're welcome :)/>/>

Yes, although it means checking yourself:

function someFunction(sAString)
if type(aString) ~= "string" then
  return nil, "someerrormessage" or error("some error")
end
end
I generally would try to return nil, "error" if you return an object, since you can then do x = assert(someFunction(…)), or try to fix it without stopping the program.

Kind of, with the above example you can check metatables:


if getmetatable(obj) == Vector then
--it's a Vector
end
If you're using the above example and you've extended a 'class' a few times, you'll have to loop through the metatables, if you want to know if it inherited stuff from another 'class'.

All in all, there are many ways of doing OO in Lua, though I'd recommend just doing it the prototype way.
Kaaz #5
Posted 27 April 2012 - 03:32 PM
My goal for the (first-) turtle is to be a mine-worker. The concept is fairly simple: Mine till its inventory is full, drop all resources at the closest droppoint and return to the closest mineshaft. I want this to be generic, so its able to work & learn without predefined area's.


I had some trouble with it, but it was mainly due to my habit of calling methods with obj.function() instead of obj.function()

So far:
http://pastebin.com/Zv9pC6X6


I think I'm getting the hang of it.
It sure looks alot more managable now.

I'm trying to implement some form of pathfiding now. I was thinking about using the A* algorithm. I've already writen that in java once. Although that was for 2 dimensions. Anyway, Thanks alot for helping me getting started!
Advert #6
Posted 27 April 2012 - 04:14 PM
Glad I could help.

Keep in mind that if you want to do pathfinding, you'll want to optimize your code quite a bit.

For your updated code, I have a few recommendations:

In the worker prototype, you're adding a vector. I'd recommend moving this to the __construct function, so you get a different vector per worker, automatically.

For your getFacing, function, I'd recommend using a table to store all the facing values:


local facings = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}
local facenames = {"North", "East", "South", "West"}

Alot is very welcome.

Have fun with your pathfinding, it can be quite tricky :)/>/>