On Sat, 25 Dec 2004 19:39:06 -0700, Joseph Flanigan <[EMAIL PROTECTED]> wrote: > What is the problem with using CFC this. variables? Are they not thread > safe? Where does MM document they are not thread safe? Is there example > code that would cause a thread failure using this. variables?
If you store a CFC instance in a shared scope, "this" scope (and "variables" scope) variables are also effectively in that shared scope. If multiple requests call methods on that (shared) CFC and those methods update variables in "this" scope (or "variables" scope) then you will have race conditions and, unless you have written the appropriate locking, your code will not be thread safe. This is basic stuff about shared scopes - CFCs just obscure it a little because <cfset this.x = this.x + 1> doesn't look like it could be thread-unsafe. But if I wrote: <cfset application.x = application.x + 1> you certainly ought to recognize that as not being thread safe! > Yes, the getter/setter proponents seem to think a function call is better > CF and it is effective encapsulating. But for the code in me I cannot > figure out why. I'm getting a bit tired of trying to explain why :( Go read about software engineering, there's mountains of stuff out there that makes it crystal clear why encapsulation is a Good Thing(tm). It's up to you whether you want to improve your skills or not. > It just seems to me that getter/setter for individual > instance variables is a lot of extra runtime memory allocations, that in > itself can cause memory leaks or thread failures. Er, rubbish. Sorry, but that sort of comment just shows that you don't understand... well, I don't even know where to start. Sorry, but that sort of comment is just silly. *sigh* This is so frustrating... > Functions in a CFC have namespaces just like this. scope variables. Pardon? > By CF > definition, all function names are CF variable namespaces. What? Neither of those statements make any sense to me. Could you explain what you mean? > The difference > between public instance variables and private instance variables is when > memory allocation occurs, loadtime or runtime. this. scope allocations > happen at loadtime. Private variable allocation happen at runtime. No, you're wrong, absolutely wrong. "this" scope and "variables" scope are created at the same time - when a CFC instance is created (at runtime). "function local" (var) scope is created when a function is called (at runtime). > The CFC this. variables are an extremely powerful feature in a CFC. If you went round telling C#, Java and C++ developers to use public data members like that, they'd laugh in your face. > If the > application uses CFC this scope, CFC variable namespace act as a > pass-by-name reference. "this" scope has absolutely nothing to do with pass-by-ref or pass-by-value. Nor has "variables" scope. > The getter/setter functions most often use > pass-by-value for individual instance variables. Technically that's correct but not in the way you think. If you pass a simple data type, CF always copies it. If you assign a simple data type, CF always copies it. If you pass a struct or a CFC, CF passes it by reference, always, same with assignment of a struct. If you pass an array, CF always performs a shallow copy of the array, same with assignment of an array. The argument passing rules and the assignment rules are identical. > Whereas by using the CFC > this. scope and simple expression statements, variable assignments conserve > memory allocations because the CFC variable space is a CF data structure. If you're arguing that obj.x = 42; is a bit more efficient than obj.setX(42); then I'll agree but you seem to be saying it in a very strange way. And that level of efficiency certainly does not outweigh basic software engineering principles like encapsulation. > (Note. Memory allocation is a runtime compiler function not memory use nor > memory availability.) "runtime compiler" is an oxymoron - something is either compile-time or run-time. > The good old equal sign in a statement is really a built-in function that > is an elegant "setter". ...that has no data validation and provides no way to ensure the integrity of the CFC instance. It'll let you stick any old values into an object. joseph.age = -42; That ought to tell you it's a bad idea. joseph.setAge(-41); That can at least check that the age value is sensible. That's why we use setters. It also lets us change the representation of the data within the object without having to change all the client code that uses the object. A Person CFC could store the year of birth and calculate age on demand or it could store both or it could store age and calculate the year of birth on demand. With getters and setters, the CFC can choose any approach and client code isn't affected. With your approach, once a choice is made, it can't change. That's brittle and creates a program that is hard to maintain. > By adding user getter/setter functions individual > instance variables complicates CFC data structure. Yes, for the trade off of a more robust design. > The difference between > an equal expression and a function call is when memory allocation occurs. Er, nope. > Equal-expression memory space happens at loadtime and for the most part is > fixed for that application execution. Nope, not true. a = b could cause all sorts of memory allocations and deallocations at runtime. > Getter/setter functions force dynamic > memory allocation at runtime which causes changes in the application memory > stack. Calling a function causes the stack to grow of course, as a new stack frame is created and when the function returns, the stack shrinks again. That's the nature of a function call. However, if you look under the hood, you'll see that CF compiles a = b down to a function call anyway - because CF is a dynamic, loosely-typed language that has to perform quite a bit of work to assign things sometimes... > It is these changes in memory stacks that expose risks for thread > failures. Are you saying that a basic function call can cause a thread failure? I guess we shouldn't use functions? What about custom tags? They cause the stack to grow and shrink too you know, as does <cfmodule>. Sheesh, we'd better write all our code as one monolithic .cfm page with no modularization, no functions, no custom tags... > Those of you who read this and who are encapsulation fans will not agree > with me recommending the use of this. scope. There's some far more fundamental problems with what you're saying than just recommending "this" scope, I'm afraid. > Declaring a CFC defined with this scope instance variable > is encapsulation by structure not by value. No, using "this" scope is a complete lack of encapsulation. Perhaps you need to go read up on what encapsulation means? I'm sorry if this response is harsh but your post is full of so many apparent misunderstandings about how things work that it's hard to know where to start. Spreading these sorts of misunderstandings damages ColdFusion's image - people in the Java and .NET world won't take CF seriously when they see stuff like this on our mailing lists. -- Sean A Corfield -- http://www.corfield.org/ Team Fusebox -- http://www.fusebox.org/ Breeze Me! -- http://www.corfield.org/breezeme Got Gmail? -- I have 6 invites to give away! "If you're not annoying somebody, you're not really alive." -- Margaret Atwood ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Special thanks to the CF Community Suite Silver Sponsor - CFDynamics http://www.cfdynamics.com Message: http://www.houseoffusion.com/lists.cfm/link=i:4:188790 Archives: http://www.houseoffusion.com/cf_lists/threads.cfm/4 Subscription: http://www.houseoffusion.com/lists.cfm/link=s:4 Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4 Donations & Support: http://www.houseoffusion.com/tiny.cfm/54

