Convenient list arguments - larg

jcw 2011-01-30

Here is a utility function which makes it possible to replace this type of multi-line construct:

set value [list \
    abc $myvar {$1 per day} \
    def [bleep "x y z"] ghi \
    "some text with expansion of $var and [my code] inside" \
]

with:

set value [larg {
    # this is an example
    abc $myvar {$1 per day}
    def [bleep "x y z"] ghi
    # comments lines starting with # will be stripped
    "some text with expansion of $var and [my code] inside"
}]

It avoids having to escape each newline, and allows command-like comments inside.

Other uses:

foreach x [larg { ... }] { ... }
dict merge $dict [larg { ... }]
myproc arg1 arg2 {*}[larg { ... }]

Implementation

The definition of larg is:

proc ::larg list {
    # Returns list, with each list item evaluated and comment lines removed.
    regsub -line -all {^\s*#.*$} $list {} list ;# same as Ju unComment
    # The trick is to allow newlines between list items, but this only works
    # when embedded newlines in any of the arguments are replaced with \n's.
    uplevel "list [string map {\n { }} $list]"
}

Discussion

aspect 2014-07-05: Scripted List presents a very similar idea.

PYK 2016-02-11: ::larg doesn't properly parse all Tcl scripts. For example, A a # after a newline in braces or quotes would throw it off. Scripted List presents a correct approach to this task.