Sujet : Re: The "leading zero means octal" thing...
De : rich (at) *nospam* example.invalid (Rich)
Groupes : comp.lang.tclDate : 05. Jan 2025, 22:04:46
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vles5e$16v92$1@dont-email.me>
References : 1 2
User-Agent : tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Luc <
luc@sep.invalid> wrote:
I updated my 'seq' code because of this thread:
https://wiki.tcl-lang.org/page/seq
And, line one of the proc contains the common Tcl bug of "applying a
string operator" to a tcl list.
Note this:
$ rlwrap tclsh
% proc p {args} { set args [string trimleft $args 0] ; return $args }
% p 08
8
% p 08 08
8 08
% p #08 08
{#08} 08
% p 08 0a "one two three"
8 0a {one two three}
The 'args' special variable to a proc is provided to the proc as a
"list".
'string trimleft' is a string operator (not a list operator). So when
'string trimleft' is applied to a list, Tcl first converts the list
into a string, the operates on the string, which will likely not
produce the expected result.
Note the second 'test' above, where 08 08 was passed to p. Because
args was converted to a string, only the initial leading zero was
removed. However it is likely that the intent was to convert 08 08
into 8 and 8. But 'string trimleft' does not work on individual list
elements, it only knows strings, and after [list 08 08] is converted to
a string, string trimleft sees "08 08" and only removes the first 0.
Next, note the third test, where #08 was passed in. It is unlikely the
intent was for #08 to become {#08} (the added {}'s are from Tcl's list
to string conversion).
Note as well the fourth test. "one two three" was changed to {one two
three}. Also not likely the intended outcome.
What this proc likely wanted was to iterate over each element in the
args list, and remove leading zeros from each element, i.e.:
proc p2 {args} { set args [lmap x $args {string trimleft $x 0}] ; return $args }
Which does the right thing for plural leading zero arguments:
% p2 08
8
% p2 08 08
8 8
% p2 08 08 08
8 8 8
Note, because the CLI does a list to string conversion when printing
the return value, we can still get 'weird characters' when showing a
demo:
% p2 #08 08 08 "this or that"
{#08} 8 8 {this or that}
But a simple tweak will show the internal contents of the list without
the extra 'stringification':
% join [p2 #08 08 08 "this or that"] |
#08|8|8|this or that