aitcs(n) 2.0 aitcs "AitCS"

Name

aitcs - Array in the Command's Shadow

Table Of Contents

Synopsis

Description

Array in the Command's Shadow provides a convenient way to access and manipulate arrays in namespaces by offering a higher level of abstraction for certain array operations.

An AitCS is an array with an associated set of commands that access or manipulate the array. Array accesses are via commands instead of referring to the array as a variable. The array is still an array, but there is now a set of commands that "know" the array.

An AitCS is designed to be used where a program would normally use global or namespace variables to hold configuration, state, widget paths, temp values, etc.

As opposed to namespace ensembles and objects, AitCS doesn't create one command and then dispatch on operators (subcommands). Instead, one command is created for each operator, with the name of the operator attached to the command.

For get/set operations, the command (the name of the AitCS) is used like Tcl's [set] command.

Regular:

	namespace eval myns {
		variable myarr
		set myarr(a) 1
		proc myproc1 {} {
			variable myarr
			if {![info exists myarr(b)]} {
				set myarr(b) [expr {$myarr(a) + 1}]
			}
		}
		proc myproc2 {} {
			variable myarr
			puts $myarr(b)
		}
		myproc1; myproc2
	}
	

AitCS:

	namespace eval myns {
		aitcs new myarr
		myarr a 1
		proc myproc1 {} {
			if {![myarr? b]} {
				myarr b [expr {[myarr a] + 1}]
			}
		}
		proc myproc2 {} {
			puts [myarr b]
		}
		myproc1; myproc2
	}
	

An AitCS is one array and nine commands. The commands access and manipulate the array itself.

An AitCS+ is one array and twelve commands. An AitCS+ is identical to an AitCS, with the exception of three additional commands. The additional commands access and manipulate the contents of array elements.

The array is created in a namespace and the commands are created in a (possibly different) namespace.

All references to array variables, elements, or commands produced by AitCS are fully qualified.

Destroying the array by any means other than by the "---" operator will only destroy the array, not the commands. There are no traces or other connections between the commands and the array; the commands only know the array's name.

An AitCS can have a random name or a user-supplied name. The actual array name is a concatenation of the name, a random string of characters, and some underscores for good measure. This is like an opaque pointer in that a human doesn't need to know the actual name of the array. Having randomly-generated names can help with writing fewer bugs as code will be less dependent on hardcoded variable names.

AitCS helps to reduce complications with namespaces, makes for cleaner code, and saves typing.

AitCS works with Jim as well as with Tcl.

COMMANDS

aitcs new ?name? ?-option value ...? ?--? ?key value ...?
aitcs+ new ?name? ?-option value ...? ?--? ?key value ...?

Creates a new array in the namespace variable_namespace and creates commands to manipulate the array in the namespace command_namespace.

If the name isn't supplied or is an empty string then the name will be set to a string of six random characters in the range a-z. An error will be returned if a unique random command in the command_namespace can't be created after one thousand attempts. This should never happen?

If the variable_namespace isn't supplied or is an empty string then it will be set to the caller's namespace.

If the command_namespace isn't supplied or is an empty string then the command_namespace will be set to the variable_namespace.

The array will be created as "variable_namespace::__name__cccccc_" where "cccccc" is six random characters in the range a-z.

If the command already exists or any of the required namespaces don't exist then an error will be returned and neither array nor commands will be created.

Initial values are set from key value ... if supplied.

Creates an array variable in the variable_namespace and associated commands in the command_namespace.

Returns the fully qualified name of the array's set/get command.

Options

-cns namespace
-command_namespace namespace

Set the command namespace.

-vns namespace
-variable_namespace namespace

Set the variable namespace.

--

End option processing. Any remaining arguments become initializers.

aitcs operators

Returns a list of all the AitCS operators.

aitcs+ operators

Returns a list of all the AitCS+ operators.

AITCS COMMANDS

AitCS commands are created in the command_namespace and are based on the name supplied when the AitCS was created.

The following commands are common to an AitCS and an AitCS+.

name!

Brings the array into existence in the current context. This is upvar #0 varname name. From then on in the current context the array can be referenced by name. Returns an empty string. Nickname: Make Exist.

name key ?value? ?key value ...?

Gets the value of one element of the array or sets the value of one or more elements of the array. The value(s) for the key(s) will be set using array set. Returns the value at key. Nickname: Get/Set.

name? key ?myVar?

Returns true if the key exists in the array or false if the key doesn't exist in the array. If the key exists and myVar is supplied and is not an empty string then the variable it names will be set in the caller's context to the value at key. Nickname: Exists.

name- key ?key ...?

Removes key(s) from the array. The array unset command is used, allowing key(s) to contain wildcards. It isn't an error if a key doesn't exist in the array. Returns an empty string. Nickname: Unset.

name^ key ?default? ?myVar?

Returns the value at key if it exists, otherwise returns default, or an empty string if default isn't supplied. If myVar is supplied and is not an empty string then the variable it names will be set in the caller's context to the returned value. Nickname: Get With Default.

name& ?key?

Returns the fully namespace qualified name of the array if no key supplied or if key is an empty string, otherwise returns the fully namespace qualified name of the array and the element key. Nickname: Variable Reference.

name&&

Returns the fully namespace qualified command. Nickname: Command Reference.

name-> key?op? ?arg ...?

The key should be another AitCS. Permits "nesting". Calls are chained. Nickname: Struct Dereference.

name---

Unsets the array and deletes all the commands. Returns an empty string. Nickname: Destroy.

The following commands are only provided by an AitCS+.

name= key ?key ...? value

Every key is set to value. Returns value. Nickname: Setto.

name+ key ?value ...?

Every value is lappended to the element at key. Returns the value at key. Nickname: Lappend.

name+= key ?incr ...?

Increments the value at key by all incr arguments (default 1). Returns the value at key. Nickname: Incr.

EXAMPLES

	# Set/Get/Variable Reference
	# Save a widget and link a textvariable
	aitcs new rec
	aitcs new gui
	set fld preference
	rec $fld Tcl
	gui $fld [entry .e -textvariable [rec& $fld]]
	[gui $fld] insert end /Tk
	string length [rec preference]; # 6
	# Get/Set
	aitcs new things
	things a 3
	things b [expr {[things a] + 2}]
	things c [expr {[things b] * [things a]}]
	things c; # 15
	# Exists
	aitcs new colours
	colours red #FF0000
	colours? red; # 1
	colours? green; # 0
	colours? red color1; # 1
	info exists color1; # 1
	set color1; # #FF0000
	colours? green color2; # 0
	info exists color2; # 0
	# Setto/Exists/Unset/Variable Reference
	aitcs+ new fruits
	fruits= apple orange pear apricot 0
	if {![fruits? peach]} {
		fruits= peach 0
	}
	array names [fruits&]; # {apple orange pear apricot peach}
	fruits- p* a*
	array names [fruits&]; # {orange}
	# Get With Default
	aitcs new things
	things are good
	things^ are ok; # good
	things^ be ok; # ok
	things^ willbe; # Empty string
	things^ is nice here; # nice, and var here is set to nice
	# Lappend
	aitcs+ new store
	store this one
	store+ this two three four five
	store this; # {one two three four five}
	# Incr
	aitcs+ new counters
	counters cycles 0
	counters+= cycles
	counters+= cycles 2
	counters+= cycles 3 -4 1
	counters cycles; # 3
	# Make Exist/Exists
	aitcs new cow
	cow!
	set cow(sound) moo
	if {[cow? sound] && $cow(sound) eq "moo"} {
		puts "Standard English Cow"
	}
	# Command Reference/Variable Reference/Incr
	aitcs new callback
	callback count 0
	after 1000 [list [callback&&]+= count]
	vwait [callback& count]
	callback count; # 1
	# Struct Dereference/Random Name/Initial Values
	aitcs new animals
	animals dog  [aitcs new {} {} {} says woof likes cat]
	animals cat  [aitcs new {} {} {} says meow likes dog]
	animals home [list dog cat]
	set res ""
	foreach animal [animals home] {
		append res $animal " says " [animals-> $animal says]
		append res " likes " [animals-> $animal likes]
		append res " who says " [animals-> [animals-> $animal likes] says]\n
	}
	set res
	# dog says woof likes cat who says meow
	# cat says meow likes dog who says woof
	# Struct Dereference
	aitcs+ new outer
	aitcs+ new inner
	aitcs+ new innest
	inner count 6
	innest things [list]
	innest+ things 1 2
	outer member inner
	inner item innest
	outer-> member+= count 2; # 8
	outer-> member-> item+ things 3 4; # {1 2 3 4}
	outer-> member-> item^ name; # Empty string
	# Destroy
	aitcs+ new tmp
	tmp count 5
	tmp+= count -1
	tmp count; # 4
	set fqarr [tmp&]
	info exists $fqarr; # 1
	tmp---
	info exists $fqarr; # 0
	tmp count; # <error>

HISTORY

The inspiration came from being tired of having to use the variable command in almost all the commands in a namespace when often in a given command there is usually interest in only a few items of the "global" state.

To maintain the smallest possible set of commands, the necessity and usefulness of each command was carefully considered before including it in AitCS. All commands were written and tested to be as fast as possible.

The "&" operator was inspired by C: obtaining a "reference" to an element of an array. The "&&" operator was inspired the "&" operator. The "^" operator was inspired by the XOR operator: result is one or the other. The "->" operator was inspired by C structures. Originally "." but changed for greater readability. The "!" operator is excitement: something has just come into existence! The "?" operator is the obvious choice for its function. The "-" operator generally means "remove something". The "+" operator generally means "add something". The "+=" operator was inspired by C. For the "---" (destroy) operator, three dashes were chosen because two would be too easily confused with C's "--", and it is reminiscent of "===" in other languages, which carries a meaning of "really serious this time".

BUGS

In the interest of speed, the AitCS commands don't check anything. Errors reported will be errors occurring inside the AitCS commands. For example, attempting to retrieve the value of a nonexistent element will result in a "no such element in array" error somewhere within the AitCS command.

Keywords

array, command, eagle, namespace, snake

Category

Programming tools