On Friday, July 29, 2022 at 1:01:01 PM UTC+2, Alan Grunwald wrote:
> May I take some hope from the fact that the resolution is "Wont fix"
> rather than something like "Not a bug"?
>
> For my money the solution would be for [dict exists] to throw an error
> and there to be a [string is dict] command, as suggested by mistachkin
> on 2012-12-27 in a comment on the ticket.
>
> FWIW I also agree completely with Donal that thrashing backward and
> forward is unhelpful.
Let me second all that. Throwing an error for invalid data is consistent.
Imho,
https://core.tcl-lang.org/tcl/info/3475264 should have been a TIP (and should probably have been declined).
"[...] sort out between yourselves what it should be and I'll willingly make it work that way if it doesn't already. Until then, this issue stays closed."
Independent reporters found this regression in 2012, 2018, and 2022 along with many supporters and hardly anyone opposing; is this representative?
Without any hidden meaning: what is the expected process (medium and decision criteria) to continue?
> > On 7/29/2022 3:07 AM, Alan Grunwald wrote:
> >> I've spent several not-so-happy hours today searching for a bug caused
> >> by someone doing
> >>
> >> [dict exists foo garp]
> >>
> >> instead of
> >>
> >> [dict exists $foo garp]
> >>
We have very basic code checkers in place to fail fast. "Basic" refers to "not a full Tcl parser". I cannot paste the full file, but basically I am using regular expressions with sed.
...
# regexp of suspicious code
# \x24 ... $ (prevent a match in this file known_pitfalls.tcl)
# \x61 ... a (prevent a match in this file known_pitfalls.tcl)
# \< ... beginning of a word
# \> ... end of a word
set forbidden {
# for variable names true and false use ${true} and ${false} respectively
{\x24false\>\|\x24true\>}
# use return "result" if you really mean it
{\<return \+result\>}
# very common spelling mistakes
{\<\x61dress\>}
{\<\(Res\|res\|S\|s\)etted\>}
# string's subcommand concat does not exist in Tcl, was string cat intended?
{\<string \+concat }
# these procedures use variable names (override with ${name})
{\<dict \+\(set\|incr\|append\|lappend\|unset\|update\|with\) \+\$\(\w\|:\)\+}
{\<\(set\|incr\|append\|lappend\|unset\|vwait\|lset\|info \+exists\|info \+vars\) \+\$\(\w\|:\)\+}
{::struct::set \+\(include\|exclude\|add\|subtract\) \+\$\(\w\|:\)\+}
# these procedures take values (use braces)
{\<dict \+\(get\|exists\|filter\|info\|keys\|merge\|remove\|replace\|size\|values\) \+[^\$\{\[ ][^ ]*}
{\<\(lreplace\|lassign\|lindex\|linsert\|llength\|lrange\|lreplace\|lreverse\) \+[^\$\{\[ ][^ ]*}
{::struct::set \+\(empty\|size\|contains\|union\|difference\|symdiff\|intersect3\) \+[^\$\{\[ ][^ ]*}
# always use the optional argument level, default is 1
{\<up\(var\|level\) \+[^$#0-9\\]}
}
...
# erase commented lines in data
set forbidden [join [regsub -all -line {^\s*#.*$} $forbidden {}] {\|}]
set deprecated [join [regsub -all -line {^\s*#.*$} $deprecated {}] {\|}]
set sed [format {
# find suspicious code in single line
s/^ *\([0-9]\+\)\t.*\(%s\).*$/\1: suspicious looking code {\2}/p;t
# if not suspicious, check for deprecated procs
s/^ *\([0-9]\+\)\t\(\|.*;\|.*\[\|.*%s\) *\(%s\) .*$/\1: DEPRECATED proc {\3}/p;t
# if not deprecated, check with the previous line (in hold buffer)
H;x
# indentation when closing nested blocks
s/^ *\([0-9]\+\)\t\( *\}\)\n *\([0-9]\+\)\t\2/\1-\3: suspicious looking code {equal indentation at end of block}/p;t
} $forbidden \{ $deprecated]
...
# - print line numbers
set result [split [exec cat -n $argv | sed -n $sed] \n]
...
Maybe that helps someone :-)