- namespace code script
From the Tcl chatroom on 2004-11-03:dkf: You can probably hack something like autoexpansion with the help of namespace code
In [1], DGP has this to say about the "crazy aunt":
When using namespace code to reference a namespace local function, one may use concat to add parameter values from the current scope. If the reference gets any parameters, they are added after this parameter:
proc lambdaish args {uplevel 1 [list ::namespace code $args]}
% [lambdaish format %.3f] [expr {atan2(0,-1)}]
3.142suchenwi: Cool, Donal! It's not exactly lambdaish, as it doesn't take a parameter list... which is half a lambda. Why not just call it "curry"? % [curry format %.3f] [expr {atan2(0,-1)}]
3.142Somehow makes more sense to me...dkf: Pop that on the wiki. It also should work with any version of Tcl from 8.0 onwards.jenglish: the 'namespace code' trick, alas, is not cool at all -- it relies on an undocumented, hairy, and almost-certainly-incorrect misfeature of unknown.dkf: It's an intended feature of unknown. It's a crazy aunt and not just a bug. There's too much code enforcing it in namespace.test for me to believe it to be anything other than intended. namespace code is just a constructor for namespace inscopeIn [1], DGP has this to say about the "crazy aunt":
- That code in unknown is a workaround for alleged brokenness in Itcl. No correctly written code should ever end up there.
- If you do end up there, your program is probably missing an {*} or an eval where one is needed. Correct that.
- The only fix I plan to ever make to that bit of code is its removal.
When using namespace code to reference a namespace local function, one may use concat to add parameter values from the current scope. If the reference gets any parameters, they are added after this parameter:
namespace eval mynamespace {
namespace export getreference
proc callback {fix variable} {
puts "Called with: <$fix> <$variable>"
}
proc getreference {fix} {
return [concat [namespace code callback] [list $fix]]
}
}
namespace import mynamespace::*
set Ref [getreference "fix value"]
--> ::namespace inscope ::mynamespace callback {fix value}
eval $Ref {"variable value"}
--> Called with: <fix value> <variable value>
eval $Ref {"another value"}
--> Called with: <fix value> <another value>The same result may be acheved by using only list (only differences to the upper example shown). The first argument is now within the command list which works too:...
proc getreference {fix} {
return [namespace code [list callback $fix]]
}
...
set Ref [getreference "fix value"]
--> ::namespace inscope ::mynamespace {callback {fix value}}
...or the tcl 8.5 delist operator and list:...
proc getreference {fix} {
return [list {*}[namespace code callback] $fix]
}
...
set Ref [getreference "fix value"]
--> ::namespace inscope ::mynamespace callback {fix value}
...