Bug reported https://bugbase.adobe.com/index.cfm?event=bug&id=3120695
So I was playing with Coldfusion 10 Beta and was trying to do some of the things I am used to in Javascript. When I came upon this issue.
<cfscript>
test={
one="1"
, two=function(){ return "2" }
};
</cfscript>
<cfoutput>#test.two()#</cfoutput>
Error
Invalid CFML construct found on line 2 at column 6
ColdFusion was looking at the following text:
{
. . . blah blah blah
What I would expect is to get the number two written to the page, but apparently you cannot define the function inline. But you can predefine the function.
<cfscript>
two=function(){ return "2"; };
test={
one="1"
, two=two
};
</cfscript>
<cfoutput>#test.two()#</cfoutput>
In a hacky workaround, you can create a function which returns a function expression.
<cfscript>
func=function(f){ return f; };
test={
one="1"
, two=func(function(){ return "2"; })
};
</cfscript>
<cfoutput>#test.two()#</cfoutput>
Similarly I also was not able to call the this scope inside a passed in function expression using the invoke command.
Bug reported https://bugbase.adobe.com/index.cfm?event=bug&id=3120773
Test.cfc
component {
instance.options={};
function init(options) {
StructAppend(instance.options, options, false);
return this;
}
function call(option, args={}) {
return invoke(instance.options, option, args);
}
}
Test.cfm (Works)
<cfscript>
two=function(){ return arguments; };
test=new Test({
one="1"
, two=two
});
</cfscript>
<cfdump var="#test.call("two", {three=3})#" />
Test.cfm (Works)
<cfscript>
two=function(){ return this; };
test=new Test({
one="1"
, two=two
});
test.two=two;
</cfscript>
<cfdump var="#test.two()#" />
Test.cfm (Doesn’t Works)
<cfscript>
two=function(){ return this; };
test=new Test({
one="1"
, two=two
});
</cfscript>
<cfdump var="#test.call("two", {three=3})#" />
Error
Variable THIS is undefined
Thanks to Ben Nadel’s well timed post for helping me understand more about this.
http://www.bennadel.com/blog/2334-ColdFusion-10-Beta-Closures-And-Components-And-The-THIS-Scope.htm
And to Raymond Camden for pointing me to it and encouraging me to post bug reports.
If I have made an error here could anyone please correct me?
Ben Nadel hits the same thing today in his blog.
http://www.bennadel.com/blog/2334-ColdFusion-10-Beta-Closures-And-Components-And-The-THIS-Scope.htm
Might explain why the this scope is acting the way you describe.
Actually, it is the opposite. He did show though that it was not the bug I thought it was, I have made an edit, essentially it is using invoke that seems to make the this scope not bind correctly.
It would be cool to have the call() and apply() methods from JavaScript! This way, we don’t have to treat method names as strings.
Indeed, and since I needed a refresher on call/apply I’m going to link to this article so anyone else can see why you are totally right.
http://odetocode.com/blogs/scott/archive/2007/07/05/function-apply-and-function-call-in-javascript.aspx
w.r.t 3120773, the error message ‘Variable THIS is undefined’ is shown because the calling page doesn’t have this scope available i.e. this scope is not available in the invoking cfm file. However, if you invoke the same from a function defined in cfc then it would work.
arguments scope is always created in a function call and hence it wouldn’t complain.
after assignment test.two to a closure function it is available in the variables scope and hence can be called.
let me know your thoughts.
No, it also works if I append the options to the this scope, like so
function init(options) { StructAppend(this, options, false); return this; }And then call this.two(), leaving out the test.two=two part of the code.
So I can only conclude that it is the invoke method not injecting the this scope into the closure.