I understand your desire to avoid passing in the actual scope structure that you want to cache to, but your alternatives are limited. The first thing that comes to mind is just passing the name (a string) of the scope you want your cache stored in, and evaluating. By its nature, evaluation is inefficient and should be avoided. That said, I was curious how it might be accomplished. I don't have your code so I just made a dirt-simple "storage" abstraction CFC (skipped caching, as it's irrelevant to what I want to test) here:
cache.cfc:
<cfcomponent>
<cfset variables.cacheScope = "session" /><!--- default to session --->
<cfset variables.cache = ""/>
<cfscript>
function init(scope){
variables.cacheScope = arguments.scope;
return this;
}
function cacheWrite(key, value){
structInsert(evaluate(variables.cacheScope),arguments.key,arguments.value,true);
return this;
}
function cacheRead(key){
if (not structKeyExists(evaluate(variables.cacheScope), arguments.key)){
return "";
}else{
variables.cache = evaluate(variables.cacheScope);
return variables.cache[arguments.key];
}
}
</cfscript>
</cfcomponent>
And a view to test it:
<!--- clear out any existing session vars --->
<cfset structClear(session)/>
<!--- show empty session struct --->
<cfdump var="#session#" label="session vars">
<!--- create storage object --->
<cfset cacher = createObject("component", "cache").init("session")/>
<!--- store a value --->
<cfset cacher.cacheWrite("foo", "bar")/>
<!--- read stored value --->
<cfset rtn = cacher.cacheRead("foo")/>
<!--- show values --->
<cfdump var="#rtn#">
<cfdump var="#session#" label="session vars">
Off topic: I like to write my setter functions to return "this" [as seen above] so that I can chain method calls like jQuery. Part of the view could just as easily been written as:
<cfset rtn = createObject("component", "cache")
.init("session")
.cacheWrite("foo", "bar")
.cacheRead("foo")/>
It's interesting that this is possible, but I probably wouldn't use it in production due to the overhead cost of Evaluate. I'd say that this is valid enough reason to pass in the scope you want to cache into.
If you're still bothered by it (and maybe rightly so?), you could create another CFC that abstracts reading and writing from the desired scope and pass that into your caching CFC as the storage location (a task well-suited for ColdSpring), that way if you ever decide to move the cache into another scope, you don't have to edit 300 pages all using your cache CFC passing in "session" to init, and instead you can edit 1 CFC or your ColdSpring config.
I'm not entirely sure why you would want to have single-request caching though, when you have the request scope. If what you're looking for is a way to cache something for the current request and have it die shortly afterward, request scope may be what you want. Caching is usually more valuable when it spans multiple requests.