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

Post code tricks here!

Started by martin509, 25 March 2013 - 10:35 AM
martin509 #1
Posted 25 March 2013 - 11:35 AM
Lua is not the most flexible of languages when it comes to low-level stuff. So, CC coders, how about you tell the world about how you optimize your programs to run cleanly and efficiently?
I'll start:
I made an arcade conversion of Hurdles, and in order for it to restart, when the game exited its final line was os.reboot().
Then, I made a startup program to run hurdles again on the monitor. I thus worked around having the program directly use the monitor in its code, and saved a ton of hassles.
So anyway post your Lua tricks here!
Cloudy #2
Posted 25 March 2013 - 01:09 PM
Uh… if you think Lua isn't flexible you're doing it wrong. Look into metatables.
SuicidalSTDz #3
Posted 25 March 2013 - 01:26 PM
when the game exited its final line was os.reboot().
That is a horrible trick. os.reboot() should not be used to restart a program since it forces all tasks to stop suddenly.. Use a while loop or something else.
Sammich Lord #4
Posted 25 March 2013 - 02:06 PM
when the game exited its final line was os.reboot().
That is a horrible trick. os.reboot() should not be used to restart a program since it forces all tasks to stop suddenly.. Use a while loop or something else.
Or have everything you want in a function then just call the function when you need to.
SuicidalSTDz #5
Posted 25 March 2013 - 02:14 PM
when the game exited its final line was os.reboot().
That is a horrible trick. os.reboot() should not be used to restart a program since it forces all tasks to stop suddenly.. Use a while loop or something else.
Or have everything you want in a function then just call the function when you need to.
P'much. Restarting a computer to loop a program is the WORST thing you can do. Alas, we all make mistakes.
Bubba #6
Posted 25 March 2013 - 09:50 PM
I think one of my favorite Lua idioms is the following bit of code:

for item=1,15 do
  local condition = item<=10 and "Less than or equal to 10" or item==11 and "Equal to 11" or "Greater than 11"
  print(condition)
end

I've only ever seen condition statements like this in Java, and even there it's not as simple or powerful as what Lua has (unless I'm missing something pretty huge from Java).

Edit: Oh and also this thread has most of the lua tricks that I find useful, although metatables are missing.
theoriginalbit #7
Posted 25 March 2013 - 10:03 PM
I've only ever seen condition statements like this in Java
The ternary operator is in many languages.

and even there it's not as simple or powerful as what Lua has (unless I'm missing something pretty huge from Java).
it is just as powerful, the only restriction they put on it (that Lua does not) is that it must be used in an assignment statement, as opposed to Lua where it can be used in any way, however I have never used it in any way other than assignment statements in Lua.
Bubba #8
Posted 26 March 2013 - 05:43 AM
I guess I'd never seen that in C++ or PHP :wacko:/> That was years ago though and I didn't get too far into those so I might just have forgotten about it. Nothing like making noob programming statements on a forum devoted to programming :lol:/>
theoriginalbit #9
Posted 26 March 2013 - 05:46 AM
I guess I'd never seen that in C++ or PHP
I know for a fact that C++ has the ternary operator… pretty sure php has it….. *googles* …………………… yep PHP has the ternary operator too link
faubiguy #10
Posted 26 March 2013 - 01:20 PM
One little trick I found for ComputerCraft is that os.pullEvent (or os.pullEventRaw) can be used as an iterator function in for loops. So for any code that loops for each event, you can use the code
for event, p1, p2 in os.pullEvent do -- Add other parameter variables as needed
  -- Do stuff with event/params
end

There's not much difference from a while true do loop that calls os.pullEvent each time, but I think this looks a bit nicer.
Kingdaro #11
Posted 26 March 2013 - 05:31 PM
That's actually really neat.
theoriginalbit #12
Posted 26 March 2013 - 06:44 PM
Here is a nice bit of code that I have that replaces this statement
Old long way:

if not someVariable then
  error( 'You did not give me the parameter I wanted', 2)
end
New way:

assert( someVariable, 'You did not give me the parameter I wanted', 2)

Code that does this:

_G.assert = function(condition, errMsg, level)
  if not condition then
	error(errMsg, (tonumber(level) or 1) + 1)
  end
  return condition
end

A usage example:

views = {}
function registerKey(screen, key, text, xPos, yPos)
  -- validate the parameters
  assert(views[screen], 'A screen with the key \''..screen..'\' does not exist', 2)
  assert(not views[screen][key], 'A key with the key \''..screen..'\' already exists', 2)
  assert(type(text) == 'string', 'Invalid parameter: expected text to be a string, got '..type(text), 2)
  assert(type(xPos) == 'number', 'Invalid parameter: expected xPos to be a number, got '..type(xPos), 2)

  -- do stuff here
end

The example using the old way


local views = {}
function registerKey(screen, key, text, xPos, yPos)
  -- validate the parameters
  if not views[screen] then
	error( 'A screen with the key \''..screen..'\' does not exist', 2)
  end
  if views[screen][key] then
	error('A key with the key \''..screen..'\' already exists', 2)
  end
  if type(text) ~= 'string' then
	error('Invalid parameter: expected text to be a string, got '..type(text), 2)
  end
  if type(xPos) ~= 'number' then
	error('Invalid parameter: expected xPos to be a number, got '..type(xPos), 2)
  end

  -- do stuff here
end
Kingdaro #13
Posted 26 March 2013 - 07:13 PM
Honestly, I've only seen people here who did it the "old" way, haha.
faubiguy #14
Posted 26 March 2013 - 07:44 PM
Not everyone here does it the "old" way :P/>
Snippet from my menu code:
function menu.addOption(menuTable, name, func)
  assert(type(menuTable) == "table", "menu.addOption: menu argument must be table")
  assert(type(name) == "string", "menu.addOption: name argument must be string")
  assert(type(func) == "function", "menu.addOption: function argument must be function")
  assert(#menuTable == 3, "menu.addOption: menu argument must be of form {string, table, table}")
  assert(type(menuTable[1]) == "string", "menu.addOption: menu argument must be of form {string, table, table}")
  assert(type(menuTable[2]) == "table", "menu.addOption: menu argument must be of form {string, table, table}")
  assert(type(menuTable[3]) == "table", "menu.addOption: menu argument must be of form {string, table, table}")
  menuTable[2][#menuTable[2] + 1] = name
  menuTable[3][#menuTable[3] + 1] = func
  return menuTable
end

Edit: This is default by the way, no extra code used to add assert.
remiX #15
Posted 27 March 2013 - 12:39 AM
I think one of my favorite Lua idioms is the following bit of code:

for item=1,15 do
  local condition = item<=10 and "Less than or equal to 10" or item==11 and "Equal to 11" or "Greater than 11"
  print(condition)
end

I've only ever seen condition statements like this in Java, and even there it's not as simple or powerful as what Lua has (unless I'm missing something pretty huge from Java).

Edit: Oh and also this thread has most of the lua tricks that I find useful, although metatables are missing.

PHP way:
<?php
	for ($i=1; $i <= 15; $i++) {
   		echo $i.' - '.($i < 11 ? 'Less than or equal to 10' : ($i == 11 ? 'Equal to 11' : 'Greater than 11')).'<br>';
	}
?>
Bubba #16
Posted 27 March 2013 - 02:02 AM
I think one of my favorite Lua idioms is the following bit of code:

for item=1,15 do
  local condition = item<=10 and "Less than or equal to 10" or item==11 and "Equal to 11" or "Greater than 11"
  print(condition)
end

I've only ever seen condition statements like this in Java, and even there it's not as simple or powerful as what Lua has (unless I'm missing something pretty huge from Java).

Edit: Oh and also this thread has most of the lua tricks that I find useful, although metatables are missing.

PHP way:
<?php
	for ($i=1; $i <= 15; $i++) {
   		echo $i.' - '.($i < 11 ? 'Less than or equal to 10' : ($i == 11 ? 'Equal to 11' : 'Greater than 11')).'<br>';
	}
?>

Yup. TOB already corrected my unfortunate lack of knowledge there :)/>
theoriginalbit #17
Posted 27 March 2013 - 03:17 AM
Not everyone here does it the "old" way :P/>/>
Snippet from my menu code:
function menu.addOption(menuTable, name, func)
  assert(type(menuTable) == "table", "menu.addOption: menu argument must be table")
  assert(type(name) == "string", "menu.addOption: name argument must be string")
  assert(type(func) == "function", "menu.addOption: function argument must be function")
  assert(#menuTable == 3, "menu.addOption: menu argument must be of form {string, table, table}")
  assert(type(menuTable[1]) == "string", "menu.addOption: menu argument must be of form {string, table, table}")
  assert(type(menuTable[2]) == "table", "menu.addOption: menu argument must be of form {string, table, table}")
  assert(type(menuTable[3]) == "table", "menu.addOption: menu argument must be of form {string, table, table}")
  menuTable[2][#menuTable[2] + 1] = name
  menuTable[3][#menuTable[3] + 1] = func
  return menuTable
end

Edit: This is default by the way, no extra code used to add assert.
Only problem with this way is if they call your function wrong then the problem will be shown in your code and they blame you. With my function to override assert the throw back (level) means you can blame them not your code.
theoriginalbit #18
Posted 27 March 2013 - 03:19 AM
Honestly, I've only seen people here who did it the "old" way, haha.
And that's why I posted this trick to improve their code :)/>
MudkipTheEpic #19
Posted 27 March 2013 - 03:19 AM
Lol, I've never thought of erroring as blaming. XD
theoriginalbit #20
Posted 27 March 2013 - 04:21 AM
Lol, I've never thought of erroring as blaming. XD
How many times have you seen people posting on people's programs saying they are getting an error from the code, but in fact the problem was caused by them not using the code right. I have seen it heaps. To me that is blaming.
Kingdaro #21
Posted 27 March 2013 - 07:07 AM
Edit: Oh and also this thread has most of the lua tricks that I find useful, although metatables are missing.
I would add metatables, but I feel that they aren't really just atrick, but there are many tricks associated with them. Metatables is basically a sole reason one would use lua, and just calling it a trick doesn't serve it justice. At least a mention is deserved, however.

EDIT: I updated the topic in light of this.
Engineer #22
Posted 27 March 2013 - 01:11 PM
I think one of my favorite Lua idioms is the following bit of code:

for item=1,15 do
  local condition = item<=10 and "Less than or equal to 10" or item==11 and "Equal to 11" or "Greater than 11"
  print(condition)
end

I've only ever seen condition statements like this in Java, and even there it's not as simple or powerful as what Lua has (unless I'm missing something pretty huge from Java).

Edit: Oh and also this thread has most of the lua tricks that I find useful, although metatables are missing.

PHP way:
<?php
	for ($i=1; $i <= 15; $i++) {
   		echo $i.' - '.($i < 11 ? 'Less than or equal to 10' : ($i == 11 ? 'Equal to 11' : 'Greater than 11')).'<br>';
	}
?>
For as syntax goes Java and PHP are sort of similair. But what does the dollar sign mean? That is te only thing I dont know.
For example in java:

public class z{
 public static void main(String[] args){
for( int i; i <= 15; i++){
 System.out.println( i == 11? 'blabla' : 'other blabla' )
}
}
}

for the record, I dont know anything about PHP
Kingdaro #23
Posted 27 March 2013 - 01:13 PM
The dollar sign is just notation for variables. (Terrible notation at that.)
Engineer #24
Posted 27 March 2013 - 01:16 PM
The dollar sign is just notation for variables. (Terrible notation at that.)
Its actually quite smart to it that way. I mean you can easily see what is a variable and what not. But its kinda bad too, because you have to type it over and over again:p

Tip: ctrl+c and ctrl+v are very handy!:P/>
Kingdaro #25
Posted 27 March 2013 - 01:26 PM
It's incredibly sad that I have to constantly keep a dollar sign in my clipboard just to code in PHP.
theoriginalbit #26
Posted 27 March 2013 - 05:32 PM
Here is another code trick. you know how sometimes we want only a particular variable from a function return. Ok for example lets say we want the distance between computers and we are using 'modem_message' event. I don't know why we want the distance, lets just pretend that we do.

ok so normally you would do this

local event, receiveChannel, replyChannel, message, distance = os.pullEvent('modem_message')

but there are a few variables that are sitting there that might confuse us later. so maybe we would do this

local _, _, _, _, distance = os.pullEvent('modem_message')

that looks a little better, but why not get just the distance variable… well we all know we can put it into a table and do this

local event = { os.pullEvent('modem_message') }
local distance = event[5]

but why not just put that in one line? like so

local distance = ( { os.pullEvent('modem_message') } )[5]

this probably isn't really the best way to do things, its very expensive, as we are making a table getting one value, then destroying the table again. But I'm not telling you about this for efficiency, I'm telling you this as a "you can do this"

now we are getting only one variable from function returns. another usage example might be that you are wanting to reset the cursor to the front of the current line

-- this is how you would normally do it
local currentX, currentY = term.getCursorPos()
term.setCursorPos(1, currentY)

-- this is how you could do it with the method described above.
term.setCursorPos(1, ({term.getCursorPos()})[2])



Another trick related to the last code snippet.

term.setCursorPos( term.getCursorPos(), 4 )

this will set the cursor x pos to the first value returned by getCursorPos and ignore the other return values from that function.
remiX #27
Posted 27 March 2013 - 05:37 PM
It's incredibly sad that I have to constantly keep a dollar sign in my clipboard just to code in PHP.

I think it's a good way of showing what's a variable.
It's not hard to hold shift and click 4 :D/>
Unless you got some whack keyboard, lol
Kingdaro #28
Posted 27 March 2013 - 05:43 PM
It's difficult for me, because if I repetitively hit a key and shift/alt/ctrl at the same time, my hand tenses up and I get pains for like an hour.

Even if that weren't the case, there's a difference between hard and annoying / completely unnecessary, and it's just plain ugly. Why do I need some weirdass symbol to tell me what's a variable or not?


someVar

I'm pretty sure that's a variable.


"bleh" 42 doStuff()

I'm pretty sure this is a string, a number, and a function call.

Context clues exist, PHP.
PonyKuu #29
Posted 27 March 2013 - 08:23 PM
TheOriginalBit, I have a question about your assert.

Why do you use + 1 in your error call? If I want to call it with level 2 error, it acts as level 3 error, isn't it?
PonyKuu #30
Posted 27 March 2013 - 08:30 PM
Ah, nevermind, I derped it out.
theoriginalbit #31
Posted 27 March 2013 - 08:37 PM
TheOriginalBit, I have a question about your assert.

Why do you use + 1 in your error call? If I want to call it with level 2 error, it acts as level 3 error, isn't it?

Ah, nevermind, I derped it out.
Yeh its just because the assert is a function call itself, so you need to get out of assert and then go to the level they expected which requires a + 1.
PonyKuu #32
Posted 27 March 2013 - 08:40 PM
Yeah, thank you. That would be helpful for my APIs, since sometimes bughunting becomes a pain in the butt
theoriginalbit #33
Posted 27 March 2013 - 09:27 PM
Ok so another trick that a lot of people sadly do not know

if term.isColor and term.isColor() then
  -- this is a computer from cc1.4+ and is an advanced computer and you can change to any colour you wish.
elseif term.isColor then
  -- this is a computer from cc1.4+ and is a non-advanced computer or TURTLE and you can change between black and white
else
  -- this is a computer before cc1.4 and it means that colours are not supported
end
Kingdaro #34
Posted 28 March 2013 - 10:27 AM
There's not much point to using CC before 1.4 anyway :lol:/>
Engineer #35
Posted 28 March 2013 - 10:38 AM
There's not much point to using CC before 1.4 anyway :lol:/>/>
*cough* tekkit *cough*
Actually why play people nowadays still tekkit (im good in english 0.0), especially with the launch of the ftb launcher. I mean they are updated and not illegal..
But as far as coding tricks go, I like to do this with os.pullEvent()

local evt = {os.pullEvent()}
if evt[1] == 'your desired event' then
   -- make the ifs for that event here
elseif evt[2] == 'another event' then
 -- etc.

it keeps things organised, at least dor me :P/>
faubiguy #36
Posted 28 March 2013 - 10:46 AM
Wouldn't evt[2] be the first parameter of whichever event was pulled?
Kingdaro #37
Posted 28 March 2013 - 10:48 AM
*cough* tekkit *cough*
it keeps things organised, at least dor me :P/>/>
Tekkit Lite is updated with (almost) the latest version, IIRC. Tekkit Classic is for the people who can't let go of their overpowered EE trinkets.
remiX #38
Posted 28 March 2013 - 10:54 AM
Wouldn't evt[2] be the first parameter of whichever event was pulled?

Indeed it would be.
theoriginalbit #39
Posted 02 April 2013 - 06:36 AM
Ok so I am posting with an update to the custom assert function I posted the other day.

After reading some of the code made by the CC devs, I have discovered that if you do a level of 0 on the error function… example

error('Some Error', 0)
it will not print the error message with the file name and line number. It is essentially

printError( 'Some Error' )
error()

this is a very handy trick to quickly exit the program, print a red message, but now show it as an error in the code. so as such I have updated the assert function… here it is:

_G.assert = function(condition, errMsg, level)
  level = tonumber(level) or 1
  if not condition then
	error(errMsg, (level == 0 and 0 or level + 1))
  end
  return condition
end
Spongy141 #40
Posted 02 April 2013 - 10:36 AM
My favorite Lua trick is this

local var = read()
print(var)
yep, that is my favorite trick, got a problem?
lieudusty #41
Posted 02 April 2013 - 04:13 PM
My lua trick

os.shutdown()
SuicidalSTDz #42
Posted 02 April 2013 - 04:15 PM
My favorite Lua trick is this

local var = read()
print(var)
yep, that is my favorite trick, got a problem?
Yeah, I do ^_^/>
print(read())
I just simplified your trick, now have a cookie :P/>
Imgoodisher #43
Posted 03 April 2013 - 02:22 PM
With this bit of code:

local tbl = setmetatable({}, {
__index = function(self, index)
  if not rawget(self, index) then
   rawset(self, index, {})
  else
   return rawget(self, index)
  end
end
})
you can have a 2-dimensional table without worrying about setting (for example) tbl[1] before setting tbl[1][5]. You could probably also put the code inside itself to make 3D tables… metatableception?
theoriginalbit #44
Posted 03 April 2013 - 04:17 PM
TheOriginalBit, I have a question about your assert.
See my even newer one! :D/>
PixelToast #45
Posted 03 April 2013 - 05:06 PM
also put the code inside itself to make 3D tables… metatableception?
you forgot to return an empty table after the rawset
anyway heres your metatableception:

rawset(self,index,setmetatable({},getmetatable(self))

i used a bit of that here