code logs -> 2006 -> Thu, 10 Aug 2006< code.20060809.log - code.20060811.log >
--- Log opened Thu Aug 10 00:00:02 2006
00:03 ReivUni [~82d94c4d@Nightstar-14006.mail.city-net.pl] has joined #Code
00:04 * ReivUni has an epiphany as to how to do his assignment. Don't mind him, he's going to babble so the home account catches it.
00:04
< ReivUni>
Ok.
00:05
< ReivUni>
Peice position on the board is going to be handled by an arraylist instead of a two dimensional array. This will track the position of the individual peices.
00:05
< ReivUni>
Each peice is an object, with type, and position data.
00:05
< ReivUni>
As instance variables, anyway.
00:06
< ReivUni>
Movement rules for vertical, horizontal, and angle movement will be, uh.
00:08
<@ToxicFrog>
'arraylist'?
00:08
<@ToxicFrog>
Assignment is a chess game, I take it?
00:08
< ReivUni>
Vertical: Take relative movement between the two peices, one of the X/Y results must be 0, whilst other non-zero.
00:08
< ReivUni>
yes
00:09
< ReivUni>
Diagonal movement, both must be non-zero /and same offset/.
00:09
< ReivUni>
Hm.
00:09
< ReivUni>
Absolute values thereof, anyway...
00:10
< ReivUni>
X/Y offset of +3, -3 is a legit move afterall.
00:11
< ReivUni>
Knights have abs offsets of 2,1 and 1,2 as legit.
00:11
< ReivUni>
Pawns have, uh. 0,1, with 0,2 if they start on the second row, and abs 1,1 if there is opposing peice in the square.
00:12
< ReivUni>
Movement... check every square between peice and destination for null. If non-null, is non-legit. Destination square is the same, but if is occupied by opposing peice, then it is legit, and opposing peice is deleted.
00:13
< ReivUni>
Will make those two methods seperate, not least because pawns bugger up the latter half, and knights bugger up the first half and so will overwrite the collision and taking methods.
00:14
< ReivUni>
Er. Each will overwrite the respective method that needs changing.
00:14
< ReivUni>
...Take function can also check if opposing peice is a king and return a victory flag, woot!
00:14
<@ToxicFrog>
...that's not quite how you win~
00:15
<@ToxicFrog>
Also, what do you mean by an 'arraylist'?
00:15
< ReivUni>
...Okay, /opposing/ king. :p
00:15
< ReivUni>
Er.
00:15
<@ToxicFrog>
That's still not how you win. You don't win by capturing the enemy king, you win by getting him into a situation where he can't evade capture :P
00:16
<@ToxicFrog>
(also, isn't it "piece"?)
00:17
< ReivUni>
Arraylist is a Java object thingy.
00:18
< ReivUni>
And our rules don't have to worry about castling, pawn en passant, or check, TF
00:18
< ReivUni>
So without the check rules, checkmate really /is/ when you kill the king. >.>
00:18
< ReivUni>
(Ironically this code would actually be pretty capable of doing check, uh, checks, but that's not the point.)
00:19
<@ToxicFrog>
Aah.
00:19
<@ToxicFrog>
That's convenient.
00:19
<@ToxicFrog>
Alright, why an arraylist and not a two-dimensional array?
00:19
< ReivUni>
Arraylist is a class in the java libraries. Um. You can add and delete objects in the array.
00:20
<@ToxicFrog>
How does this differ from a two-dimensional array?
00:20
< ReivUni>
Er. By tracking peices, not the board itself.
00:21
<@ToxicFrog>
Aah. I see. It's a vector of pieces, with pieces removed as they are taken.
00:21
< ReivUni>
I'll have an Arraylist that tracks X peices, each peice has a type and a position. The empty squares will return null.
00:21
< ReivUni>
Yes
00:21
< ReivUni>
I think this could work slightly better because we /also/ have to have an AI able to move peices in a randomized fashion. (So more an Adolt, but what the hell).
00:21
<@ToxicFrog>
Alright, so given this, how do you look up a piece by location rather than by array index?
00:22
<@ToxicFrog>
After all, you need to able to translate a coordinate-pair into a piece in order to implement move checking, capture, etc.
00:23
< ReivUni>
Arraylist.contains(Object element)
00:23
<@ToxicFrog>
...not quite what I mean.
00:23
< ReivUni>
I /think/ that will let you use getters on teh object inside.
00:24
<@ToxicFrog>
Say you have a Pawn at (0,1)
00:24
<@ToxicFrog>
You try to move it to (0,2)
00:24
<@ToxicFrog>
You need to be able to take (0,2) and turn into either an Object or null, to determine if it's a legal move or not.
00:24
< ReivUni>
So it would be Arraylist.contains(Peice.getY != 2) I hope?
00:25
< ReivUni>
...No
00:25
<@ToxicFrog>
...IIRC, Arraylist.contains does not work at all like that.
00:25
< ReivUni>
Oh. Bugger.
00:25
<@ToxicFrog>
You pass it an object reference, and it tells you if it already has a reference to that object in the list.
00:25
< ReivUni>
Hrm. I see.
00:25
<@ToxicFrog>
I believe, let me look it up.
00:25
< ReivUni>
So not so good at quickly searching through the array as I'd hoped.
00:26
< ReivUni>
Darn, that was what I was hoping to be able to do >.>
00:26
<@ToxicFrog>
Yeah. It behaves like this:
00:26
<@ToxicFrog>
ArrayList foo = new ArrayList<String>;
00:27
<@ToxicFrog>
String bar = new String("Testing, testing...");
00:27
<@ToxicFrog>
foo.contains(bar); -> false
00:27
<@ToxicFrog>
foo.add(0, bar);
00:27
<@ToxicFrog>
foo.contains(bar); -> true
00:27
< ReivUni>
...Hrm.
00:27
< ReivUni>
Is it possible to have a two dimensional arraylist? >.>
00:28
<@ToxicFrog>
...you could have an array of ArrayLists, but /why/?
00:28
< ReivUni>
...Or you could cheat with 00 01 10 52 as your xy, perhaps, but that is Naughty(tm).
00:28
< ReivUni>
I think.
00:28
<@ToxicFrog>
All it does it make your code more complicated, harder to work with and harder to debug.
00:29
<@ToxicFrog>
Yeah, you could do index = (x*10)+y or something.
00:29 * ReivUni was hoping to have a way of just tracking what peices were still on the board.
00:30
<@ToxicFrog>
So use an object xref table.
00:30
< ReivUni>
A what?
00:30
<@ToxicFrog>
You have a two-dimensional array that maps coordinates to pieces, and a vector that maps indexes to pieces (and thus to coordinates).
00:31
<@ToxicFrog>
So if you need to look up a piece by location, you check board[x][y], and if you need to iterate over all pieces or something, you use ArrayList<Piece> pieces.
00:31 MWork [~db585354@85.219.239.ns-22164] has joined #code
00:32
< ReivUni>
And I make sure when you delete a peice, it updates both arrays?
00:32
< ReivUni>
...Or I do it all OO and have a capturepeice(x, y) function that makes /sure/ it does so.
00:32
<@ToxicFrog>
Well. It's been a while since I was feeling masochistic enough to use Java, but I think if you call delete on one reference it'll automatically null out the others.
00:32
< ReivUni>
Yes?
00:33 * ReivUni eyes that.
00:33
<@ToxicFrog>
Also, ArrayList<> has a remove(Object) method.
00:33
< ReivUni>
Wait, so... you'd have a two dimensional board that was drawn off of the arraylists peices, y/n?
00:33
<@ToxicFrog>
So you could do something like this:
00:33
<@ToxicFrog>
Piece::~Piece() {
00:33
< ReivUni>
Or would you have a static two dimensional board, and the arraylist off to the side?
00:33
<@ToxicFrog>
pieces.remove(this);
00:34
<@ToxicFrog>
board[x][y] = null;
00:34
<@ToxicFrog>
return;
00:34
<@ToxicFrog>
}
00:34
<@ToxicFrog>
The latter.
00:34
<@ToxicFrog>
Piece[][] board = new Piece[8][8];
00:34
<@ToxicFrog>
ArrayList pieces = new ArrayList<Piece>()
00:35
< ReivUni>
Right. So just need to make sure when one bit is captured, it's also removed from the arraylist.
00:35
<@ToxicFrog>
Well, actually, I guess it'd be new ArrayList<Piece>(32);
00:35
<@ToxicFrog>
Yes. Which is what the destructor above does.
00:35
<@ToxicFrog>
ArrayList::remove(Object o) removes that object from the list, if present.
00:35
< ReivUni>
And... hrm.
00:35
<@ToxicFrog>
So, given a piece P, you can remove it from both data structures with:
00:36
<@ToxicFrog>
pieces.remove(P); // remove from the arraylist
00:36
<@ToxicFrog>
board[P.x][P.y] = null; // remove from the board
00:36
<@ToxicFrog>
Presumably you would put this in the destructor so that you can just delete P; and have it work.
00:36 * ReivUni pauses, ponders.
00:37
< ReivUni>
So would I have peice objects, or would I be treating them as data points in the board array?
00:37
<@ToxicFrog>
...'data points'?
00:37
< ReivUni>
Er.
00:38
< ReivUni>
IF board(X, Y) == P { Apply pawn rules }
00:38
<@ToxicFrog>
They'd be objects of type Piece (or some subclass thereof, presumably); the board is an array[8][8] of Pieces, which - this being Java - contains references to them rather than copies.
00:38
<@ToxicFrog>
board[X][Y].moveTo(newX, newY);
00:38
< ReivUni>
So to move a peice one shifts the reference, and then deletes the old one.
00:39
<@ToxicFrog>
Yes. The implementation might look something like:
00:39
< ReivUni>
And if the peice is moved to capture something, one also needs to delete the captured bit from the Arraylist to the side.
00:39
<@ToxicFrog>
Piece::moveTo(int newX, newY) {
00:39
<@ToxicFrog>
checkLegalityOfMove(newX, newY); // check for clear path & obeys this piece's movement rules
00:40
<@ToxicFrog>
checkForCapture(newX, newY); // delete enemy piece at target square if any
00:40
<@ToxicFrog>
board[X][Y] = null; // remove us from our current location
00:40
<@ToxicFrog>
board[newX][newY] = this; // and put us at our new one
00:40
<@ToxicFrog>
X = newX; Y = newY; // update internal data structures
00:40
<@ToxicFrog>
return;
00:40
<@ToxicFrog>
}
00:41
<@ToxicFrog>
A full implementation would throw exceptions for illegal moves and so forth, presumably.
00:41 * ReivUni eyes. Just as a sidenote, don't you need to do the [newX][newY] before you set [X][Y] to null?
00:42
< ReivUni>
As java garbage collectors attack objects without references to them, but.
00:42 * ReivUni hrms, fiddles.
00:43
< ReivUni>
Seems... less clean, sorta, than having an Arraylist storing peice type and location, and just updating the location as needed. I'm assuming this impression is wrong, but...
00:44
<@ToxicFrog>
It's less clean in the sense that you have twice as many data structures.
00:44
< ReivUni>
Right.
00:44
<@ToxicFrog>
It's more clean in the sense that looking up a piece by location is now much, much simpler and faster.
00:44
< ReivUni>
And drawing the board would be too, I assume.
00:45
<@ToxicFrog>
Depends. Drawing the board is actually easier with an ArrayList, I think.
00:45
<@ToxicFrog>
If you can use background images, anyways.
00:45
<@ToxicFrog>
Lay down the board as a background, then iterate over the ArrayList and draw each piece.
00:45
< ReivUni>
Nah. We're boilerplating ASCII.
00:45
< MWork>
Ugh.
00:46
<@ToxicFrog>
Oh. Dumb terminal, or curses?
00:46
<@ToxicFrog>
If the former, the two-dimensional array is easier; if the latter, the ArrayList...maybe.
00:48
< ReivUni>
Dumb terminal.
00:48
< ReivUni>
So yeah, former.
00:48
< ReivUni>
http://www.cs.waikato.ac.nz/Teaching/COMP209B/assignments/Assignment1.pdf is the actual assignment.
00:49
< ReivUni>
(Don't worry too much about the 'own work' thing; asking for advice and code layouts/concepts is fine - having the entire assignment copied off a mate, of course, is not.)
00:51 MWork [~db585354@85.219.239.ns-22164] has quit [Quit: Client is home!]
00:51 * ToxicFrog nods.
00:51
< ReivUni>
(What is sad is how many people will copy entire classes and methods off each other /including comments/ verbatim, and not expect to get caught. :p)
00:51
< ReivUni>
So yeah, two dimensional is probably best, then. Hrm.
00:52
< ReivUni>
...The arraylist is only used for the AI player now, isn't it? Ergo, it only needs to be /made/ when you have an AI player?
00:52
<@ToxicFrog>
(and I ganked this approach from System Shock anyways, so~)
00:53
< ReivUni>
...No, that wouldn't work, because you need to have it in the methods to remove the peice from the arraylist when it's captured, and having the arraylist only there on a conditional basis would make life complicated.
00:54
<@ToxicFrog>
ArrayList::remove() works even if the object isn't there.
00:54
<@ToxicFrog>
However, it's probably easiest just to use it even when the AI isn't present.
00:58
< ReivUni>
For anything in particular, though?
01:00
<@ToxicFrog>
Rephrase?
01:00
< ReivUni>
What will we be using the arraylist for when the AI is not present?
01:00
< ReivUni>
It is sort of... getting a touch superfluous.
01:01
<@ToxicFrog>
Unless you want an on-screen list of pieces in play or something, nothing.
01:01
< ReivUni>
Right. Alas.
01:01
<@ToxicFrog>
But it's easier to have it always present, than to have it present only when the AI is as well. And it's not large enough to be a significant performance hit.
01:01 * ReivUni nods. Just... y'know, coder cleanliness. >.>
01:01
<@ToxicFrog>
Premature optimization is the root of all evil.
01:02
< ReivUni>
Hrm. Okays, then.
01:03
< ReivUni>
So... what does a peice need the instance variables for location for? We seem to be doubling up on location data - stored both in the board itself an inside the peice.
01:04
<@ToxicFrog>
Two reasons:
01:04
<@ToxicFrog>
- so that, given a piece from the ArrayList, you can map it to its board location
01:05
<@ToxicFrog>
- so that you can call things like moveTo() or the piece's destructor without having to pass in the piece's coordinates
01:06
< ReivUni>
...It still seems as if we sort of don't really need either the array list/instance variables, or the board array, because the two seem to result in pretty heavy redundancy.
01:06
<@ToxicFrog>
Well. It is true that if you're willing to write a bunch of search functions instead, you can do away with this.
01:07
<@ToxicFrog>
Personally, I'd rather have an extra 64 bytes of memory use than an extra 200 lines of code.
01:07
< ReivUni>
Hmm.
01:08
<@ToxicFrog>
Consider. The AI wants to make a move. It picks a unit from the ArrayList. Now it needs to know where it is!
01:08
<@ToxicFrog>
It can either access the member variables, or do a linear search of the entire board.
01:08
< ReivUni>
And then the board is used for movement legality checks.
01:08
<@ToxicFrog>
Conversely. Say we have member variables but no board.
01:09
< ReivUni>
Right
01:09
<@ToxicFrog>
If we want to check the legality of a move, we need to map coordinates to pieces...which means either indexing the board, or linear-searching the ArrayList and querying the coordinates of each piece.
01:09
<@ToxicFrog>
(or binary-searching it or something if you can get it to be sorted by coordinates)
01:09
<@ToxicFrog>
While these structures aren'
01:09
<@ToxicFrog>
t strictly /necessary/, they simplify the program.
01:10
< ReivUni>
So we double-bookeep in the name of simplicity. Hmm.
01:11
< Lukhan>
Correct.
01:11
<@ToxicFrog>
(this is part of the philosophy that it is 'better to have smart data than smart code', which is usually correct~)
01:12
< ReivUni>
Mostly because we can't directly link the arraylist co-ordinates to any direct reference...
01:12
< Lukhan>
extra bookkeeping is bad /if and only if/ the effort required to maintain the bookkeeping is worse than than the effort required to do without it.
01:13
<@ToxicFrog>
Or if you're working under draconian resource constraints (programming for small embedded systems, say) but that's an edge case.
01:13
< ReivUni>
It does double the amount of code used everywhere, though...
01:13
< ReivUni>
Well, for movement.
01:13
< Lukhan>
toxic: well. yes. but people love to talk about that edge case for no good reason, I find.
01:13
< ReivUni>
And we get marks for code cleanliness. ^^;
01:13
< Lukhan>
Reiv: What about the code it cleans up elsewhere?
01:14
< Lukhan>
And how much of the code is actually devoted to movement ... and is there any way to factor out the extra code into functions?
01:14
<@ToxicFrog>
ReivUni: how exactly does this double the movement code?
01:15
< ReivUni>
Your code snippet above.
01:15
< Lukhan>
also the start data vs smart code is true primarily because our brains handle complicated data much more easily than they handle complicated procedures. simple and logical result of the environment we live in ...
01:15
<@ToxicFrog>
It adds, I think, one line to the destructor and two to moveTo(), and vastly simplifies checkLegalMove() and the AI.
01:16
< ReivUni>
So can I still get away with the movement rules being, uh, abstracted like they were? CheckStraight, CheckDiag, and the special cases for Pawns and Knights?
01:16
< Lukhan>
Rule of thumb: Turning one two-hundred-line function into a fifty-line function is worth tripling the size of three ten-line functions. ;)
01:16
< ReivUni>
Oh, and kings, but that's just absolutes being <=1, <=1.
01:16
< ReivUni>
Er.
01:16
< ReivUni>
The relative movement being <=[1], <=[1]
01:17
< ReivUni>
But.
01:17
<@ToxicFrog>
Personally, I would define a few basic checks (isHorizontal, isDiagonal, isClear) in the superclass and give each subclass its own simple movement routines.
01:18
< ReivUni>
Right, that was my thought
01:18
<@ToxicFrog>
So for example, the queen is (isHorizontal(newX, newY) || isDiagonal(newX, newY)) && isClear
01:18
< ReivUni>
isStraight, isDiagonal,
01:18
<@ToxicFrog>
(newX, newY)
01:18
< ReivUni>
Yah
01:18
<@ToxicFrog>
Yes. Sorry.
01:18
<@ToxicFrog>
This basically means that moveTo() and isWhatever() are all in the superclass.
01:19
<@ToxicFrog>
Each class just needs to define its own checkLegalMove(*)
01:19
< ReivUni>
Right, that was my thinking
01:19
< ReivUni>
...Then we get to what /does/ isClear check? Does it check the endpoint?
01:19
< ReivUni>
I am thinking it iterates all squares between mover and destination.
01:19
<@ToxicFrog>
Yes.
01:20
< ReivUni>
But does it check the final square?
01:20
< ReivUni>
Or do we make it non-boolean, and have Clear, Blocked, Capture as the results?
01:20
<@ToxicFrog>
I think the final square is checked in checkForCapture() instead.
01:20
< ReivUni>
Right.
01:20
<@ToxicFrog>
checkForCapture() will throw an exception if there's a friendly piece there.
01:20
< ReivUni>
Yes!
01:20
<@ToxicFrog>
So it ends up in the exception handler at some higher level and the piece never actually gets moved.
01:21
<@ToxicFrog>
Similarly, you can basically do error checking by having isWhatever() throw an exception if the condition is false. (possibly it should be called checkWhatever()?)
01:21
<@ToxicFrog>
Then you do something like:
01:21
<@ToxicFrog>
try {
01:21
<@ToxicFrog>
P.moveTo(newX, newY);
01:22
<@ToxicFrog>
} catch(Exception E) {
01:22
<@ToxicFrog>
error("Illegal move! " + E.message);
01:22
<@ToxicFrog>
}
01:22
< ReivUni>
...Can you /do/ try loops in Java?
01:23
<@ToxicFrog>
...try-catch is Java's primary error handling mechanism.
01:23
< ReivUni>
(I get the meaning either way, this is my nosy.)
01:23
< ReivUni>
Oh. Cool.
01:23
<@ToxicFrog>
try {
01:23
<@ToxicFrog>
// code block
01:23
<@ToxicFrog>
} catch(ExceptionSubclass E) {
01:23
<@ToxicFrog>
// exception handler
01:23
<@ToxicFrog>
}
01:23
<@ToxicFrog>
I believe you can chain exception handlers, too (but don't quote me on this):
01:23
< ReivUni>
We haven't been told about it yet. I'll ask the lecturer if I'd get in trouble for being complicated. ;)
01:23
<@ToxicFrog>
} catch(FooException E) {
01:24
<@ToxicFrog>
FooError();
01:24
<@ToxicFrog>
} catch(BarException E) {
01:24
<@ToxicFrog>
BarError();
01:24
<@ToxicFrog>
} catch(Exception E) {
01:24
<@ToxicFrog>
GenericError();
01:24
<@ToxicFrog>
}
01:24 * ReivUni nods.
01:24
<@ToxicFrog>
And a thrown exception will fall through the chained handlers until it hits one that it matches the signature for.
01:24
< ReivUni>
Hm!
01:25
<@ToxicFrog>
But I may be getting the sytax wrong and/or confusing it with other languages, it's been a while.
01:25
< ReivUni>
Is fine
01:25
< ReivUni>
checkCapture is the one that Pawns mess with. Yes.
01:25
< ReivUni>
In fact most of its movement rules are just in checkCapture.
01:25
<@ToxicFrog>
(also, being complicated? This is /less/ complicated than passing return codes through 3-4 stack frames!)
01:25
< ReivUni>
Meaning the name is a slight misnomer, but that is well.
01:26
<@ToxicFrog>
Yeah. Pawn will have to overload both checkLegalMove() and checkCapture().
01:26
< ReivUni>
...Queening...
01:27
< ReivUni>
delete pawn, create new queen?
01:27
<@ToxicFrog>
Yep.
01:27
< ReivUni>
Because each is a subclass of the main class, rather than just an instance variable inside the object. Okays.
01:28
< ReivUni>
Hm!
01:28
< ReivUni>
Initialising the board. Is it possible to say "Next twenty squares, empty" in code cleanly? >.>
01:29
<@ToxicFrog>
Umm.
01:29
<@ToxicFrog>
I am very, very rusty on my Java array initialization.
01:30
<@ToxicFrog>
I believe that what you want to do is create an array of Pieces initialized to all null, then fill in spots as needed.
01:32
< ReivUni>
BoardArray[8][8] = {R, N, B, Q, K, B, N, R} is well and good, but then you have 8 P, 4*8 null, and then 8 p, and {r, k, b, k, q, b, n, r}...
01:32
< ReivUni>
Which is fine. Sorta.
01:34
<@ToxicFrog>
I think you can go:
01:34
<@ToxicFrog>
Piece[][] board = new Piece[8][8]; // 8x8 array of null
01:34
<@ToxicFrog>
new Rook(0,0);
01:34
<@ToxicFrog>
new Rook(7,7);
01:34
<@ToxicFrog>
...
01:34
<@ToxicFrog>
...actually, you need a third argument for ownership.
01:35
<@ToxicFrog>
But, what you do is you write the constructor so that it automatically inserts it into the board.
01:35
< ReivUni>
...Ah. We have to do it that way? >.>
01:35
< ReivUni>
Right, ok.
01:35
< ReivUni>
0,7 :)
01:35
< ReivUni>
Yes, you do.
01:35
< ReivUni>
0,0,R
01:35
< ReivUni>
vs 0,8,r
01:35
< ReivUni>
Or possibly B and W
01:36
<@ToxicFrog>
new Rook(true, 0, 0);
01:36
<@ToxicFrog>
new Rook(true, 7, 0);
01:36
<@ToxicFrog>
new Rook(false, 0, 7);
01:36
<@ToxicFrog>
new Rook(false, 7, 7);
01:36
< ReivUni>
true vs false for B and W?
01:37
<@ToxicFrog>
Unless you're planning on N-player chess~
01:37
<@ToxicFrog>
Anyways. You don't /have/ to do it that way. You can also use curlybraces.
01:37
<@ToxicFrog>
http://www.janeg.ca/scjp/lang/arrays.html <-- a nice summary
01:38
< ReivUni>
Well, okay, point.
01:38
< ReivUni>
But benifits of using true and false as boolean vs white and black as strings?
01:38
<@ToxicFrog>
Better performance on both axes with no added code complexity.
01:38
<@ToxicFrog>
And it's just as readable with the following:
01:39
<@ToxicFrog>
static final bool BLACK = true;
01:39
<@ToxicFrog>
static final bool WHITE = false;
01:39
<@ToxicFrog>
And then you can:
01:39
<@ToxicFrog>
new Root(BLACK, 0, 0);
01:39
<@ToxicFrog>
new Rook(WHITE, 7, 7);
01:40
< ReivUni>
..Oh. Sneaky. I like.
01:41 Mahal [~Mahal@Nightstar-5192.worldnet.co.nz] has joined #code
01:41 mode/#code [+o Mahal] by ChanServ
01:41
< ReivUni>
Also, B vs w...
01:41
<@ToxicFrog>
(this also means that if you ever decide to make it N-player, you still have to change the function signatures from 'bool' to 'int' or whatever, but you /don't/ have to change the function calls - just change the definitions of BLACK and WHITE (and add GREEN and BLUE and OCTARINE or whatever))
01:43
< ReivUni>
Heh. Right.
01:43
< ReivUni>
...Oh. Wait. Hrm. How's that work?
01:43
< ReivUni>
Displaying the array. If null is easy, but if it's an object...
01:44
< ReivUni>
You'd have a Peice.Display() method, that returns the appropriate letter and size.
01:44
< ReivUni>
I'm mostly wondering how you do that /cleanly/.
01:45
<@ToxicFrog>
letter and /size/?
01:46
< ReivUni>
Uppercase vs lowercase.
01:46
< ReivUni>
Er.
01:46
<@ToxicFrog>
Aah.
01:46
<@ToxicFrog>
void Piece::Display() {
01:46
<@ToxicFrog>
System.out.print(myDisplayCharacter);
01:47
<@ToxicFrog>
}
01:47
<@ToxicFrog>
class Pawn extends Piece {
01:47
<@ToxicFrog>
myDisplayCharacter = 'p';
01:47
<@ToxicFrog>
...
01:47
<@ToxicFrog>
}
01:47
<@ToxicFrog>
class King extends Piece {
01:47
<@ToxicFrog>
myDisplayCharacter = 'K';
01:47
<@ToxicFrog>
....
01:47
<@ToxicFrog>
}
01:47
<@ToxicFrog>
Etc.
01:47
< ReivUni>
And when it is black, which uses P instead of p?
01:47
< ReivUni>
The two sides are differentiated by case.
01:47
<@ToxicFrog>
Aah. Ok then:
01:48
<@ToxicFrog>
void Piece::Display() {
01:48
<@ToxicFrog>
if(color == BLACK) {
01:48
<@ToxicFrog>
System.out.print(toUpperCase(myDisplayCharacter));
01:48
<@ToxicFrog>
} else {
01:48
<@ToxicFrog>
System.out.print(myDisplayCharacter);
01:48
<@ToxicFrog>
}
01:48
<@ToxicFrog>
}
01:48
<@ToxicFrog>
And then enter them all as lowercase.
01:48
<@ToxicFrog>
Then the display loop is something like:
01:49 * ReivUni hees. We booleaned BLACK! So... if(BLACK) { }
01:49
< ReivUni>
Y/N?
01:49
<@ToxicFrog>
No, that won't work.
01:49
<@ToxicFrog>
if(BLACK) -> if(TRUE)
01:49
<@ToxicFrog>
You need if(color)
01:49
<@ToxicFrog>
or, for clarity, if(color == BLACK)
01:49
< ReivUni>
...Ohh. Right. Ok.
01:49
<@ToxicFrog>
And the display loop is something like
01:49
<@ToxicFrog>
for(each row, starting at the top)
01:50
<@ToxicFrog>
for(each cell in this row)
01:50
<@ToxicFrog>
if(cell == null)
01:50
<@ToxicFrog>
System.out.print('.');
01:50
<@ToxicFrog>
else
01:50
<@ToxicFrog>
cell.Display();
01:50
<@ToxicFrog>
end
01:51
<@ToxicFrog>
System.out.println(); // newline
01:51
<@ToxicFrog>
end
01:51 * ReivUni nod. And then the ASCII art wedged in around it. That's not too bad.
01:52
< ReivUni>
...Right. I am actually getting a handle on zis.
01:53
< ReivUni>
Excelent. Thankye, TF.
01:56 * ReivUni did have such hopes for the arraylist, but c'est la vie. ;)
01:56
< ReivUni>
...Oh, we have to have a text file explaining the problem.
01:56
< ReivUni>
I can put my justification for simple data over simple code in there and sound intelligent. ¬¬
01:57
< ReivUni>
However, now I must flee. I got the braindump outta my head though, so that's the main thing.
01:57
<@Mahal>
I wish I'd had #code when I was programming >.<
01:57
<@Mahal>
Byebye Reiver.
01:58
< ReivUni>
Mahal: This is partly why I have invented it... :)
01:58
< ReivUni>
It origionally was done when I dragged Chalcy onto the server to talk to Vorn.
01:58
<@Mahal>
:)
01:58
< ReivUni>
As I couldn't think of any other suitable channel, so I made it up...
01:58
< ReivUni>
It's since, uh, grown quite nicely. :)
01:58
<@Mahal>
*nod*
01:59
< ReivUni>
(Who knows, people might actually have /high tech/ discussions in here too one day. This would require adbucting Raif, Pi, and McM, though. >.<)
01:59
< ReivUni>
(...And Chalain, but.)
01:59
< ReivUni>
But now? I FLEE
02:00 ReivUni [~82d94c4d@Nightstar-14006.mail.city-net.pl] has quit [Quit: Aaaand orf to werk for the arvo.]
02:08 Chalc [~Chalceon@Nightstar-869.bitstream.orcon.net.nz] has joined #code
02:09 Chalc is now known as Chalcedon
02:09 Chalcy [~Chalceon@Nightstar-869.bitstream.orcon.net.nz] has quit [Killed (NickServ (GHOST command used by Chalcedon))]
02:19 Mahal [~Mahal@Nightstar-5192.worldnet.co.nz] has quit [Quit: It's hard to be mad at someone who misses you while you're asleep. ]
02:19 Mahal [~Mahal@Nightstar-5192.worldnet.co.nz] has joined #code
02:20 mode/#code [+o Mahal] by ChanServ
04:14
< Chalcedon>
Thanks for the tip Reiver, I've managed to remove a ginormous amount of code.
04:15
<@ToxicFrog>
What tip was this?
04:17
< Chalcedon>
I wanted to know how to do "repeat until you've got two non identical things", he suggested a while loop
04:18
< Chalcedon>
(of course, now that I've made the changes it's really obvious, particularly given I was using them for much the same thing before anyway... I just couldn't see the forest for the trees)
04:19
< Chalcedon>
o.O actually, I've about halved the length of that file.
04:19
< Chalcedon>
I still have all the ifelseifs but at least they're manageable now.
04:26
<@ToxicFrog>
Aah. What were you using before that?
04:26
< Chalcedon>
I wrote another (nearly identical) function. Which I knew was a dumb thing to do, but I wanted it to work and couldn't think of a better idea.
04:27
< Chalcedon>
(hence halving the file length)
04:44 Syloq [Coder@NetAdmin.Nightstar.Net] has joined #code
04:45 Syloq [Coder@NetAdmin.Nightstar.Net] has quit [Connection reset by peer]
06:13
< Lukhan>
There are some very dumb people in this world.
06:13
< Lukhan>
"<DanF_DrC> fabolous. how much faster would brute force have been. think think think think think think"
06:13
< Lukhan>
(there is no context. none at all.)
06:14
< Lukhan>
(well there is, but it DOESN'T MATTER.)
06:21 You're now known as TheWatcher
06:34 ReivClass is now known as Reiver
06:38
<@Reiver>
Lukhan: Chalcedon has dived into coding without first knowledge of principles, so to speak..
06:38
<@Reiver>
Thus she has an interesting blend of enough tricks to do most things, but occasionally overlooking the odd simple, obvious one elsewhere.
06:39 * Chalcedon thought he was talking about the person he was quoting
06:39 * Mahal did, too.
06:39
<@Mahal>
kkkkkklluk.
06:39
<@Mahal>
6u7uilk./yurtyjk ,./yoiluo;b/lk;n./
06:39
<@Reiver>
Oh, okay then.
06:39 * Reiver eyes Mahal.
06:39
<@Mahal>
... oops.
06:39
<@Reiver>
Wake up!
06:39
<@Reiver>
:p
06:39 * Chalcedon blinks at Mahal
06:39
<@Mahal>
(dusting kbd!!!)
06:40
<@Reiver>
Aha.
06:40 * Reiver huggles!
07:05
< Lukhan>
yeeeah.
07:05
< Lukhan>
person I was quoting.
07:05
< Lukhan>
"how much faster would brute force have been".
07:05
< Lukhan>
THINK ABOUT THAT FOR A MOMENT.
07:06
<@TheWatcher>
There are entire countries that work on that principle...
07:06
<@TheWatcher>
(not that it makes it /right/, but)
07:12
< Lukhan>
really? I can think of a few that /tried/ to ... >.>
08:16 You're now known as TheWatcher[afk]
08:23 EvilLurkingLord is now known as EvilDarkLord
08:36 * EvilDarkLord braces for impact, but still asks what kind of Linux distro any awake people might recommend for a newbie who mainly would use it as backup if Windows dies.
08:36
<@Mahal>
ubuntu.
08:37
<@Mahal>
:)
08:37
<@Mahal>
It appears to be the most idiot friendly - not that I'm saying you're an idiot, far from it - distro available atm.
08:38
<@Reiver>
Despite the mutterings in channel about it... Ubuntu is dummyproof, yes...
08:38
<@Mahal>
Reiver is trying to not be a dummy on it, though, wihtout going through tth learning curve first.
08:39
<@Mahal>
Hence his mutterings :)
08:39
<@Reiver>
Pretty much.
08:39
<@Reiver>
I need to get into teh Clever Bits(tm), and don't have time to faff about. >.>
08:39
<@Reiver>
As have an assignment due in three weeks and all. ^^;
08:39
<@Reiver>
Speaking of...
08:39
<@Reiver>
I should start writing that. ^^;
08:41
< EvilDarkLord>
Hm. Basic Ubuntu or one of the other *buntus?
08:42
<@Reiver>
Ubuntu is probably best.
08:42
<@Reiver>
Kubuntu is well and good, but no-one uses it.
08:42
<@Reiver>
>.>
08:42
<@Reiver>
(KDE in general seems to be losing the frontend war. *cough*)
08:44
< Lukhan>
ubuntu has a few things going for it. but if anything goes wrong you're boned. >.>
08:44
< Lukhan>
and god help you if you have hardware the ubuntu officials don't like. >.>
08:44 * Lukhan likes gentoo. but he /is/ a programmer, even if he was a relative newb to linux when he started using it ...
08:45
<@Reiver>
Yes, yes.
08:45 * Reiver puts Luk back into the evangelist box. :p
08:46
< Lukhan>
gentoo
08:46
< Lukhan>
ahem.
08:49
<@Reiver>
Quite.
08:49
<@Reiver>
Now.
08:49
<@Reiver>
Help me write java!
08:49
<@Reiver>
:p
08:50
< EvilDarkLord>
What seems to be the major malfunction in your code?
08:51
<@Mahal>
That's easy, EDL.
08:51
<@Mahal>
Reiver wrote it.
08:51
<@Reiver>
...
08:51 * Mahal ducks and runs
08:51
<@Reiver>
;_;
08:51 * Reiver will go sit in his corner and cry now.
08:53 * EvilDarkLord hands Reiver a comfort blanket.
08:53 * Reiver debugs it.
08:54
<@Mahal>
Are you implying EDL has fleas?
08:54
<@Reiver>
No.
08:54
<@Reiver>
But I am implying that I have code on the brain.
08:54 * Reiver decides to start with the chessboard function.
09:06 * Chalcedon and Forj have used ubuntu and would recommend it too
09:06
< Lukhan>
your primary bug is that you used java imo
09:06
< Chalcedon>
he doesn't have too many options given it's an assignment....
09:07
<@Reiver>
Lukhan: This course is taught in java.
09:08
<@Reiver>
I think they're using it as a stepping stone language, as for the pure comp-sci, it's the first real programming they've had to do in languages other than C, which they've been doing for the past two years.
09:08
<@Reiver>
And to be fair, java is not a bad 'gentle transition', given it's got half the syntax from C anyway...
09:10 EvilDarkLord is now known as EvilNROMLord
09:19 You're now known as TheWatcher[wr0k]
09:21
< Lukhan>
bah. C++ is the only language you'll ever need >.>
09:21
<@Reiver>
Except when crafting assignments in java. :p
09:27
< Lukhan>
I'm bitching about their choice of language.
09:28
<@Reiver>
It's a good start if you're OO.
09:28
<@Reiver>
As OO in C++ is mostly bolted on with chewing gum.
09:29
<@Reiver>
And they gotta learn a new language /some day/, it might as well be one which has familiar looking code. ¬¬
09:53 EvilNROMLord is now known as EvilDarkLord
10:17
< Lukhan>
except that java's oo model is both broken and mandatory. :P
10:19
<@Reiver>
I think they like the 'mandatory' bit, Luk.
10:20
<@Reiver>
:P
10:21 Reiver is now known as ReivF0d
10:23
< Lukhan>
yes, but it's mandatory in ways that are decidedly unOO. if you really want to force someone to use OO, do smalltalk. Or have them do C++ and just say "You have to use classes to do this". >.>
10:36 ReivF0d is now known as Reiver
10:39
<@Reiver>
Nah.
10:40
<@Reiver>
They might as well learn another language, and at least Java sorta /looks/ like C++...
10:40
<@Reiver>
And FWIW, Java /is/ one of the most common languages out there at the moment. It might be crap, but you'll probably have to learn it one day~
11:01
< Lukhan>
I "learned" it.
11:02
< Lukhan>
used it enough to pass a grad-level course with an A. (perfected the final, even!)
11:02
< Lukhan>
still don't really know it, don't need to, don't care.
11:02
< Lukhan>
:P
11:03 * Reiver suggests Luk put the ruler away. :p
11:03
<@Reiver>
What do you do for a living, incidentally?
11:30
<@Reiver>
...Does each class have to be in its own .java file in Java?
11:31
<@Reiver>
Or is this my code software being a prick?
11:35
< EvilDarkLord>
Unless you have been shown some good examples of how to make classes inside classes, just go with the .java for each one. I think I read in passing that multiple classes would be possible but I'm not quite sure on it.
11:36
<@Reiver>
A new .java for each object. That's horrid.
11:36
< EvilDarkLord>
How many objects are you dealing with here?
11:37
<@TheWatcher[wr0k]>
Reiver: you /can/ have multiple classes in a .java file, but generally it is best not to unless you know what you're doing
11:38
<@Reiver>
Well, I need an object for Peices, and object for the chessboard, the main method, and, uh
11:38
<@Reiver>
Possibly (Probably) one for the players.
11:38
<@Reiver>
Which would handle the AI/Human split better, I think.
11:38
< EvilDarkLord>
Class player with subclasses HumanPlayer and AIPlayer?
11:38
<@Reiver>
Yeah.
11:39
<@Reiver>
I'm assuming subclasses get to stick in the same .java, I pray?
11:40
< EvilDarkLord>
I've always used different .javas, but I'm assuming TW will have a better answer.
11:41
< EvilDarkLord>
Would be great if you could stick them all in the same one. Either that or you fiddle around with folders.
11:41 * Reiver doesn't remember being told to put all his objects in individual .javas...
11:42
<@Reiver>
So how's that affect the final compilation to bytecode?
11:42 * EvilDarkLord is clueless here, for the record.
11:44 * Chalcedon woes for Reivy and his .javas
11:44 * Chalcedon supplies Reivy with a cookie for his woe.
11:44 * Chalcedon then goes to bed.
11:44
< Chalcedon>
night all.
11:46
< EvilDarkLord>
'night
11:47
<@TheWatcher[wr0k]>
Reiver: you will usually need to put subclasses in seperate files (this is actually an artifact of the way the java classloader works - even when you put more than one class in the same .java, the compiled bytecodes end up in multiple .class files with mangled names)
11:47 * Reiver nrom cookie, wishes Chalcedon a goodnights sleep.
12:11 Mahal is now known as MahalZzz
12:17 Reiver is now known as ReivZzz
13:06 EvilDarkLord [althalas@Nightstar-17046.a80-186-184-83.elisa-laajakaista.fi] has quit [Ping Timeout]
13:07
<@ToxicFrog>
'night, Reiv, Mahal, Chalcy.
13:18 EvilDarkLord [althalas@Nightstar-17046.a80-186-184-83.elisa-laajakaista.fi] has joined #code
14:04 You're now known as TheWatcher[OMGD00M]
14:44 ToxicFrog|AFK is now known as ToxicFrog|W`rkn
14:49 Chalcy [~Chalceon@Nightstar-869.bitstream.orcon.net.nz] has joined #code
14:49 mode/#code [+o Chalcy] by ChanServ
14:50 Chalcedon [~Chalceon@Nightstar-869.bitstream.orcon.net.nz] has quit [Ping Timeout]
14:53 You're now known as TheWatcher[wr0k]
15:05 Chalain [~chalain@Admin.Nightstar.Net] has joined #Code
15:05
< Chalain>
It's all crap! Change this! Refactor that! Run the garbage collector already!
15:06
< Chalain>
That is all. Carry on.
15:06
< ToxicFrog|W`rkn>
wha?
15:08
< Chalain>
Oh, I'm just running the identity function on myself.
15:08 * Chalain is just being Chalain.
15:09
< Chalain>
OH! TF! There's a Plua2! It's Lua 5!
15:09 * Chalain does the setmetatable boogie.
15:09
< ToxicFrog|W`rkn>
"plua2"?
15:10
< Chalain>
Did I not chat with you about Lua, because I was learning Plua (PalmOS Lua)?
15:10
< Chalain>
I thought it was you. Perhaps my memory core is damaged.
15:10
< ToxicFrog|W`rkn>
Aah! Yes, you did.
15:10
< ToxicFrog|W`rkn>
Now I remember.
15:11
< Chalain>
Ah, okay. So, yeah. Plua was Lua 4.
15:11 * ToxicFrog|W`rkn switched to Linux-based PDAs recently, so~
15:11
< ToxicFrog|W`rkn>
Most excellent.
15:11
< Chalain>
I just discovered Plua2, which is currently in beta. But it seems stable and it's Lua 5, which means there's like REAL documentation out there for it.
15:11
< Chalain>
Oh? Which PDA did you get?
15:12
< ToxicFrog|W`rkn>
Zaurus SL-5500, running OpenZaurus Opie.
15:12 * Chalain has a Zaurus SL-5500 but he doesn't use it much.
15:12
< Chalain>
Cool, that's the one I've got.
15:12
< ToxicFrog|W`rkn>
Nice.
15:12
< Chalain>
I have ROM from last December--the one that resets if you hold down the right arrow.
15:12 * ToxicFrog|W`rkn uses it constantly for bookreading, and the ability to SSH into it is pretty awesome when setting stuff up~
15:13
< Chalain>
Unfortunately, the profound lack of documentation and the general crashiness of it caused me to shelve it. Hmm, I should ebay it.
15:13
< ToxicFrog|W`rkn>
Next step is to see if I can get an NES emulator.
15:13
< ToxicFrog|W`rkn>
*running on it, that is.
15:13
< Chalain>
Heh
15:13 * ToxicFrog|W`rkn got a Genesis emulator working, but it was unplayably slow.
15:14
< ToxicFrog|W`rkn>
What dist do you have on it? OZ? Sharp mainline?
15:14
< Chalain>
Every other PDA I get is non-Palm because I want a better computer. Every other-other PDA I get is Palm because I always discover that the reason I got the darn thing in the first place was to have an organizer, and I have yet to find a PDA that
15:14
< Chalain>
doesn't suck ass as an organizer that wasn't Palm.
15:14
< ToxicFrog|W`rkn>
Heh.
15:14
< Chalain>
I don't know which OS. It was Opie, and it wasn't the Sharp OS
15:14
< ToxicFrog|W`rkn>
Porbably OZ Opie, then.
15:14
< Chalain>
(But I think Opie was the ROM, which != OS)
15:14
< Chalain>
Probably
15:15
< ToxicFrog|W`rkn>
...it doesn't /have/ a ROM, is the thing.
15:15
< ToxicFrog|W`rkn>
Or rather, it does, but it just holds the tiny little machine BIOS that understands stuff like how to install a new system image.
15:16
< Chalain>
But yeah, over the years, I have had a PalmPilot 1000, an HP Geo, a PalmPilot 3000, a Philips Nino, a Handspring Visor, the Zaurus SL-5500, and now a Treo 650, which slipped in under the radar because it's a cell phone. :-)
15:17
< ToxicFrog|W`rkn>
Anyways, I don't use it as a computer, I use it as a notepad, ebook reader, portable gaming system, etc.
15:17
< ToxicFrog|W`rkn>
Err, don't use it as an organizer.
15:17
< Chalain>
Well, what's Opie, then? Isn't it a core or a bios or sommat?
15:17
< Chalain>
Yeah, my problem is I really need both.
15:17
< ToxicFrog|W`rkn>
Opie is the GUI.
15:17
< Chalain>
Ah, ok
15:17
< ToxicFrog|W`rkn>
OZ Opie is OpenZaurus using Opie for the UI; OZ GPE is OpenZaurus using X11 + GPE (which is GTK-based) for the GUI, etc.
15:18
< ToxicFrog|W`rkn>
Opie is based on Qtopia (libQt) which is what the mainline install uses, IIRC.
15:18
< Chalain>
the biggest reason I've used Palms, however, is the graffiti--the HW recognition on the other devices was uniformly ass. The Treo doesn't accept graffiti, it has a keyboard. So there's a very good chance I may break down and buy a WinCE device in the
15:18
< Chalain>
next year or two.
15:18 * ToxicFrog|W`rkn nods.
15:18
< Chalain>
...because I'm freakin in LOVE with the keyboard.
15:19 * Chalain used to graffiti at 35WPM, though. Scary.
15:19
< ToxicFrog|W`rkn>
OZ has trainable handwriting recognition, but I can type on the keyboard faster than I can write anyways, so what's the point?
15:19
< Chalain>
correction. 35CPM.
15:19 * ToxicFrog|W`rkn hated, HATED Graffiti on the Palm he had before this. A keyboard is so much more civilised~
15:19
< Chalain>
*slight* difference, as typing WPM is 5x CPM. No, I don't type 5CPS.
15:20
< ToxicFrog|W`rkn>
Wouldn't it be CPM/5?
15:20
< Chalain>
Er, yes.
15:20
< Chalain>
5 chars == wrd
15:20
< Chalain>
1 word, also, when my fscking keybord isn't dropping letters.
15:22 * Chalain has a lame USB keyboard that disconnects about 5 times per day, just for ~500ms at a time... long enough to drop 3-4 characters as I'm typing.
15:22
< Chalain>
But anyway, yeah... Plua2 is rocking my world. I've started writing scripts that write other scripts. It's a sickness, I think... :-)
15:22
< ToxicFrog|W`rkn>
Ick.
15:22 * ToxicFrog|W`rkn is all about the AT IBM model M.
15:23
< Chalain>
model M? Wossat?
15:23
< ToxicFrog|W`rkn>
101-key keyboard, using buckling-spring rather than conductor-pad sensors.
15:23
< ToxicFrog|W`rkn>
Makes a distinctive clicking sound, has nice tactile feedback and is effectively indestructable.
15:24
< ToxicFrog|W`rkn>
I actually prefer the KeyTronic E3600QL, but as far as I can tell only one of those still exists in the world, and I have it~
15:24
< Chalain>
Oh, is that like the old IBM PC keyboards? The ones that go "click-PING, click-PING?"
15:24
< ToxicFrog|W`rkn>
If it goes 'ping' I think there's something wrong with it, it should just go 'click'~
15:25
< ToxicFrog|W`rkn>
Oh, wait, those!
15:25
< ToxicFrog|W`rkn>
Not the same, but similar.
15:26
< ToxicFrog|W`rkn>
They're quite popular in schools, probably because they're so difficult to damage.
15:27
< Chalain>
Heh, when I was a kid, my dad and I never really had much in common... he was into cars and I was into computers. We would watch TV and he'd see a glimpse of a truck and he'd say, "Oh, hey, that's a '72 International" or "That's a '78 Chevy Impala,
15:27
< Chalain>
you can tell by the grille" and stuff.
15:27
< ToxicFrog|W`rkn>
Heh. My /granddad/ was into cars, but my dad was into computers.
15:28
< Chalain>
One day we were watching TV and some guy was typing on a word processor and it was going "click-PING, click-PING" and I shouted, "Hey! That's an IBM PC-jr! You can tell by the keyboard sound!"
15:28
< ToxicFrog|W`rkn>
Snrk.
15:28
< Chalain>
After that, my dad sort of begrudgingly agreed that maybe I wasn't wasting my time buried in all those books. :-)
15:32
< Chalain>
Hey, Lua coding question. Is there a good way to make enums? I'd like to be able to say something like curve_type = { SPLINE, BSPLINE, QSPLINE }, but have it actually create curve_type.SPLINE = 1, etc, and have the table be readonly.
15:32
< Chalain>
I've been doing it with curve_type = { SPLINE=1, BSPLINE=2,... } etc, but I haven't got the read-only.
15:33
< Chalain>
Also, I'd *really* like to figure out some magic way to make the enums have the equivalent of a toString() method.
15:34
< Chalain>
Hmm, I suppose I could write an Enum class that takes a table of strings, like Enum:new { "SPLINE", "BSPLINE", ... } and then new() could use some kind of reflection....
15:34
< ToxicFrog|W`rkn>
Hmm.
15:34
< ToxicFrog|W`rkn>
The short answer is, no, you can't do this at the language level, you have to roll your own.
15:35
< Chalain>
Well, yeah. That's what I'm trying to figure out how to do. :-)
15:35
< ToxicFrog|W`rkn>
Making it readonly you can do with a shadow table and an overload on __index and __newindex.
15:35
< Chalain>
Oh, wait, I've got a script somewhere that has a read-only table in it. You override __newindex I think--yeah.
15:36
< ToxicFrog|W`rkn>
Yeah, but you have to do that on the shadow table; doing it on the table itself won't work.
15:36
< ToxicFrog|W`rkn>
Because if you have:
15:36
< ToxicFrog|W`rkn>
T = { a=1 }
15:36
< ToxicFrog|W`rkn>
T.b = 2 -- sets off __newindex
15:36
< ToxicFrog|W`rkn>
T.a = 2 -- doesn't set off __newindex, because T.a already exists
15:37
< ToxicFrog|W`rkn>
So instead you do:
15:38
< ToxicFrog|W`rkn>
function shadow(t); local R = {}; local mt = { __index = t; __newindex = function() return; end; }; setmetatable(R, mt); return R; end
15:38
< ToxicFrog|W`rkn>
T = shadow { a=1 }
15:39
< ToxicFrog|W`rkn>
And the flipping it from number->string to string->number is easy, you just use ipairs().
15:40
< Chalain>
ipairs? Ooh. Tell me mor.
15:40 You're now known as TheWatcher[afk]
15:41
< Chalain>
I just wrote a quick test, though, and it seems to work: function Enum:new(t) local e={} setmetatable(e, Enum) local k,v for k,v in t do e[v]=k end return e end
15:41
< Chalain>
The test was: e = Enum:new { "RED", "BLUE", "GREEN" } print(e.RED)
15:42
< Chalain>
And it outputs 1.
15:42
< ToxicFrog|W`rkn>
...'for k,v in t' works now?
15:42
< Chalain>
Seems to... worked in Plua and Plua2
15:42
< ToxicFrog|W`rkn>
Aah.
15:42
< ToxicFrog|W`rkn>
It doesn't work in Lua proper.
15:42
< Chalain>
Weird.
15:42
< ToxicFrog|W`rkn>
Where the syntax is: for (list of variables) in (iterator function) do
15:42
< ToxicFrog|W`rkn>
So you'd write:
15:43
< ToxicFrog|W`rkn>
for key,value in ipairs(table) do
15:43
< ToxicFrog|W`rkn>
(which iterates over all numerical indexes starting from 1)
15:43
< ToxicFrog|W`rkn>
or for key,value in pairs(table) do
15:43
< ToxicFrog|W`rkn>
(which iterates over all table entries in undefined order)
15:44
< Chalain>
Cool. Yeah, I haven't gotten into iterator functions yet. Haven't needed them (because for k,v works) :-)
15:45
< ToxicFrog|W`rkn>
Yeah, that appears to be a PLua-specific extension; it's not in the language spec.
15:46
< ToxicFrog|W`rkn>
Anyways, here's my sample enum function:
15:46
< ToxicFrog|W`rkn>
function enum(T)
15:46
< ToxicFrog|W`rkn>
local R = {}
15:46
< ToxicFrog|W`rkn>
local mt = {}
15:46
< ToxicFrog|W`rkn>
local newT = {}
15:46
< ToxicFrog|W`rkn>
mt.__index = newT;
15:46
< ToxicFrog|W`rkn>
function mt:__newindex(key, value)
15:46
< ToxicFrog|W`rkn>
error("Attempted to assign "
15:46
< ToxicFrog|W`rkn>
..tostring(value)
15:46
< ToxicFrog|W`rkn>
.." to "
15:46
< ToxicFrog|W`rkn>
..tostring(self)
15:46
< ToxicFrog|W`rkn>
.."["..tostring(key)
15:46
< ToxicFrog|W`rkn>
.."], which is a read-only enum.")
15:46
< ToxicFrog|W`rkn>
end
15:46
< ToxicFrog|W`rkn>
for value,name in ipairs(T) do
15:46
< ToxicFrog|W`rkn>
newT[name] = value
15:46
< ToxicFrog|W`rkn>
end
15:46
< ToxicFrog|W`rkn>
setmetatable(R, mt)
15:46
< ToxicFrog|W`rkn>
return R
15:46
< ToxicFrog|W`rkn>
end
15:46
< ToxicFrog|W`rkn>
And you use it as
15:46
< ToxicFrog|W`rkn>
colors = enum { 'red', 'green', 'blue' }
15:47
< ToxicFrog|W`rkn>
It would also be possible to write it so that it becomes:
15:47
< ToxicFrog|W`rkn>
enum 'colors' { 'red', 'green', 'blue' }
15:49
< Chalain>
whoa, 'splain to me the syntax of that last line.
15:49
< Chalain>
...or does it require more magic in the metatable?
15:50
< Chalain>
(Looks like at the very least you're going to need a function enum())
15:53
< ToxicFrog|W`rkn>
Yes. enum() takes a string, and returns a function which takes a table.
15:54
< ToxicFrog|W`rkn>
Hang on, I'll show you the source.
15:55
< ToxicFrog|W`rkn>
function enum(name)
15:55
< ToxicFrog|W`rkn>
return function(T)
15:55
< ToxicFrog|W`rkn>
local R = {}
15:55
< ToxicFrog|W`rkn>
local mt = {}
15:55
< ToxicFrog|W`rkn>
local newT = {}
15:55
< ToxicFrog|W`rkn>
mt.__index = newT;
15:55
< ToxicFrog|W`rkn>
function mt:__newindex(key, value)
15:55
< ToxicFrog|W`rkn>
error("Attempted to assign "
15:55
< ToxicFrog|W`rkn>
..tostring(value)
15:55
< ToxicFrog|W`rkn>
.." to "
15:55
< ToxicFrog|W`rkn>
..tostring(self)
15:55
< ToxicFrog|W`rkn>
.."["..tostring(key)
15:55
< ToxicFrog|W`rkn>
.."], which is a read-only enum.")
15:55
< ToxicFrog|W`rkn>
end
15:55
< ToxicFrog|W`rkn>
for value,name in ipairs(T) do
15:56
< ToxicFrog|W`rkn>
newT[name] = value
15:56
< ToxicFrog|W`rkn>
end
15:56
< ToxicFrog|W`rkn>
setmetatable(R, mt)
15:56
< ToxicFrog|W`rkn>
getfenv(2)[name] = R
15:56
< ToxicFrog|W`rkn>
return R
15:56
< ToxicFrog|W`rkn>
end
15:56
< ToxicFrog|W`rkn>
end
15:56
< ToxicFrog|W`rkn>
Pretty much the same, except that it's now two nested functions and the assignment to getfenv(2)[name] near the end.
15:58
< ToxicFrog|W`rkn>
The actual evaluation translates it into enum('colors')({[1]='red'; [2]='green'; [3]='blue';})
15:58
< ToxicFrog|W`rkn>
The first call returns an anonymous function, which is then called again with the enum table as its sole argument.
16:00
< Chalain>
Wild.
16:00
< ToxicFrog|W`rkn>
(this is also how version 2 of ooLua worked, so that you could write [[class "foo" { --[[ class members here ]] })
16:00
< Chalain>
[[class ?
16:01
< ToxicFrog|W`rkn>
Err. using [[ ]] to bracket code, except I forgot the closing ]].
16:01
< Chalain>
Ah, heh. Ok.
16:02
< ToxicFrog|W`rkn>
Anyways. The enum function above could be made more sophisticated; better error checking, modifying the original table rather than creating a new one (possibly allowing value->name mappings as well as name->value), and detecting what it's been passed so that [[ enum 'colors' {} ]] and [[ colors = enum {} ]] are both legal. But that's just details.
16:02 * Chalain nods.
16:02
< Chalain>
It's also details that are largely beyond me. :-)
16:03
< Chalain>
But that's okay. I'm content with the simple Enum:new {...} version.
16:04
< ToxicFrog|W`rkn>
Well, the detection is easy:
16:05
< ToxicFrog|W`rkn>
function enum(name)
16:05
< ToxicFrog|W`rkn>
local function build_enum(T)
16:05
< ToxicFrog|W`rkn>
-- code omitted as it's the same as above
16:05
< ToxicFrog|W`rkn>
end
16:05
< ToxicFrog|W`rkn>
if type(name) == 'table' then
16:05
< ToxicFrog|W`rkn>
return build_enum(name)
16:05
< ToxicFrog|W`rkn>
else
16:05
< ToxicFrog|W`rkn>
return build_enum
16:05
< ToxicFrog|W`rkn>
end
16:05
< ToxicFrog|W`rkn>
end
16:06
< ToxicFrog|W`rkn>
If you call it as enum 'foo', it returns the enum construction function the same as above.
16:06
< ToxicFrog|W`rkn>
If you call it as enum {
16:07
< ToxicFrog|W`rkn>
If you call it as enum {}, rather than returning the function itself, it tail calls it passing in the table it was given.
16:09
< ToxicFrog|W`rkn>
And value->name lookups is just a matting of changing all references to newT to T.
16:17
< Chalain>
Hmm.
16:18
< Chalain>
So I'm considering writing Enum:toString(val), and I need to figure out where to hide the string->value lookup.
16:18
< Chalain>
Can I stuff it into the metatable, I wonder?
16:20
< Chalain>
So I build the object as table e from table t. Then perhaps I do: local names = table:copy(t) getmetatable(e)[e] = names
16:20
< ToxicFrog|W`rkn>
...don't you mean value->string?
16:20
< Chalain>
So the metatable would have its usual __ methods, plus a bunch of table->table values.
16:21
< ToxicFrog|W`rkn>
And yeah, you could do it in the metatable, personally I just whack it into the same table that holds the names.
16:21
< ToxicFrog|W`rkn>
for k,v in t do
16:21
< ToxicFrog|W`rkn>
t[v] = k
16:21
< ToxicFrog|W`rkn>
end
16:21
< ToxicFrog|W`rkn>
And then you can either do t.one and get 1 back, or t[1] and get "one" back.
16:23
< ToxicFrog|W`rkn>
Also, does PLua give you table.copy, or have you rolled your own?
16:23
< Chalain>
rolled my own. :-)
16:23
< ToxicFrog|W`rkn>
Deep-copy with reference resolution?
16:25
< Chalain>
Not sure. It does deep table copies, but I'm not sure what you mean by reference resolution.
16:25
< ToxicFrog|W`rkn>
Erm. Say you have something like this:
16:25
< ToxicFrog|W`rkn>
A = {}
16:25
< ToxicFrog|W`rkn>
T = {
16:25
< ToxicFrog|W`rkn>
reference_one = A;
16:25
< ToxicFrog|W`rkn>
reference_two = A;
16:25
< ToxicFrog|W`rkn>
}
16:25
< ToxicFrog|W`rkn>
So T contains two references to the same table.
16:26
< ToxicFrog|W`rkn>
With a naiive copy, this comes out the other side as T containing references to two different but identical tables; with reference resolution it contains two references to the same table, which is a copy of A.
16:26
< ToxicFrog|W`rkn>
(with a shallow copy, of course, the copy contains two references to the original A)
16:27
< Chalain>
function table:copy(src)
16:27
< Chalain>
local dst = {}
16:27
< Chalain>
for k,v in t do
16:27
< Chalain>
if type(v)=='table' then
16:27
< Chalain>
dst[k] = table:copy(k)
16:27
< Chalain>
else
16:27
< Chalain>
dst[k] = v
16:27
< Chalain>
end
16:27
< Chalain>
end
16:27
< Chalain>
return dst
16:27
< Chalain>
end
16:27
< Chalain>
Pretty trivial
16:27
< Chalain>
Ah, yeah, that would make two tables
16:27
< ToxicFrog|W`rkn>
Aah. Yes. Deepcopy, no reference resolution.
16:28
< ToxicFrog|W`rkn>
(just out of curiosity, why are you declaring it as table:copy and not table.copy, since self never gets used?)
16:28
< Chalain>
It'll also stackfault if your table has any cycles in it
16:28
< ToxicFrog|W`rkn>
Yeah, that's another thing reference resolution solves.
16:29
< ToxicFrog|W`rkn>
...in theory. Now that I think about it I'm not sure if my implementation handles that properly.
16:29 * ToxicFrog|W`rkn runs off to check it
16:31
< Chalain>
I think it is actually table.copy. I was writing it here from memory
16:31
< ToxicFrog|W`rkn>
Hmm.
16:31
< ToxicFrog|W`rkn>
You know, I don't think it does.
16:32
< ToxicFrog|W`rkn>
refs[v] = tcopy(v, refs)
16:32
< ToxicFrog|W`rkn>
This works fine until v refers to itself.
16:32
< ToxicFrog|W`rkn>
At which point it blows the stack.
16:32
< Chalain>
heh
16:32
< ToxicFrog|W`rkn>
(it /will/, however, work if v refers to w, which refers to v)
16:32
< ToxicFrog|W`rkn>
(wait, I lie, it wont)
16:32
< ToxicFrog|W`rkn>
(dammit)
16:32
< ToxicFrog|W`rkn>
(now I have to rewrite tcopy())
16:36
< Chalain>
What about this:
16:36
< Chalain>
function table:copy(src,seen)
16:36
< Chalain>
local dst = {}
16:36
< Chalain>
local seen = seen or {}
16:36
< Chalain>
for k,v in t do
16:36
< Chalain>
if type(v)=='table' and not seen[v] then
16:36
< Chalain>
dst[k] = table:copy(k)
16:36
< Chalain>
seen[v] = true
16:36
< Chalain>
else
16:36
< Chalain>
dst[k] = v
16:36
< Chalain>
end
16:36
< Chalain>
end
16:36
< Chalain>
return dst
16:36
< Chalain>
end
16:37
< Chalain>
that should be table.copy, natch
16:37
< ToxicFrog|W`rkn>
No, because then the above example loses one of its members.
16:37
< ToxicFrog|W`rkn>
What you actually want is something like seen[v] = table.copy(k)
16:37
< ToxicFrog|W`rkn>
dst[k] = seen[v]
16:38
< ToxicFrog|W`rkn>
But, as stated earlier, this still breaks on cyclical tables.
16:38 * Chalain shakes his head
16:38
< Chalain>
Oh, wait. Hmm.
16:38
< ToxicFrog|W`rkn>
I am working on fixing this~
16:38
< ToxicFrog|W`rkn>
...oh, wait,.
16:38
< ToxicFrog|W`rkn>
No, you're right, it does work.
16:38
< ToxicFrog|W`rkn>
But still not on cyclical tables :P
16:39
< ToxicFrog|W`rkn>
Wait, no, it doesn't.
16:39
< ToxicFrog|W`rkn>
Argh, I'm not thinking right today.
16:39
< ToxicFrog|W`rkn>
Yeah. You don't lose a member, but the second one ends up as a reference to the original rather than the copy.
16:39
< ToxicFrog|W`rkn>
It needs to be a table mapping originals to copies, not just recording whether a copy already exists.
16:48
< Chalain>
There we go, yeah
16:49
< Chalain>
function table.copy(src,seen)
16:49
< Chalain>
local dst = {}
16:49
< Chalain>
local seen = seen or {}
16:49
< Chalain>
for k,v in t do
16:49
< Chalain>
if type(v)=='table'
16:49
< Chalain>
if not seen[v] then
16:49
< Chalain>
seen[v] = table.copy(k)
16:49
< Chalain>
end
16:49
< Chalain>
dst[k] = seen[v]
16:49
< Chalain>
else
16:49
< Chalain>
dst[k] = v
16:49
< Chalain>
end
16:49
< Chalain>
end
16:49
< Chalain>
return dst
16:49
< Chalain>
end
16:49
< ToxicFrog|W`rkn>
Yeah.
16:50
< ToxicFrog|W`rkn>
I believe I see how to get it to handle cycles, too, it's just ugly.
16:52
< Chalain>
mrm, yeah, I just tested the recursive case, and it pukes. Bleh.
16:52 * Chalain wonders how come they're not being seen.
16:52
< ToxicFrog|W`rkn>
Simple.
16:53
< ToxicFrog|W`rkn>
Seen[v] = table.copy(k)
16:53
< ToxicFrog|W`rkn>
They get seen /after/ the copy function is called.
16:53
< ToxicFrog|W`rkn>
But the copy function never returns!
16:53
< Chalain>
Yeah, but it's seen[v], not seen[tabe.copy(k)]
16:53
< ToxicFrog|W`rkn>
And boom goes the stack.
16:53
< Chalain>
ahh.
16:53
< Chalain>
Hrm.
16:53
< Chalain>
Crap.
16:53
< ToxicFrog|W`rkn>
The bytecode is presumably something like this:
16:53
< Chalain>
oh, DAMMIT
16:53
< ToxicFrog|W`rkn>
push k
16:54
< ToxicFrog|W`rkn>
call table.copy
16:54
< Chalain>
This is so easy because we're so stupid
16:54
< ToxicFrog|W`rkn>
push seen
16:54
< ToxicFrog|W`rkn>
exch
16:54
< ToxicFrog|W`rkn>
set
16:54
< Chalain>
seev[v] = table.copy(k, seen)
16:54
< ToxicFrog|W`rkn>
Nope, still doesn't work. That's what my code does.
16:54
< Chalain>
Drat.
16:54
< ToxicFrog|W`rkn>
Because, again, seen[v] doesn't exist until /after/ table.copy returns.
16:54
< ToxicFrog|W`rkn>
Anwyways. I /have/ a solution, I just haven't finished writing it.
16:55
< Chalain>
Okay, I gotta get to work... my team is here and I need to stop goofing off. :-)
16:55
< ToxicFrog|W`rkn>
Alright. Have fun.
16:56
< Chalain>
Ah, here's asolution.
16:57
< Chalain>
if not seen[v] then seen[v] = true seen[v] = table.copy(k) end
16:57
< Chalain>
seen[v]=true prevents the recursion. It immediately gets overwritten with a table, but it's good enough to prevent the recursion, at least according to my Treo. :-)
16:57
< Chalain>
And now, work for real.
16:58
< ToxicFrog|W`rkn>
The copy gets corrupted, though.
16:58
< ToxicFrog|W`rkn>
It doesn't blow the stack, but it doesn't copy accurately either.
16:59
< Chalain>
Hmm. Perhaps a 2-pass algorithm, then. One to shallow copy, then another to deep-copy unseens.
16:59
< Chalain>
GRAH I gotta get to work.
17:00 * Chalain closes irssi.
17:00
< Chalain>
Cheers
17:00
< Chalain>
(Oh, damn you shiny thing! DAMN YOU TO HELL!)
17:00
< ToxicFrog|W`rkn>
Nope, it's a one-pass solution.
17:01
< ToxicFrog|W`rkn>
Works by inserting an empty table into seen[] and populating it during the recursion.
17:05
< ToxicFrog|W`rkn>
function tcopy(T)
17:05
< ToxicFrog|W`rkn>
local R = {}
17:05
< ToxicFrog|W`rkn>
local seen = { [T] = R }
17:05
< ToxicFrog|W`rkn>
local get_ref,docopy
17:05
< ToxicFrog|W`rkn>
function get_ref(ref)
17:05
< ToxicFrog|W`rkn>
if type(ref) ~= 'table' then
17:05
< ToxicFrog|W`rkn>
return ref
17:05
< ToxicFrog|W`rkn>
end
17:06
< ToxicFrog|W`rkn>
if not seen[ref] then
17:06
< ToxicFrog|W`rkn>
seen[ref] = {}
17:06
< ToxicFrog|W`rkn>
docopy(ref, seen[ref])
17:06
< ToxicFrog|W`rkn>
end
17:06
< ToxicFrog|W`rkn>
return seen[ref]
17:06
< ToxicFrog|W`rkn>
end
17:06
< ToxicFrog|W`rkn>
function docopy(from, to)
17:06
< ToxicFrog|W`rkn>
for key,value in pairs(from) do
17:06
< ToxicFrog|W`rkn>
to[get_ref(key)] = get_ref(value)
17:06
< ToxicFrog|W`rkn>
end
17:06
< ToxicFrog|W`rkn>
end
17:06
< ToxicFrog|W`rkn>
docopy(T, R)
17:06
< ToxicFrog|W`rkn>
return R
17:06
< ToxicFrog|W`rkn>
end
17:06
< ToxicFrog|W`rkn>
> v = {}
17:06
< ToxicFrog|W`rkn>
> v.v = v
17:06
< ToxicFrog|W`rkn>
> x = tcopy(v)
17:06
< ToxicFrog|W`rkn>
> print(v, v.v, x, x.v)
17:06
< ToxicFrog|W`rkn>
table: 0x49cb78 table: 0x49cb78 table: 0x4988b8 table: 0x4988b8
17:12 You're now known as TheWatcher
17:17
< ToxicFrog|W`rkn>
Wibs, TW.
17:17
<@TheWatcher>
Ta
17:25 You're now known as TheWatcher[afk]
17:47
< Chalain>
TF: Yeah, in our meeting I fixed it by realizing that the first thing table.copy(src) needs to do is "see" src, and then you don't assign to it later.
17:48
< Chalain>
Um, wait. I didn't remove the later assign.
17:48
< Chalain>
I just added seen[src] = dst.
17:49
< Chalain>
function table.copy(src,seen)
17:49
< Chalain>
local dst = {}
17:49
< Chalain>
local seen = seen or {}
17:49
< Chalain>
seen[src] = dst
17:49
< Chalain>
for k,v in t do
17:49
< Chalain>
if type(v)=='table'
17:49
< Chalain>
if not seen[v] then
17:49
< Chalain>
seen[v] = table.copy(k)
17:49
< Chalain>
end
17:49
< Chalain>
dst[k] = seen[v]
17:49
< Chalain>
else
17:49
< Chalain>
dst[k] = v
17:49
< Chalain>
end
17:49
< Chalain>
end
17:49
< Chalain>
return dst
17:49
< Chalain>
end
17:49
< Chalain>
That does reference-safe, recursion-safe, deep copy.
17:51
< ToxicFrog|W`rkn>
It's not key-safe, and I don't think it's recursion-safe either.
17:53
< ToxicFrog|W`rkn>
Say you pass it something like this:
17:53
< ToxicFrog|W`rkn>
v = {}
17:53
< ToxicFrog|W`rkn>
v.v = v
17:53
< ToxicFrog|W`rkn>
T = { v }
17:53
< ToxicFrog|W`rkn>
table.copy(T)
17:54
< ToxicFrog|W`rkn>
Oh, wait.
17:54
< ToxicFrog|W`rkn>
Right. If it's table.copy(k,seen) it works.
17:55
< ToxicFrog|W`rkn>
...or does it.
17:55 * ToxicFrog|W`rkn works it out by hand
17:55
< ToxicFrog|W`rkn>
seen[v] needs to = table.copy(v,seen)
17:55
< Chalain>
My test works for recursion safety.
17:56
< Chalain>
Hmm, you are correct about key safety. Drat.
17:56
< Chalain>
You have a huge speed advantage over me, as I don't actually have Lua on my PC. I'm keying all this into my PDA and then copying it by hand here. :-)
17:57
< ToxicFrog|W`rkn>
Aah.
17:58
< ToxicFrog|W`rkn>
Anyways, the above runs into some problems; you end up with keys where you should have values, since it's copying the key, not the value, for assignment as the value when resolving references.
17:58
< ToxicFrog|W`rkn>
Fixing that, you still run into problems with recursive tables as keys, but that's not conceptually any different.
18:03
< Chalain>
Hmm
18:03
< Chalain>
*should* it be key-safe?
18:03 * Chalain doesn't think it should.
18:04
< Chalain>
f = {'foo'} d={x=42} d[f] = 69 e=table.copy(d) e[f] == nil --[[oops.]]
18:04
< Chalain>
Errrrk, but what if a key is also a value. Fark.
18:05
< Chalain>
Blah, screw it. keys are not deep-copied, values are, and if you have d[t]=t you're going to get d[t] = copy of t.
18:14
< ToxicFrog|W`rkn>
Or you could just use the algorithm I pasted above~
18:15
< Chalain>
Well, but what I'm suggesting is that e[f]==nil is an error in the copy. The duplicate no longer responds to the same keys as the original.
18:16
< Chalain>
(I am thinking, however, that I want table.shallow_copy() and table.deeper_copy(), the first being obvious and the second being the deep-key-copy version.
18:16
< Chalain>
)
18:17
< ToxicFrog|W`rkn>
Yes. It is an error.
18:17
< Chalain>
Or perhaps I'll name them table.clone, table.dup and table.copy, and then never document which does what.
18:17
< ToxicFrog|W`rkn>
One that is not present in the algo above!
18:17 * ToxicFrog|W`rkn doesn't see the problem here
18:17
< Chalain>
Oh, wait, then. What does your algorithm do differently, then?
18:19
< ToxicFrog|W`rkn>
For keysafety, it deep-copies both keys and values rather than just values.
18:19
< ToxicFrog|W`rkn>
For recursion-safety, it copies tables by creating an empty table in seen[] and then doing copy(from,to) rather than to = copy(from)
18:20
< ToxicFrog|W`rkn>
Where the copy operation fills in the contents of to.
18:20 Chalain [~chalain@Admin.Nightstar.Net] has quit [Connection reset by peer]
18:20
< ToxicFrog|W`rkn>
As you can see, docopy() does the actual copy from one table to another, and get_ref() handles adding a new table to seen[] and recursively invoking docopy() as needed.
18:22 Chalain [~chalain@ServicesAdmin.Nightstar.Net] has joined #code
18:23
< Chalain>
That was weird. My irc client locked up, which is scary, given that I'm irc'ing *FROM* troika.
18:23
< Chalain>
I did not see anything after I posted my question about the difference between our algorithms.
18:26
< ToxicFrog|W`rkn>
13:14 <Chalain> Oh, wait, then. What does your algorithm do differently, then?
18:26
< ToxicFrog|W`rkn>
13:16 <ToxicFrog|W`rkn> For keysafety, it deep-copies both keys and values rather than just values.
18:26
< ToxicFrog|W`rkn>
13:17 <ToxicFrog|W`rkn> For recursion-safety, it copies tables by creating an empty table in seen[] and then doing copy(from,to) rather than to = copy(from)
18:26
< ToxicFrog|W`rkn>
13:17 <ToxicFrog|W`rkn> Where the copy operation fills in the contents of to.
18:26
< ToxicFrog|W`rkn>
13:17 -!- Chalain [~chalain@Admin.Nightstar.Net] has quit [Connection reset by peer]
18:26
< ToxicFrog|W`rkn>
13:18 <ToxicFrog|W`rkn> As you can see, docopy() does the actual copy from one table to another, and get_ref() handles adding a new table to seen[] and recursively invoking docopy() as needed.
18:27
< Chalain>
Okay, but then you'd have the e[f]==nil problem, wouldn't you?
18:27
< Chalain>
e[copy_of_f] would now contain the value once contained by e[f].
18:27
< Chalain>
The key would move.
18:28
< ToxicFrog|W`rkn>
Oh. I see what you mean.
18:28
< ToxicFrog|W`rkn>
We were talking about different bugs.
18:29
< ToxicFrog|W`rkn>
I /don't/ consider that a bug.
18:29
< Chalain>
But I *do* see case when a double-deep copy would be beneficial. I am trying to duplicate a table such that the new table behaves exactly as the old one. You're trying to duplicate an *object* which needs to maintain complete internal consistency.
18:30
< ToxicFrog|W`rkn>
Right.
18:30 You're now known as TheWatcher
18:31
< ToxicFrog|W`rkn>
If you aren't worried about deep-copying keys, then your implementation works fine.
18:31
< Chalain>
So, yeah, I need good names for three different functions--shallow copy, value-deep copy, and double-deep copy.
18:33 * Chalain ponders table.copy as shallow, table.dup as vdeep, and table.deepcopy as kvdeep.
18:33
< Chalain>
Except that dup harkens me back to Ruby, in which [].dup is a shallow copy.
18:34
< Chalain>
But pretty much every array.copy method in every language ever means shallow copy.
18:34
< Chalain>
Hmm. copy, vcopy, kvcopy?
18:35
< Chalain>
Ah, wait! copy, dup and clone. You copy a shallow table. You duplicate a table whose keys need to remain the same, and you clone an object!
18:36
< Chalain>
Blerk. So I had to kill -9 irssi, and it didn't save my logs. Can you repaste your algo?
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> function tcopy(T)
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> local R = {}
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> local seen = { [T] = R }
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> local get_ref,docopy
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> function get_ref(ref)
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> if type(ref) ~= 'table' then
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> return ref
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> end
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> if not seen[ref] then
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> seen[ref] = {}
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> docopy(ref, seen[ref])
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> end
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> return seen[ref]
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> end
18:37
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> function docopy(from, to)
18:38
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> for key,value in pairs(from) do
18:38
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> to[get_ref(key)] = get_ref(value)
18:38
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> end
18:38
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> end
18:38
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> docopy(T, R)
18:38
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> return R
18:38
< ToxicFrog|W`rkn>
12:03 <ToxicFrog|W`rkn> end
18:42
< Chalain>
Thanks.
18:52 * TheWatcher ponders, could make his channel logs web accessible if it'd be useful
19:06
< ToxicFrog|W`rkn>
Hmm. And now I'm wondering if I need to change ttoa(), too.
19:06
< ToxicFrog|W`rkn>
I don't think I ever tested it on something recursive.
20:32 Alla [~alla@Nightstar-7829.oz.net] has joined #code
20:32
< Alla>
can someone here help me with a CGI script?
20:32
<@jerith>
What's the problem?
20:32
< Alla>
Please?
20:33
< Alla>
I managed to make the CGI IRC script run, on my new host, but it won't connect.
20:33
<@jerith>
If it doesn't require anything perl-specific I may be able to help.
20:33
<@jerith>
Hmm...
20:33
<@jerith>
Is it not perhaps a network issue?
20:33
< Alla>
http://zomg.freehostia.com/irc.cgi
20:33
<@jerith>
Can you telnet to the appropriate port?
20:34
< Alla>
it's set to irc.nightstar.net:6660
20:34
< Alla>
which SHOULD work.
20:34
< Alla>
but it displays NOTHING.
20:34
< Alla>
hmm. I should try a different network.
20:35
<@jerith>
Do you have shell access on the server?
20:35
<@jerith>
Perhaps the machine is firewalled?
20:35
< ToxicFrog|W`rkn>
Try SSHing into the host machine and telneting to Nightstar, first.
20:36
< Alla>
hmm. no, a different server doesn't work.
20:37
<@jerith>
You're hosted on freehostia, right?
20:37
<@TheWatcher>
Do you have access to your error_log?
20:37
< Alla>
and I'm currently connected to nightstar via someone else's CGI script, so it's not an IRC network issue.
20:37
<@TheWatcher>
Oh yeah, cgiirc works fine with nightstar
20:37
< Alla>
where would error_log be?
20:38
<@jerith>
Looks like they're unlikely to offer much in the way of server-side stuff.
20:38
<@TheWatcher>
Depends - on virtual hosts, usually in a logs/ directory outside your www
20:38
< Alla>
and I don't have ssh here, toxic.
20:38
<@TheWatcher>
But yeah, I'm surprised a perl script even works on a free host
20:38
< Alla>
there's ONLY a www directory here, watcher.
20:38
<@TheWatcher>
Ech, then you probably don't then
20:39
<@TheWatcher>
Hm
20:39
< Alla>
and they say they support cgi and perl, and a number of other server-side stuff.
20:39 * TheWatcher pokes his cgiirc install
20:39
<@jerith>
But they probably firewall outgoing connections.
20:39
< Alla>
watcher, where are you hosting it?
20:39
<@TheWatcher>
On my own box, next to me
20:39
< Alla>
hmm. teststream.cgi fails all but the first test. looks like a probable streaming issue, but I have no idea how to fix it.
20:40
<@jerith>
I'd offer you reasonably priced hosting on my box, but layeredtech have a very firm "no IRC" policy. :-/
20:40 * ToxicFrog|W`rkn knows nothing about debugging servers without SSH access; sorry.
20:40
< Alla>
see, the reason I'm going to a free host is that I can't afford paid hosting.
20:40
< ToxicFrog|W`rkn>
...although you could probably upload a script that gives you limited shell access.
20:40 You're now known as TheWatcher[afk[
20:40
< Alla>
ooh, toxic, do tell...
20:40
< ToxicFrog|W`rkn>
Although the hosting company might object to that.
20:41
< ToxicFrog|W`rkn>
And it's a horrible, horrible security risk.
20:41
<@jerith>
Hmm... read a textbox into a system() perhaps?
20:41
< Alla>
ToxicFrog|W`rkn: freehostia allows me to make password-protected areas. not as much of a security risk.
20:41
< ToxicFrog|W`rkn>
Yes. Or, for easier implementation, use bash instead of perl.
20:42
<@jerith>
Alla: That's not as secure as you might think.
20:42
< ToxicFrog|W`rkn>
argv=`cat`; cmd=`echo "$argv" | sed -r -e 's;^cmd=;;' | urldecode`
20:42
< Alla>
heck, I'd have gone java-chat but the boxen at this college block java ports.
20:42
< Alla>
jerith: it's all relative.
20:42
<@jerith>
Especially if it's not ssl.
20:42
< ToxicFrog|W`rkn>
bash -c "$cmd"
20:42
< ToxicFrog|W`rkn>
Add headers to that and you have a remote shell access script.
20:42
< Alla>
okay, I'm a little confused.
20:42
< ToxicFrog|W`rkn>
With, I note, no form of authentication or safety checking.
20:43
< Alla>
>_>
20:43
<@jerith>
TF: Nice. :-)
20:43
< ToxicFrog|W`rkn>
So I can't really recommend it~
20:43
< ToxicFrog|W`rkn>
jerith: well, you also need a 'urldecode' program.
20:43
< ToxicFrog|W`rkn>
Although you can fake it with sed.
20:43
< ToxicFrog|W`rkn>
(if you enjoy pain)
20:43
< Alla>
uuh.
20:44
<@jerith>
urldecode's pretty easy to write with anything that groks hex.
20:44
< Alla>
I'm not that much of a power user. >_>
20:44
< ToxicFrog|W`rkn>
jerith: yeah, generally I just slap together a small C program to do this.
20:44
< Alla>
I mean, I can hack and slash my way through a hello.c, but that's a bit beyond me.
20:44
<@jerith>
Heh. We're all grizzled programmers in here (mostly) so you're not expected to follow everything. :-)
20:44
< ToxicFrog|W`rkn>
But it depends on what kinds of binaries you're allowed to install on the server.
20:45
< ToxicFrog|W`rkn>
I mean, what if his host /only/ supports perl?
20:45
< ToxicFrog|W`rkn>
What if it doesn't even have a shell?
20:45
<@jerith>
Gah! It /could/ be IIS or something equally nasty.
20:45
< ToxicFrog|W`rkn>
Then we find ourselves porting bash to perl, which is not something I even want to contemplate.
20:45
< Alla>
perl, php, mysql...
20:45
< ToxicFrog|W`rkn>
Alla: what OS?
20:45
< ToxicFrog|W`rkn>
And webserver?
20:45
<@jerith>
On second thoughts, probably not since it's still up...
20:46
< ToxicFrog|W`rkn>
jerith: could be Apache running on 2k or something.
20:46
< Alla>
and yeah, it's Linux Apache.
20:46
< ToxicFrog|W`rkn>
That'll usually stay up a few days at least.
20:46
< ToxicFrog|W`rkn>
Aah, excellent.
20:46
< ToxicFrog|W`rkn>
You probably have a shell, then.
20:46
<@jerith>
In which case tcpdump to sniff the irc packets is unlikely to work.
20:46
< Alla>
but no idea how to connect to said shell. ftp works, but that's all I can find.
20:46
<@jerith>
Then again, I can never remember if tcpdump likes you to be root.
20:47
< ToxicFrog|W`rkn>
Alla: you have tried SSH and it failed, yes?
20:47
<@jerith>
Alla: I very much doubt they give you shell access.
20:47
< Alla>
I'm on an XP box. cmd can't find ssh.
20:47
< ToxicFrog|W`rkn>
Cygwin.
20:47
<@jerith>
Very few web hosting places do unless you specifically ask for it.
20:47
<@jerith>
Putty.
20:47
< ToxicFrog|W`rkn>
Seriously, if you don't have a POSIX environment, how do you expect to test stuff~
20:48
<@jerith>
http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
20:48
< ToxicFrog|W`rkn>
jerith: very few places offer free CGI, too, but this one apparently does.
20:48 Alla [~alla@Nightstar-7829.oz.net] has quit [Quit: CGI:IRC 0.4.2 [EOF]]
20:48
< ToxicFrog|W`rkn>
www.cygwin.com/setup.exe
20:48
< ToxicFrog|W`rkn>
Fooey.
20:48
<@jerith>
There's no mention of shell access on the homepage, though.
20:48
< ToxicFrog|W`rkn>
Aah.
20:48 Alla [~alla@Nightstar-7829.oz.net] has joined #code
20:48
< ToxicFrog|W`rkn>
Wibs.
20:49
<@jerith>
Welcome back. :-)
20:49
< ToxicFrog|W`rkn>
In case you missed it:
20:49
< ToxicFrog|W`rkn>
15:45 <jerith> http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
20:49
< ToxicFrog|W`rkn>
15:45 <ToxicFrog|W`rkn> www.cygwin.com/setup.exe
20:49
< Alla>
have I mentioned how much I hate cgi?
20:49
< ToxicFrog|W`rkn>
The former is PuTTY, an SSH client and terminal emulator.
20:49
< Alla>
which binary do I download from putty?
20:49
<@jerith>
That putty URL was off the top of my head, by the way.
20:49
< ToxicFrog|W`rkn>
The latter ic Cygwin, a nearly complete POSIX environment for windows.
20:49
< ToxicFrog|W`rkn>
Alla: x86 win32?
20:49
<@jerith>
The installer should do the trick.
20:49
< Alla>
XP, yes.
20:50
< ToxicFrog|W`rkn>
putty.exe will do for this.
20:50
<@jerith>
I have to use far to many random windows boxen.
20:50
< ToxicFrog|W`rkn>
"for windows XP on intel x86"
20:50
< ToxicFrog|W`rkn>
Or, alternately, the putty-0.58-installer.exe
20:50
< ToxicFrog|W`rkn>
jerith: I just install Cygwin on all of them.
20:50
<@jerith>
Gah! Nearly 22h00.
20:50
<@jerith>
TF: I usually don't have install perms.
20:51
<@jerith>
And since all I need is ssh to a real box...
20:51
< ToxicFrog|W`rkn>
Aah.
20:51
< ToxicFrog|W`rkn>
I still need to come up with a way to store a portable Cygwin on a USB stick.
20:51
<@jerith>
Also, since internet is so bloody expensive and slow here at the bottom of the Dark Continent...
20:52
< Alla>
...
20:52
< Alla>
it denies my password on ssh connect.
20:52
<@jerith>
So no shell, then.
20:52
< ToxicFrog|W`rkn>
You probably don't have SSH access, then.
20:52
< ToxicFrog|W`rkn>
(which also means no scp, no rsync and no sftp. Blergh.)
20:53
<@jerith>
And chances are the cgi runs in a padded cell, too.
20:53
< ToxicFrog|W`rkn>
jerith: as long as we can run netcat~
20:53
< ToxicFrog|W`rkn>
...
20:53
< ToxicFrog|W`rkn>
If they have netcat and it's compiled with -DGAPING_SECURITY_HOLE, I won't know whether to laugh or cry.
20:53
< ToxicFrog|W`rkn>
But they probably wont.
20:53
< ToxicFrog|W`rkn>
I mean, no-one could be that stupid...
20:54
<@jerith>
Worth a shot anyway.
20:54
< Alla>
... might the fact that free accounts are only allowed 1.3% of their cpu load have anything to do with it?
20:54
<@jerith>
Probably not really.
20:54
< Alla>
as a streaming problem?
20:54
<@jerith>
Not for a single user.
20:54
< Alla>
cause indications are that's what it is.
20:54
< ToxicFrog|W`rkn>
Not for--what Jerith said.
20:55
< Alla>
http://zomg.freehostia.com/teststream.cgi
20:55
< ToxicFrog|W`rkn>
What, it's getting kill()d for exceeding CPU use limits?
20:55
< Alla>
I dunno.
20:55
<@jerith>
Not unless the perl interpreter's really crunching something.
20:55
<@jerith>
Write a simple cgi that "curl"s a website or something?
20:56
< Alla>
wha?
20:56
< ToxicFrog|W`rkn>
curl is a program for downloading webpages from the command line.
20:56
< ToxicFrog|W`rkn>
Similar to wget.
20:56
< Alla>
ookay.
20:56
<@jerith>
Only it outputs to stdout instead of a file.
20:57
< ToxicFrog|W`rkn>
Alright, but here's a really simple test script:
20:57
<@jerith>
It's also a library that's been ported to a bunch of different languages.
20:57
< ToxicFrog|W`rkn>
#!/bin/bash
20:57
< Alla>
okay. out of 6 streaming tests, only the first, test 0, passed.
20:57
< ToxicFrog|W`rkn>
echo 'Content-type: text/plain'
20:57
< ToxicFrog|W`rkn>
echo 'Pragma: no-cache'
20:57
< ToxicFrog|W`rkn>
echo
20:57
< ToxicFrog|W`rkn>
telnet irc.nightstar.net 6660
20:57
< ToxicFrog|W`rkn>
exit 0
20:58
< ToxicFrog|W`rkn>
That'll tell you if you can connect.
20:58
<@jerith>
(Assuming apache doesn't timeout before the telnet's done.)
20:59
<@jerith>
But a firewall should trow a "connection refused" which comes back pretty quickly.
20:59
< ToxicFrog|W`rkn>
This may depend on configuration, but I think it'll send lines from telnet as they arrive, rather than waiting for the CGI to exit.
20:59
<@jerith>
Unless the packets are being routed to /dev/null.
21:00
< ToxicFrog|W`rkn>
In which case it'll come back with a timeout. Eventually.
21:00
< Alla>
Trying 72.20.46.108...
21:00
< Alla>
Connected to blargh.nightstar.net.
21:00
<@jerith>
Cool, TF is right. :-)
21:00
< Alla>
Escape character is '^]'.
21:00
< Alla>
that's all the output.
21:00
<@jerith>
And it seems to be connecting fine.
21:00
< ToxicFrog|W`rkn>
That's not find.
21:00
< ToxicFrog|W`rkn>
*fine.
21:00
< Alla>
uhhuh. so what's the problem with my cgi then?
21:01
<@jerith>
So it's apparently not a network issue.
21:01
<@jerith>
Isn't it?
21:01
< ToxicFrog|W`rkn>
$ telnet blargh.nightstar.net 6660
21:01
< ToxicFrog|W`rkn>
Trying 72.20.46.108...
21:01
< ToxicFrog|W`rkn>
Connected to blargh.ca.us.nightstar.net.
21:01
< ToxicFrog|W`rkn>
Escape character is '^]'.
21:01
< ToxicFrog|W`rkn>
:Blargh.CA.US.Nightstar.Net NOTICE AUTH :*** Looking up your hostname...
21:01
< ToxicFrog|W`rkn>
:Blargh.CA.US.Nightstar.Net NOTICE AUTH :*** Checking ident...
21:01
< Alla>
oookay.
21:01
< ToxicFrog|W`rkn>
What you're seeing is like it's connecting, but not getting anything back from the servert.
21:01
< Alla>
huh.
21:01
< Alla>
and before you ask, modes are all 755.
21:01
< Alla>
like the installation docs say.
21:01
< ToxicFrog|W`rkn>
Yeah, modes aren't going to be the problem.
21:02
< ToxicFrog|W`rkn>
Can you link me to that test script in its uploaded form?
21:02
< Alla>
http://zomg.freehostia.com/test.cgi
21:02
< Alla>
or just use http://zomg.freehostia.com/
21:02
< Alla>
it's a directory listing. >_>
21:02
< ToxicFrog|W`rkn>
...yeah. Weird.
21:02
<@jerith>
It seems to just be stopping.
21:02
< Alla>
try connecting via irc.cgi
21:03
< ToxicFrog|W`rkn>
I did. Same results: nothing comes back from the server.
21:03
< Alla>
also try teststream.cgi
21:03
< ToxicFrog|W`rkn>
And I did that, too. Test 0 passes, the others fail.
21:03
<@jerith>
Perhaps replace the telnet line with: curl www.google.com
21:04
<@jerith>
That'll at least tell us if /something/ is getting through.
21:04
< Alla>
loads, but not the pictures.
21:04
< Alla>
try test2.cgi
21:04
< Alla>
links are dead, though.
21:05
< Alla>
are they supposed to be like that?
21:05
< Alla>
redirecting to freehostia.com...
21:05
< Alla>
O_O
21:05
< ToxicFrog|W`rkn>
Yes, that's normal.
21:05
< ToxicFrog|W`rkn>
It's dumping the page as text, not as HTML.
21:05
< Alla>
... only the images link redirects, the others are as normal.
21:05
< ToxicFrog|W`rkn>
That's what the [[echo 'Content-type: text/plain']] does.
21:05
<@jerith>
Hmm...
21:05
< Alla>
well, video and news are.
21:06
<@jerith>
Perhaps the browser is interpreting it as html anyway?
21:06
< Alla>
and so is sign in.
21:06
< ToxicFrog|W`rkn>
jerith: mine damn well isn't.
21:06
< Alla>
VERY interesting.
21:06
< ToxicFrog|W`rkn>
I get the text of www.google.com just as though I'd curled it from the shell.
21:06
<@jerith>
Try: curl http://www.jerith.za.net:4133
21:07
< Alla>
seems most of the links are coded to (current server)/link.html but those three are hardcoded to google.com/link.html
21:07
<@jerith>
(That'll tell us if arbitrary ports are blocked.)
21:07
<@jerith>
Alla: Yeah, they're relative so they think they should go to your server.
21:07
< Alla>
test3.cgi
21:07
< Alla>
works.
21:08
< Alla>
except it's all relative. >_>
21:08
<@jerith>
What web browser are you using?
21:08
< Alla>
IE
21:08
<@jerith>
Ah, that explains it.
21:08
< Alla>
6.0
21:08
<@jerith>
IE ignores a bunch of standards.
21:08
< Alla>
kinda can't use anything else here.
21:09
<@jerith>
And it thinks that anything that looks like html should be rendered as such.
21:09
< Alla>
heh.
21:09
< Alla>
that's so.
21:09
<@jerith>
Meh. Yet another reason to switch to Firefox. :-/
21:10
<@jerith>
So, it seems to only be having the problem with IRC.
21:10
< Alla>
I said, can't use anything else here.
21:10
< Alla>
those are college boxen.
21:11
<@jerith>
I remember the days of being stuck using campus machines.
21:11
< Alla>
and it's almost definitely a server-side problem, since I'm connected from a different host.
21:11
< Alla>
http://www.axenhammer.com/cgi-bin/cgiirc/irc.cgi
21:11
<@jerith>
Yeah, probably network funkiness.
21:11
<@jerith>
Maybe they block anything that looks like IRC.
21:11
< Alla>
and no, the machines here ARE able to share. I remember connecting several CGI-IRC windows simultaneously earlier.
21:12
<@jerith>
That would be daft, though, since content-based firewalls are horrendously expensive computationally.
21:12
< Alla>
well, they block mirc and pirch, and java chat. but not cgi-irc.
21:12
<@jerith>
CGI-IRC uses http as a transport medium.
21:12
< Alla>
which is how it's able to bypass the local block.
21:13
< Alla>
maybe freehostia has an irc block...
21:13
<@jerith>
So from campus they probably just block anything that isn't port 80 or 443 (or a few other select ports).
21:13
<@jerith>
The fact that the telnet claims to connect makes a block on port 6660 unlikely...
21:14
<@jerith>
I'll quickly fire up a webserver on port 6660 for you to test, though...
21:14
< Alla>
well... they don't allow irc servers or irc bots, but says nothing of irc clients.
21:15
< Alla>
and yeah, telnet DOES usually work on these boxen.
21:16
<@jerith>
Try that cgi with jerith.za.net:6660
21:17
< Alla>
works.
21:18
< Alla>
can you set it to 23 for a moment so I can try that?
21:18
<@jerith>
So, it's something to do with streaming.
21:18
< Alla>
apparently.
21:19
<@jerith>
I can't, my server doesn't run as root.
21:19
<@jerith>
So nothing below 1024.
21:20
<@jerith>
Anyways, I'd best head off to bed now.
21:20
< Alla>
mmmh
21:20
<@jerith>
It's after 22h00 and I have a long day at work tomorrow. :-(
21:20
< Alla>
good night.
21:20
< Alla>
you're in Europe?
21:20
<@jerith>
(The silly networking people keep breaking things and then we have to pick up the pieces.)
21:20
<@jerith>
South Africa.
21:20
<@jerith>
:-)
21:20
< Alla>
that works too.
21:21
< Alla>
GMT+1
21:21
<@jerith>
GMT+2, actually.
21:21
<@jerith>
And no DST madness, thank $deity.
21:22
<@jerith>
Anyways, g'night.
21:22
<@jerith>
Thanks for a pleasant conversation and sorry I couldn't be of more help.
21:22
< Alla>
ah, no DST. okay. night.
21:22
< Alla>
no problem.
21:23
< Alla>
anyone else awake in here?
21:23
< ToxicFrog|W`rkn>
Intermittently.
21:24
< ToxicFrog|W`rkn>
I am at work, after all.
21:24
< Alla>
so, any suggestions?
21:25
< ToxicFrog|W`rkn>
Not really...this is kind of outside my experience.
21:25
< Alla>
okay.
21:25 MahalZzz is now known as Mahal
21:25
< Alla>
know where I can find some help? or a free web host that allows cgi/perl and is reliable?
21:26
<@Mahal>
A) define help b) no idea, although I can point you at a really really good cheap one.
21:26
< Alla>
Mahal, I'm having trouble getting a cgi irc script to connect. looks like streaming issues.
21:26
<@Mahal>
Ah.
21:26
<@Mahal>
Outside my abilities, sorry.
21:27
< Alla>
mmkay.
21:27 * Mahal read the backchat :)
21:27
< ToxicFrog|W`rkn>
It's entirely possible that they don't allow you to open sockets for more than a certain period of time.
21:27
< Alla>
hmm. that WOULD be a problem, wouldn't it?
21:27
< ToxicFrog|W`rkn>
Quite.
21:28
< Alla>
and it would go hand in hand with the restricted cpu usage.
21:28
< ToxicFrog|W`rkn>
There's various cheap hosts that you can do this on, but I don't know of any free ones.
21:28 * ToxicFrog|W`rkn nods.
21:28
< Alla>
okay, back to free-webhosts.com it is.
21:30 You're now known as TheWatcher
21:31
< ToxicFrog|W`rkn>
Why do you need this, anyways?
21:31
< ToxicFrog|W`rkn>
You said something about your univ banning Java?
21:31 * Mahal points at irc.myapple.pl
21:32
< Alla>
yes, toxic.
21:33
< ToxicFrog|W`rkn>
All java? Or the ports that the javachat uses for outbound connections?
21:34
< Alla>
just javachat.
21:34
< Alla>
and downloadable irc clients.
21:34
<@Mahal>
there's a fair few pre-existing cgi:irc's available on the web.
21:34
<@Mahal>
like the one I just pointed at :)
21:35
< Alla>
I've found one working cgi irc that I'm using right now, but I've had problems before with these sites disappearing, so I wanted to host my own so I'd be sure of it.
21:35
<@Mahal>
Ah, I see.
21:35
<@Mahal>
myapple's been around 6 months that I know of.
21:35
< ToxicFrog|W`rkn>
Alla: do you know what ports they block?
21:35
<@TheWatcher>
I could let you use mine, except that it tends to be flakey since I'm hosting a lot of other stuff off here
21:35
< Alla>
and this one's the only one I've found that allows me to connect to irc.nightstar.net
21:35
< ToxicFrog|W`rkn>
There might be a port we have open that they don't block.
21:35
< Alla>
even irc.myapple.pl doesn't quite connect.
21:35
< ToxicFrog|W`rkn>
(also, have you tried asking why they ban it? Their netadmins might be reasonable.)
21:36
<@Mahal>
Frog: My uni blocked /everything/ except: 80, 8080, 443, and one other that I forget.
21:36
< Alla>
hmm. I could ask, I suppose.
21:36
<@Mahal>
Oh, 25. Mail, duh.
21:36
< Alla>
and no, I have no idea how to find out what ports are blocked except by asking.
21:36
< ToxicFrog|W`rkn>
Alla: try.
21:36
< ToxicFrog|W`rkn>
Open a shell, telnet irc.nightstar.net <port>
21:36
< Alla>
heh. I will, I suppose.
21:36
< ToxicFrog|W`rkn>
Ports are 6660-6666,6668,6669,7000.
21:37 * Mahal notes her own uni was retarded >.<
21:37
< ToxicFrog|W`rkn>
Mahal: they let mail out? o.O
21:37
<@Mahal>
No, in.
21:37
< ToxicFrog|W`rkn>
Aah
21:38
<@Mahal>
Blooody hard to work on assignments - especially linux o nes - when you can't SSH,too.
21:38
< ToxicFrog|W`rkn>
Mine initially blocked IRC (well, deprioritized it, which had effectively the same effect), but I talked to them, explained that IRC and DCC are different protocols (citing the RFCs), and they unblocked it.
21:38
< Alla>
nope, all blocked.
21:38
<@Mahal>
We weren't allowd chat, Frog.
21:39
< ToxicFrog|W`rkn>
Keh.
21:39
< Alla>
heh. chat proggies work on here, as evidenced by the occasional Y! or AIM install... but not irc. >_>
21:39
< ToxicFrog|W`rkn>
How vexing.
21:39
< Alla>
quite.
21:39
< ToxicFrog|W`rkn>
I recommend a mix of fire, and rich, chunky volts.
21:39
< Alla>
heh.
21:40
< Alla>
oh yeah, I'm gonna leave soon. lab closes early during breaks between the semesters.
21:40
<@TheWatcher>
Mahal: that's th epoint where I'd have a machine in the department runnign ssh on port 80 and then connect in to that to get to other machines ¬¬
21:40
< Alla>
I have... 45 minutes left.
21:41
<@Mahal>
Watcher: we were students.
21:41
< Alla>
exactly.
21:41
<@Mahal>
Without sufficient access to any machines to be able to do that.
21:41
<@Mahal>
Unless we could use our own.
21:41
<@TheWatcher>
That never stopped me <.< >.> *cough*
21:41
< Alla>
heh.
21:41
<@Mahal>
And at that stage, I was still fighting the battle of "BUT INTERNETS ARE EVIL" with my mother.
21:42
< Alla>
come to think of it, this place has wifi.
21:42
< Alla>
all I need's a laptop with a wifi card.
21:42
<@TheWatcher>
Eeesh, ouch. I'm lucky I never had that one.
21:42
< Alla>
... shyeah right. where am I gonna get $500 for even a low-end one? much less $1000+ for one I can run games on?
21:43
<@Mahal>
I was /21/ before I finally oncinved her that I needed 'net access at home. To finish my /computing science/ degree >.<
21:43
< Alla>
hehe.
21:43 * Alla hugs Mahal.
21:43
< Alla>
I know the feeling. I STILL don't have net access at home.
21:43
< Alla>
at 25.
21:43
<@TheWatcher>
>.<
21:44 * Mahal nods
21:44 * Mahal moved Out :)
21:44
< Alla>
I can't afford to. :(
21:44
<@Mahal>
Suck.
21:45 * TheWatcher patpats Alla
21:50
< Alla>
oh well. I'll ask the netadmins here about it, sometime.
21:50
< Alla>
thanks, guys.
21:51
< Alla>
hey guys, a question.
21:51
< Alla>
... mistell. sorry.
21:54 * TheWatcher readsup, idly notes that the only difference between an irc bot and an irc client is that one has a bunch of scripts doing th ework rather than a human - if they don't allow bots, it's a pretty good bet clients of all kinds ar eblocked.
21:55
< Alla>
that's a good point...
21:55 * ToxicFrog|W`rkn upreads. I was lucky; net access at home pretty much from the beginning.
21:55 ReivZzz is now known as ReivClass
21:57 Chalcy is now known as Chalcedon
21:58 Mahal is now known as MahalWr0k
22:06 * Chalcedon beats her Uni
22:07 ToxicFrog|W`rkn is now known as ToxicFrog|AFK
22:07
<@Chalcedon>
they were the internet gateway for New Zealand, in from very early on when it was still an academic project
22:07
<@Chalcedon>
Then they sold it to Telecom when it became more of a publicly available thing.
22:07 * Chalcedon mutters @#$$%^$%&^**(%^&$$%$%@!!!!!!!!!!!!!
22:27 Alla [~alla@Nightstar-7829.oz.net] has quit [Quit: Scarlet Princess has been captured!]
22:43 You're now known as TheWatcher[afk]
23:01 MahalWr0k is now known as Mahal
23:02 Mahal [~Mahal@Nightstar-5192.worldnet.co.nz] has quit [Quit: It's hard to be mad at someone who misses you while you're asleep. ]
23:02 Mahal [~Mahal@Nightstar-5192.worldnet.co.nz] has joined #code
23:02 mode/#code [+o Mahal] by ChanServ
23:02 You're now known as TheWatcher
23:13 You're now known as TheWatcher[T-2]
23:24 You're now known as theWatcher[afk]
23:24 You're now known as TheWatcher[afk]
23:29 ReivUni [~82d94c4d@Nightstar-14006.mail.city-net.pl] has joined #Code
23:39 Mahal is now known as MahalAFK
23:58 ReivUni [~82d94c4d@Nightstar-14006.mail.city-net.pl] has quit [Quit: HOME]
--- Log closed Fri Aug 11 00:00:02 2006
code logs -> 2006 -> Thu, 10 Aug 2006< code.20060809.log - code.20060811.log >