开发者

Tcl and records (structs)

开发者 https://www.devze.com 2023-02-21 20:11 出处:网络
Package struct::record from TCLLIB provides means for emulating record types.But record instances are commands in the current namespace and not variables in the current scope.This means there is no ga

Package struct::record from TCLLIB provides means for emulating record types. But record instances are commands in the current namespace and not variables in the current scope. This means there is no garbage collection for recor开发者_JAVA技巧d instances. Passing name of the record instance to a procedure means passing it by reference not by value, it is possible to pass string representation of the record as parameter but it requires to create another instance in the procedure, configure it and delete by hand, it's annoying. I wonder about the rationale behind this design. A simple alternative is provide a lisp-style records - a set of construction, access and modification procedures and represent records as lists.


The struct::record implementation is, from my viewpoint, an oo-style implementation. If you're searching for a data-style implementation (like lisp) where the commands are totally separate from the data, you might want to look at the dict command.

I'll note that oo-style and data-style are really not good descriptions, but they were the best I could think of offhand.


You most certainly can do it “the Lisp way”.

 proc mkFooBarRecord {foo bar} {
     # Keep index #0 for a "type" for easier debugging
     return [list "fooBarRecord" $foo $bar]
 }
 proc getFoo {fooBarRecord} {
     if {[lindex $fooBarRecord 0] ne "fooBarRecord"} {error "not fooBarRecord"}
     return [lindex $fooBarRecord 1]
 }
 # Etc.

That works quite well. (Write it in C and you can make it more efficient too.) Mind you, as a generic data structure, it seems that many people prefer Tcl 8.5's dictionaries. There are many ways to use them; here's one:

 proc mkFooBarRecord {foo bar} {
     return [dict create "type" fooBarRecord "foo" $foo "bar" $bar]
 }
 proc getFoo {fooBarRecord} {
     dict with fooBarRecord {
         if {$type ne "fooBarRecord"} {error "not fooBarRecord"}
         return $foo
     }
 }

As for the whole structures versus objects debate, Tcl tends to regard objects as state with operations (leading to a natural presentation as a command, a fairly heavyweight concept) whereas structures are pure values (and so lightweight). Having written a fair chunk on this, I really don't know what's best in general; I work on a case-by-case basis. If you are going with “structures”, also consider whether you should have collections that represent fields across many structures (equivalent to using column-wise storage instead of row-wise storage in a database) as that can lead to more efficient handling in some cases.

Also consider using a database; SQLite integrates extremely well with Tcl, is reasonably efficient, and supports in-memory databases if you don't want to futz around with disk files.


I will not answer your question, because I was not been using Tcl for many years and I never use this kind of struct, but I can give you the path to two possible places that are very plausible to provide a good answer for you:

  • The Tcl'ers Wiki http://wiki.tcl.tk
  • The Frenode's Tcl IRC channel

At the time I used Tcl they proved to be invaluable resources.

0

精彩评论

暂无评论...
验证码 换一张
取 消