Version 1 of dict object in oo

Updated 2021-09-10 22:05:21 by xk2600

Put this to together purely for some fun object based sugar around the builtin dict.

% set d [::oo::Dict new] ;# create a new Dict object
::oo::Obj29

% $d set a 1 b 4 c 3         ;# set some key values
a 1 b 4 c 3

% $d set b 2                 ;# modify a value
a 1 b 2 c 3

% $d                         ;# print the dict
a 1 b 2 c 3

% $d a                       ;# lookup a key
1

Note how this object just has methods for all of the original dict subcommands.

% info class methods ::oo::Dict
merge exists append size info with set remove map constructor unset values get unknown update replace keys incr lappend filter for


And the implementation:

oo::class create ::oo::Dict { 

  #TODO: Add abililty to detect child dictionaries and return a dictionary
  #      possibly in `$dict get ...` method.
                                                                                                                                                                                          
  variable dict

  method constructor {dictionaryValue} {
    my variable dict
    set dict [::tcl::dict::create]
  }

  # add some sugar to allow:
  #   [$dict] and [$dict key ?...key?] to translate to [$dict get ...]
  method unknown {args} {
    my variable dict
    if {[llength $args] == 0} { return $dict }

    if {[lindex $args 0] in $dict} {
      return [::tcl::dict::get $dict {*}$args]
    }
    next {*}$args
  }

  ############ Generic Methods

  method dictionaryVariable {command args} {
    my variable dict
    set dictVar dict
    return [::tcl::dict::$command $dictVar {*}$args]
  }
  unexport dictionaryVariable

  method dictionaryValue {command args} {
    my variable dict
    return [::tcl::dict::$command $dict {*}$args]
  }
  unexport dictionaryValue

  method dictionaryIterator {keyValueVarTuple command args} {
    tailcall ::tcl::dict::$command $keyValueVarTuple [self object]::dict {*}$args
  }
  unexport dictionaryIterator

  method dictionary {command args} {
    set cls [info object class [self object]]
    return [$cls new [::tcl::dict::$command {*}$args]]
  }
  unexport dictionary

  #   dictionaryVariable: 
  #
  #     Represents an interaction where the commands modify the dictionary in
  #     place. There is no return, as the object contains the state.
  #
  #   dictionaryValue:
  #
  #     Represents an interaction where the commands return a component from
  #     the dictionary which is not a dictionary itself. These are always
  #     actual values.
  #
  #   dictionaryIterator:
  #
  #     Represents an idempwtent dictionary at the point of execution, allowing
  #     iteration over the dictionary. **NOT FULLY TESTED/IMPLEMENTED**
  #
  #   dictionary:
  #
  #     Represents an interaction where the commands return a new dictionary,
  #     either because its a subset of the parent dictionary, or the resultant
  #     contents could represent a dict.

  ############ Manipulates dictionary in place
  #
  forward append  my dictionaryVariable append
  forward incr    my dictionaryVariable incr
  forward lappend my dictionaryVariable lappend
  forward set     my dictionaryVariable set
  forward unset   my dictionaryVariable unset
  forward update  my dictionaryVariable update
  forward with    my dictionaryVariable with


  ############ Returns non-dictionary
  #
  forward get     my dictionaryValue get
  forward exists  my dictionaryValue exists
  forward filter  my dictionaryValue filter
  forward info    my dictionaryValue info
  forward keys    my dictionaryValue keys
  forward size    my dictionaryValue size

  # syntax prefixes command with {keyVariable and valueVariable} tupple
  forward for     my dictionaryIterator for
  forward map     my dictionaryIterator map


  ############ Returns dictionary
  #
  forward merge   my dictionary merge
  forward remove  my dictionary remove
  forward replace my dictionary replace
                                                                                                                                                                                          
  # returns a list of possible dictionaries.
  method values {args} {
    my variable dict
    set resultList [list]
    foreach dictionaryValue [::tcl::dict::values $dict {*}$args] {
      lappend resultList $resultList
    }
    return $resultList
  }
}