Go to the first, previous, next, last section, table of contents.


Indices

Hashes are one of the most common and useful MUF datastructures: They are comparable to Perl's hashes. A MUF hash maps arbitrary keys to values. Internally it is organized as a hashed b-tree, so it can efficiently handle half a dozen keys or half a million keys.

Use makeHash to create a hash:

root:
makeHash --> phone
root:
phone
root: #<Hash _ 4e9c915>

We normally use bracket notation to add and retrieve values from a hash:

root:
"234-5555" --> phone["pat"]
root:
"324-6666" --> phone["kim"]
root:
phone["pat"]
root: "234-5555"
pop phone["kim"]
root: "324-6666"

If you want to check for the presence or absence of a key without risking an error condition, use the get? primitive. The top return value is the stored value, if any, and the bottom return value is a t/nil flag indicating whether the key was found:

root:
phone["sam"]
Sorry: No such property: "sam"
root: 
phone "sam" get?
root: nil nil
pop pop
root:
phone "kim" get?
root: t "324-6666"

Use ls to list the contents of an hash:

root:
phone ls
"kim"	"324-6666"
"pat"	"234-5555"
root:

Use foreach to iterate over the contents of a hash:

root:
phone foreach key do{ key , "\n" , }
kim
pat
root: 
phone foreach key val do{ key , " " , val , "\n" , }
kim 324-6666
pat 234-5555
root: 

By default, values in a hash are visible to anyone who can access the hash. You may also store hidden values on a hash, in a space separate from the public one:

root:
"666-6666" --> phone$hidden["nsa"]
root:
"777-7777" --> phone$hidden["cia"]
root:
phone$hidden["nsa"]
root: "666-6666"
pop phone$hidden["cia"]
root: "777-7777"

Use lsh to list hidden properties:

root:
phone lsh
"cia"	"777-7777"
"nsa"	"666-6666"
root: 

Use foreachHidden to iterate over the hidden contents of an hash:

phone foreachHidden key val do{ key , " " , val , "\n" , }
cia 777-7777
nsa 666-6666
root: 

Use delete: to remove values from an hash:

root:
phone lsh
"cia"	"777-7777"
"nsa"	"666-6666"
root: 
delete: phone$hidden["cia"]
root: 
phone lsh
"nsa"	"666-6666"
root: 
phone ls
"kim"	"324-6666"
"pat"	"234-5555"
root: 
delete: phone["kim"]
root: 
phone ls
"pat"	"234-5555"
root:

In addition to the public and private values on a hash, each hash has system values which are visible to the owner but are (often) settable only by root. Use lss to list these system values:

root:
phone lss
:dbname	"ROOTDB"
:isA	#<MosClass Object 209fa15>
:myclass	"obj"
:owner	#<Root root 2c015>
:name	"_"
root: 
me lss
:dbname	"ROOTDB"
:isA	#<MosClass Root 3a9d015>
:myclass	"rot"
:owner	#<Root root 2c015>
:hashName	1263705246727446217
:lib	#<Object .u.roo%s.lib 91e915>
:name	"root"
:ip3	82
:ip2	182
:ip1	179
:ip0	205
:breakOnSignal	0
:breakEnable	0
:breakDisable	0
:doSignal	0
:debugger	'debug:mufDebugger
:doBreak	0
:group	0
:runQueue1	#<JobQueue 1 1020215>
:runQueue0	#<JobQueue 0 20115>
:psQueue	#<JobQueue ps f20415>
:pgpKeyprint	0
:pauseQueue	#<JobQueue poz ea0515>
:objectsOwned	9660
:objectQuota	268435456
:configFns	#<Object _ 211fb0000b81de15>
:loginHints	#<Object _ 211fb0000359cc15>
:homepage	0
:haltQueue	#<JobQueue hlt e20615>
:email	0
:doing	0
:doNotDisturb	0
:defaultPackage	#<Package root 422a15>
:dbrefConvertErrors	0
:bytes-owned	20714832
:byte-quota	268435456
:packetPreprocessor	0
:dateAtWhichWeLastQueriedUserServers	0
:userServer4NeedsUpdating	0
:userServer3NeedsUpdating	0
:userServer2NeedsUpdating	0
:userServer1NeedsUpdating	0
:userServer4	0
:userServer3	0
:userServer2	0
:userServer1	0
:userServer0	1511201586247629963
:userVersion	8
:hasUnknownUserServer	0
:port	30000
:ioStream	0
:dateOfLastNameChange	0
:originalNickName	"root"
:lastSharedSecrets	nil
:lastHashName	0
:lastTrueName	nil
:lastLongName	0
:sharedSecrets	nil
:trueName	nil
:longName	21785844818505190280484762160577916926604332233153169514740797048102153525671947608990996953242732183859349004057149371159606487467804054198140106344292159054364973335175134573886793277186528940143238208826532169922986204369431519881943212123282907303118638555788690891574541957756718153188906349437557021918
:nickName	"root"
:gagged	0
:rank	100
:timeSlice	125983
:textEditor	'edit:editString
:telnetDaemon	#<c-fn start>
:shell	0
:runQueue2	#<JobQueue 2 fa0315>
:timesUsedByMuqnet	0
:lastUsedByMuqnet	0
:firstUsedByMuqnet	0
:packetPostprocessor	0
root: 

A package is implemented by a specialized hash object.

Hashes also have an administrative namespace visible and settable only by root, useful for systems programming. It uses such syntax as obj$admins.val, obj$admins["key"] lsa and foreachAdmins.

Use makeIndex to create Index objects. They have an interface identical to Hash objects, but internally the keys are stored in a sorted btree instead of a hashed btree: This saves a little space (no separate hash value to store) but slows down access and retrieval a bit (comparing keys is slower than comparing integer hash values). Indices are especially useful when you want to list keys in order for display to the user.

Almost everything in Muq is also an index. This makes it easy to hang random values off of objects without having to redefine their class every time. The User object me which represents your account on the Muq server is an object which is also an index, for example:

root:
me
root: #<Root root 2c015>
ls
:doBreak	'muf:]doBreak
:www	0
root: 
12 --> me["twelve"]
root: 
me["twelve"]
root: 12
pop delete: me["twelve"]
root:
me["twelve"]
Sorry: No such property: "twelve"
root:

The backbone of the internal Muq "file system hierarchy" (actually an object graph) consists of indices of various kinds. Use a leading "." to explore it, just as you use a leading "/" to explore the Unix filesystem. Points of interest include .u (indexes local users by name), .etc (much like unix /etc), and .folkBy.nickName (lists known muqnet users by name, both local and remote).

Use makeSet to create a Set, which is like a SortedIndex whose value field is alway t -- this cuts the space needs in half:

root:
makeSet --> _x
root:
t --> _x["b"]
root:
t --> _x["c"]
root:
_x ls
"b"	t
"c"	t
root:

Here is a more compact way of creating Sets, along with an illustration of set union and intersection operations and the vals[ operator for extracting an object's set of keys as a stackblock (stackblocks will be discussed shortly):

root:
[ 'a' 'b' 'c' | ]set   [ 'b' 'c' 'd' | ]set   union   keys[
root: [ 'a' 'b' 'c' 'd' |
]pop
root:
[ 'a' 'b' 'c' | ]set   [ 'b' 'c' 'd' | ]set   intersection   keys[
root: [ 'b' 'c' |

Much the same shortcut and operations are available for Index objects:

root:
[ "a" 'a' "b" 'b' "c" 'c' | ]index   [ "b" 'b' "c" 'c' "d" 'd' | ]index   union   ls
"a"	'a'
"b"	'b'
"c"	'c'
"d"	'd'
root:
[ "a" 'a' "b" 'b' "c" 'c' | ]index   [ "b" 'b' "c" 'c' "d" 'd' | ]index   intersection   ls
"b"	'b'
"c"	'c'
root:


Go to the first, previous, next, last section, table of contents.