I'm a This-Scoping Fool
Hey, ColdFusion experts! Remember when you said "Just don't use the This scope in CFC's."?
And then I said "No, I can totally use it."
And then you said "No, you totally can't"
And then I was all like "I totally can!"
Yeah?
Well I was totally wrong.
(In case your wondering this conversation happened entirely in my head.)
We were having a weird issue with one of applications. It uses cookie based authentication that was written centrally into a cfc, and every once in awhile users were getting someone else information. We couldn't track it down. The CFC was all properly var scoped. However it turns out that it was using the This scope to return the results of each function. The CFC was instantiated in the application scope of the calling application. So things like this were happening:
- User 1 authenticates.
- Application.Obj.username is set to User1
- User2 authenticates
- Application.Obj.username is set to User2
- User1 sets session.username to Application.Obj.username
- User2 sets session.username to Application.Obj.username
- Both are User2 in their session
This is dumb stuff from me. At the time I wrote it, like a year and a half ago, I assumed no one would instantiate the CFC to the application scope. But now time has proven me wrong. It just goes to show, that no matter how small your application is, or how narrowly you think it is going to be used, always follow best practices, unless you have a specific reason not to do so. If I had just set the proper response to be returned from the function instead of in the this scope, I wouldn't be rewriting code, and trying not to break existing calls to this central CFC in 20 or so applications by 10 or so different developers.
Comments
Well I chalk it up to the this scope as I had var scoped all of the other variables, and thought I had made it thread safe. The bigger point there might be "There's more to thread safe CFC's then just the var scope." 


When you use shared-scope objects, you must ensure that the only instance-level state is request-agnostic. If that's impossible, you need to use a request-aware scope to house the data a la a java.lang.ThreadLocal. Fortunately (or unfortunately) CF has that built-in with the request scope, which you can use from anywhere. Just be aware of what you're doing and clearly document the dependancy.
Posted by: Barney at November 9, 2006 4:19 PM