Re: how to create a simple closure to create validators

Liste des GroupesRevenir à cl tcl 
Sujet : Re: how to create a simple closure to create validators
De : mark (at) *nospam* qtrac.eu (Mark Summerfield)
Groupes : comp.lang.tcl
Date : 21. Jun 2024, 10:43:00
Autres entêtes
Message-ID : <RJ-dnbImWOe51uj7nZ2dnZfqnPWdnZ2d@brightview.co.uk>
References : 1 2
User-Agent : Pan/0.154 (Izium; 517acf4)
On Thu, 20 Jun 2024 11:59:38 -0700, et99 wrote:

On 6/20/2024 12:59 AM, Mark Summerfield wrote:
I can make a variable that has a specific validator quite easily using
trace add.
 
But I can't work out how to create a validator maker (i.e., a simple
closure).
 
I am using Tcl/Tk 9.0b2.
 
Here is the code:
 
#!/usr/bin/env tclsh9
 
proc valid_percent {varname elemname op} {
     upvar 1 $varname var if {$op eq "write"} {
         if {$var < 0} {
             set var 0
         } elseif {$var > 100} {
             set var 100
         }
     }
}
 
proc check {expected actual} {
     if {$expected != $actual} {
         puts "ERROR $expected != $actual"
     } else {
         puts "OK $expected == $actual"
     }
}
 
trace add variable percent write valid_percent
 
set percent 50 check 50 $percent set percent -5 check 0 $percent set
percent 492 check 100 $percent
 
# All the above works correctly; what's below fails with:
#   can't read "min": no such variable
 
proc clamper {min max} {
     proc clamp {varname elemname op} {
         upvar 1 $varname var if {$op eq "write"} {
             if {$var < $min} {
                 set var $min
             } elseif {$var > $max} {
                 set var $max
             }
         }
     }
     return clamp
}
 
trace add variable score write [clamper 0 20]
 
set score 15 check 15 $score set score -5 check 0 $score set score 25
check 20 $score
 
 
Here's how I might do this:
 
 
proc validateRange {min max name1 name2 op} {
     if { $name2 eq "" } { ;# scalar
         upvar 1 $name1 newValue if { $newValue < $min } {
             set newValue $min
         } elseif { $newValue > $max } {
             set newValue $max
         }
     } else { ;# array - left as exercise for reader
        
     }
}
 
trace add variable my_percent write {validateRange 0 20 }
 
set my_percent 10 puts "my_percent= |$my_percent| was 10"
set my_percent 50 puts "my_percent= |$my_percent| was 50"
set my_percent -50 puts "my_percent= |$my_percent| was -50"
 
 
trace add variable my_percent100 write {validateRange 5 100 }
 
set my_percent100 10 puts "my_percent100= |$my_percent100| was 10"
set my_percent100 500 puts "my_percent100= |$my_percent100| was 500"
set my_percent100 -50 puts "my_percent100= |$my_percent100| was -50"
 
output:
 
my_percent= |10| was 10 my_percent= |20| was 50 my_percent= |0| was -50
my_percent100= |10| was 10 my_percent100= |100| was 500 my_percent100=
|5| was -50

Ah, get that, v. clever. In the end I used this simple variation:

proc clamp {min max varname elemname op} {
    upvar 1 $varname var
    if {$op eq "write"} {
        if {$var < $min} {
            set var $min
        } elseif {$var > $max} {
            set var $max
        }
    }
}

trace add variable score write {clamp 0 20}


Thank you.

Date Sujet#  Auteur
20 Jun 24 * how to create a simple closure to create validators4Mark Summerfield
20 Jun 24 +* Re: how to create a simple closure to create validators2et99
21 Jun 24 i`- Re: how to create a simple closure to create validators1Mark Summerfield
20 Jun 24 `- Re: how to create a simple closure to create validators1Joerg Mertens

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal