Tcl Library Source Code

dicttool - Extensions to the standard "dict" command
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2018 Conference, Houston/TX, US, Oct 15-19
Send your abstracts to tclconference@googlegroups.com
or submit via the online form by Aug 20.

[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]

dicttool(n) 1.2 tcllib "Extensions to the standard "dict" command"

Name

dicttool - Dictionary Tools

Description

The dicttool package enhances the standard dict command with several new commands. In addition, the package also defines several "creature comfort" list commands as well. Each command checks to see if a command already exists of the same name before adding itself, just in case any of these slip into the core.

Commands

proc PROC name arglist body ?ninja ?

Because many features in this package may be added as commands to future tcl cores, or be provided in binary form by packages, I need a declaritive way of saying Create this command if there isn't one already. The ninja argument is a script to execute if the command is created by this mechanism.

proc noop ?args?

Perform a noop. Useful in prototyping for commenting out blocks of code without actually having to comment them out. It also makes a handy default for method delegation if a delegate has not been assigned yet.

proc putb ?map? text

Append a line of text to a variable. Optionally apply a string mapping.

proc tcl::dict::getnull dictionary ?element? ?element...?

If the path (given by the list of elements) exists, return that value. Otherwise return an empty string. Designed to replace

 if {[dict exists $dictionary {*}$args]} {
   return [dict get $dictionary {*}$args]
 } else {
   return {}
 }
 

Example:

 set value [dict getnull $arglist $option]
proc tcl::dict::is_dict d

Test if value is a dict.

This command is added to the dict ensemble as dict is_dict

proc dicttool::is_branch dict path

Return true if the element with the value is a dict. is given as a list to descend into sub-dicts of the current dict. The rules are as follows:

  1. If the last character of the last element of is a colon (:) return false

  2. If the last character of the last element of is a slash (/) return true

  3. If a sub-element if named .info is present return true

This command is added to the dict ensemble as dicttool::is_branch

Example:

 > set mydict {sub/ {sub/ {field {A block of text}}}
 > dicttool::is_branch $mydict sub/
 1
 > dicttool::is_branch $mydict {sub/ sub/}
 1
 > dicttool::is_branch $mydict {sub/ sub/ field}
 0
proc dicttool::print dict

Output a dictionary as an indented stream of data suitable for output to the screen. The system uses the rules for dicttool::is_branch to determine if an value in a dictionary is a leaf or a branch.

Example:

 > set mydict {sub/ {sub/ {field {A block of text}}}
 > dicttool::print $mydict
 sub/ {
   sub/ {
     field {A block of text}
   }
 }
proc dicttool::_dictputb level varname dict

Helper function for ::dicttool::print Formats the string representation for a dictionary element within a human readable stream of lines, and determines if it needs to call itself with further indentation to express a sub-branch

proc dicttool::sanitize dict

Output a dictionary removing any . entries added by dicttool::merge

proc dicttool::_sanitizeb path varname dict

Helper function for ::dicttool::sanitize Formats the string representation for a dictionary element within a human readable stream of lines, and determines if it needs to call itself with further indentation to express a sub-branch

proc dicttool::canonical rawpath

Return the path as a canonical path for dicttool with all branch keys ending in a / and the final element ending in a / if the final element in the path ended in a / This command will also break arguments up if they contain /.

Example:

 > dicttool::canonical foo bar baz bang
 foo/ bar/ baz/ bang
 > dicttool::canonical foo bar baz bang/
 foo/ bar/ baz/ bang/
 > dicttool::canonical foo bar baz bang:
 foo/ bar/ baz/ bang
 > dicttool::canonical foo/bar/baz bang:
 foo/ bar/ baz/ bang
 > dicttool::canonical foo/bar/baz/bang
 foo/ bar/ baz/ bang
proc dicttool::storage rawpath

Return the path as a storage path for dicttool with all branch terminators removed. This command will also break arguments up if they contain /.

Example:

 > dicttool::storage foo bar baz bang
 foo bar baz bang
 > dicttool::storage foo bar baz bang/
 foo bar baz bang
 > dicttool::storage foo bar baz bang:
 foo bar baz bang
 > dicttool::storage foo/bar/baz bang:
 foo bar baz bang
 > dicttool::storage foo/bar/baz/bang
 foo bar baz bang
proc dicttool::dictset varname ?args?

Set an element with a recursive dictionary, marking all branches on the way down to the final element. If the value does not exists in the nested dictionary it is added as a leaf. If the value already exists as a branch the value given is merged if the value is a valid dict. If the incoming value is not a valid dict, the value overrides the value stored, and the value is treated as a leaf from then on.

Example:

 > set r {}
 > ::dicttool::dictset r option color default Green
 . 1 option {. 1 color {. 1 default Green}}
 > ::dicttool::dictset r option {Something not dictlike}
 . 1 option {Something not dictlike}
 # Note that if the value is not a dict, and you try to force it to be
 # an error with be thrown on the merge
 > ::dicttool::dictset r option color default Blue
 missing value to go with key
proc dicttool::dictmerge varname ?args?

A recursive form of dict merge, intended for modifying variables in place.

Example:

 > set mydict {sub/ {sub/ {description {a block of text}}}}
 > ::dicttool::dictmerge mydict {sub/ {sub/ {field {another block of text}}}}]
 > dicttool::print $mydict
 sub/ {
   sub/ {
     description {a block of text}
     field {another block of text}
   }
 }
proc dicttool::merge ?args?

A recursive form of dict merge

A routine to recursively dig through dicts and merge adapted from http://stevehavelka.com/tcl-dict-operation-nested-merge/

Example:

 > set mydict {sub/ {sub/ {description {a block of text}}}}
 > set odict [dicttool::merge $mydict {sub/ {sub/ {field {another block of text}}}}]
 > dicttool::print $odict
 sub/ {
   sub/ {
     description {a block of text}
     field {another block of text}
   }
 }
proc tcl::dict::isnull dictionary ?args?

Returns true if the path specified by args either does not exist, if exists and contains an empty string or the value of NULL or null.

This function is added to the global dict ensemble as dict isnull

proc ladd varname ?element? ?element...?

Add elements to a list if that are not already present in the list. As a side effect, if variable does not exists, create it as an empty list.

Example:

 ladd contents foo bar
 puts $contents
 > foo bar
 ladd contents foo bar baz bang
 puts $contents
 > foo bar baz bang
proc ldelete varname ?element? ?element...?

Delete all instances of the elements given from a list contained in . If the variable does exist this is a noop.

Example:

 set contents {foo bar baz bang foo foo foo}
 ldelete contents foo
 puts $contents
 > bar baz bang
proc lrandom list

Return a random element from

Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and other problems. Please report such in the category dict of the Tcllib Trackers. Please also report any ideas for enhancements you may have for either package and/or documentation.

When proposing code changes, please provide unified diffs, i.e the output of diff -u.

Note further that attachments are strongly preferred over inlined patches. Attachments can be made by going to the Edit form of the ticket immediately after its creation, and then using the left-most button in the secondary navigation bar.

Category

Utilities