Forum OpenACS Development: 'in' operator in if tag seems messed up.

Casual usage of something like:

<if @value@ in true false maybe> 
would lead one to believe that @value@ should be one of 'true', 'false' or 'maybe', i.e. in a list. Actually this does work, because the code generated is:
[regexp true|false|maybe @value@]

However, it doesn't work in all cases, for instance: 'truemaybe' matches.

Another problem is that you could not setup the list in your tcl file [list true false maybe].

In this case the code generates the following regexp:

[regexp "true false maybe" @value@]

I tried several things and the one that works the way I thought it should work produces:

[expr [lsearch "true false maybe" @value@] + 1]

I have more info and tests setup here.

Replacing the code with this version could break existing code that rely on the regexp implimentation.

Collapse
Posted by Dan Wickstrom on
The regexp is fixable by using word anchors '\b', and such a fix is backward compatible with usage based on the regexps.
Collapse
Posted by Tom Jackson on

How do you construct the regexp using the word anchors? the current code for in is:

    in { 
      set expr [join [lrange $args $i end] "|"]
      append condition "\[regexp \"$expr\" $arg1\] " 
      set next [llength $args]
    }

The 'inlist' addition uses the following:

    inlist { 
      set expr [lrange $args $i end]
      append condition "\[expr \[lsearch \"$expr\" $arg1\] + 1] " 
      set next [llength $args]
    }

inlist works even when you construct the list in tcl, will your regexp work in that situation? Should inlist be added for future use?

Collapse
Posted by Dan Wickstrom on
Sorry about that, I confused perl's re flavor with tcl's. For tcl you need to use \m and \M. Something like the following should work:

in { 
    set expr "\\m([join [lrange $args $i end] "|"]\\M"
    append condition "\[regexp \"$expr\" $arg1\] " 
    set next [llength $args]
}

Collapse
Posted by Dan Wickstrom on
There should have been a close parenthesis:

set expr "\\m([join [lrange $args $i end] "|"])\\M"

Collapse
Posted by Tom Jackson on

Thanks Dan, that cured some ills, but it doesn't work for lists that contain multi-word elements:

[list ab cd ef gh ij "a b"]

I changed my inreg code to use your regexp. Take a look at the results for "a b"

Collapse
Posted by Dan Wickstrom on
You need to escape the whitespace in the regexp:

set expr [string map {{ } \\s} "\\m([join [lrange $args $i end] "|"]\\M"]