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

Reply via email to