This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

A C programmer grumbles...

Old posts that have not been replied to for several years.
Locked
P
PurplePants

A C programmer grumbles...

Post by PurplePants »

Go on, admit it, tcl has 'female' logic, right?

I'm trying to create a list of arrays. In C this would be an array of structs, I guess. The idea is there's a number of records (the arrays) and the list just keeps 'em easy to look up. It doesn't work :)

For a sample, when the script starts it initialises an array and populates the list thus:

Code: Select all

    global RecordList

    unset RecordList
    set ARecord ""
    upvar $ARecord Record
    set Record(Ref) "12345"
    set Record(IP) "123.456.789.0"
    set Record(nick) "ABotter"
    lappend RecordList Record
    set Record(Ref) "98765"
    set Record(IP) "098.765.432.1"
    set Record(nick) "BBotter"
    lappend RecordList Record
        set Record(Ref) "33333"
        set Record(IP) "333.3.333.1"
        set Record(nick) "CBotter"
        lappend RecordList Record
    unset ARecord

    set maxrecs [llength $RecordList]
    putlog "Records: $maxrecs"
No doubt there's some stuff there which is sub-optimal, but after a whole day of furkling this didn't cause an error whereas the other 2000 attempts did :)

$maxrecs says '3' so I assume the list is populated. Next, I try to pull out the last record:

Code: Select all

    global RecordList

    upvar #0 RecordList ARecordList
    set LastRecord [llength $ARecordList]
    upvar [lindex $ARecordList $LastRecord] Record
    putserv "NOTICE $nick :Latest record is $LastRecord:"
    putserv "NOTICE $nick :$LastRecord $Record(Ref) $Record(IP) $Record(nick)"
Works fine. $LastRecord is '3' and the appropriate info is shown.

But... if I make $LastRecord '2' or '1' the thing just comes back and says "Tcl error [do_ABlistcmd]: can't read "Record(Ref)": no such variable".

This is doing my head in (even more so than the wallop thing). I think I'm going to cry.
User avatar
stdragon
Owner
Posts: 959
Joined: Sun Sep 23, 2001 8:00 pm
Contact:

Post by stdragon »

Tcl and C do not use the same terms for everything. Tcl's "arrays" are actually hash tables. They are different from all other tcl variables, because you cannot say $arrayname to get their value. When you are doing lappend RecordList Record, it is actually appending the string "Record" to that list, not the contents of the array.

It is possible to do what you're trying to do, using upvar and unique variable names, but it's not worth it.

The easiest way (probably) is to use a single array (not a list) and make it look multi-dimensional by using a naming trick, e.g.:

set records(1,ip) "1.2.3.4"
set records(1,nick) "stdragon"
set records(1,ref) "blah"

Then for the 2nd record, use 2 instead of 1, and so on. However, it would be better if you used some unique identifier rather than 1, 2, 3. That way you don't need to update a bunch of entries when you insert/delete one. For instance, if your "ref" thing is unique, that would be good. You'd do something like:

set records($ref,ip) "1.2.3.4"
set records($ref,nick) "stdragon"

To see if it exists, do

if {[info exists records($ref,nick)]} {...}

Another way to do this, which might be easier if you don't have a unique key, or you need to keep track of ordering, is to use nested lists (much like nested arrays in C).

set record [list "stdragon" "1.2.3.4" "3333"]
lappend all_records $record

Then when you want the first record,
set record [lindex $all_records 0]

Extract the individual fields like:
set nick [lindex $record 0]
set ip [lindex $record 1]
set ref [lindex $record 2]
or the one-liner: foreach {nick ip ref} $record {}

Anyway, don't cry! Everything will be all right, there there.
P
Photon
Op
Posts: 170
Joined: Wed Aug 28, 2002 8:00 am
Location: Liverpool, England

Post by Photon »

Speaking as an established pro C coder, TCL did my head in.

It wasnt as much the strange syntax, but also the lack of reasonable debugging info and the totally bizarre error messages that you occasionally get...

Thats why I delved into the wonderful world of modules. Everything you can do in tcl, and much more power too... and all in a 'logical' language... *bliss* :D

takes a little to get started ... but from then on...

/me runs before the hardcore TCL-ers get me for blasphemy!!! :evil:
P
PurplePants

Post by PurplePants »

stdragon wrote:Tcl and C do not use the same terms for everything
Or much at all, really :)

Let me explain further, to put your suggestions in context:

I have a database on disk from which I want to display specific records. To find which record to display, the user can ask for a list of records and the output of the list displays the information you see in my query - basic stuff that allows him to pick the one he wasn't the full details from. He selects, say, record #20 and this is then pulled off disk and shown. Oh, and it's sort of free form so a particular field may or may not exist in any particular record.

The array stuff that I'm doing here is basically an in-memory index to the disk database, so there's no need to disk furkling until all the details for a record are needed. At startup (and periodically if the database is updated) the basic fields (IP, Ref, etc) are read into memory. Thus there wil be no inserts or deletions because the whole thing is created from scratch if there's a modification.

So, back to your first suggestion... looks just the job actually :). However, the list of lists does actualy look like a list of arrays (i.e. what I was trying to do) because you can set an array from a list, no? So pulling the record list from the list of lists and setting an array from that is pretty much what I was trying to do, even if I might not have wanted to be doing that in the first place. Hmmm. Something to think about before I'm allowed lose on the code again tonight.

Thanks very much, I'm much happier now :)
P
PurplePants

Post by PurplePants »

Photon wrote:TCL did my head in.
Oh yes! There are comments as to my probable state of mind and safety of my computer whenever it's known that I'm having a go at tcl. And it's not hard to figure out when that is, apparently.

I'm thinking of specifying tcl as a scripting addon to our next product, just to piss off those colleagues that annoy me :)
Locked