Ok, how many of you out there ever program in Tcl?
Ah! One, and someone in the back row (which, on this blog, also happens to be the first row) that was scratching their nose. Ok, hands down.
So I’m doing a project in Tcl (as in, the language they talk about at http://tcl.tk) and there’s been something I wanted to do that is SO DAMN CINCHY IN OTHER LANGUAGES.
A list of arrays. You know, a basic list where each element is a pointer or ref to a blob of memory (in this case, a Tcl array, which is a hashmap/associative array).
That’s all.. just a list where each element is an associative array. You’d think this would be straightforward. But ah! Not in Tcl. Believe me, I’ve gone around to wiki.tcl.tk, googled this and that, and stared at my Tcl book till my eyes got bloodshot. I figured it should be possible without having to get into something like “eval”.
I’ll show ya what I mean. Here’s a simple hash:
nscp 1> set hashOne(dls) daniel
daniel
nscp 2> set hashOne(ss) sophia
sophia
and here’s another…
nscp 3> set hashTwo(pet) cat
cat
nscp 4> set hashTwo(car) m3
m3
and they look like:
nscp 5> array get hashOne
ss sophia dls daniel
nscp 6> array get hashTwo
pet cat car m3
So far so good. Can we add an array to a list?
nscp 13> set rr [list]
nscp 14> lappend rr $hashTwo
can’t read “hashTwo”: variable is array
(and about 5 other tries at this failed as well…)
Oh fuck you Tcl! I mean, really now, why should this be so hard? Or perhaps the question could be: how come this is so straightforward in PHP, Perl, Java, and so on?
(btw, I realize there is likely a Tcl extension that makes this work, but for the purposes of what I am doing, I have to stay stock)
Of course, you could collapse an array into a list:
nscp 8> set someList [array get hashOne]
ss sophia dls daniel
nscp 12> lrange $someList 0 3
ss sophia dls daniel
But that’s a hassle if I ever want to get the data back out as a proper hash.
To be clear, I want a list of arrays, not a list of lists.
So to bring this little excursion to a close (and to be able to get on with the thing I am prototyping, that I can’t talk about), I punted a bit.
Another approach which seems common in Tcl-land is to imply dimensions in an array by using the comma ‘,’ separator:
set someContainer(PetOne,catName) “tasha”
set someContainer(PetOne,catAge) 12
set someContainer(PetTwo,catName) “valentine”
set someContainer(PetTwo,catAge) 5
Then you can zero in on a particular slice of the array via:
nscp 30> array get someContainer PetOne,*
PetOne,catAge 12 PetOne,catName tasha
Works, yes. But I feel so dirty doing it this way :-)