2

How to I construct a huddle structure, in a way that huddle strip generates {a {b}} {c {d}}?

For example

#create as a dict
% set bb [huddle create a b c d]
HUDDLE {D {a {s b} c {s d}}}

#create as a list
% set cc [huddle list e f g h]
HUDDLE {L {{s e} {s f} {s g} {s h}}}

% set bbcc [huddle create bb $bb cc $cc]
HUDDLE {D {bb {D {a {s b} c {s d}}} cc {L {{s e} {s f} {s g} {s h}}}}}

% set folding [huddle list $bbcc p [huddle list q r] s]
HUDDLE {L {{D {bb {D {a {s b} c {s d}}} cc {L {{s e} {s f} {s g} {s h}}}}} {s p} {L {{s q} {s r}}} {s s}}}

#normal Tcl's notation
% huddle strip $folding
{bb {a b c d} cc {e f g h}} p {q r} s

(see http://tcllib.sourceforge.net/doc/huddle.html)

Johannes Kuhn
  • 14,778
  • 4
  • 49
  • 73

2 Answers2

1

Huddle is a way of encoding Tcl values with structure annotations; it's conceptually similar to JSON and YAML, but different in detail.

The major issue you face is that a {b} is not a canonical list or dictionary (though it is indeed both a valid list and a valid dictionary). That is, you'll never get it as a result from list or dict create (or any of the other structured-value-synthesising commands). To get it, you'll have to make the value more directly:

set val [format "%s {%s}" a b]

Once you've got the value, putting it in a Huddle list will encapsulate it just fine:

set hud [huddle list [format "%s {%s}" a b] [format "%s {%s}" c d]]

And then you can strip it to get the value you want:

puts [huddle strip $hud]
#==> {a {b}} {c {d}}

Advanced Construction

Forcing the addition of the braces when you don't “need” them is quite tricky if you want Tcl to otherwise do things right. The simplest (raw) mechanism is this:

if {[list $val] eq $val} {format "{%s}" $val} {list $val}

You need to do it like this because otherwise you'll go thoroughly wrong on values which are not barewords. (This is particularly true if you've got unbalanced braces in the value; in that case, the results are ugly due to the addition of backslashes but they work.)

With that, we can then construct the value to use in Huddle like this:

proc braceitem val {
    if {[list $val] eq $val} {format "{%s}" $val} {list $val}
}
set val [concat [list a] [braceitem b]]

Most Tcl programmers don't do this. It's a lot of work and the code is a lot more verbose. It's also more error-prone than just using list (or dict create) and accepting formatting it uses by default.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • 1
    Because the values aren't canonical, huddle will package them as plain strings. You shouldn't care about this detail. – Donal Fellows Nov 29 '13 at 09:43
0

use huddle wrap TYPE VALUE :)

% set abcd {{a {b}} {c {d}}}
{a {b}} {c {d}}
% set hud [huddle wrap s $abcd]
HUDDLE {s {{a {b}} {c {d}}}}
% huddle strip $hud
{a {b}} {c {d}}

huddle wrap is an API, which generate a tagged value specialized by TAG(e.g. 's', 'L' or 'D')