Consider the following:

Demo1:
Run it.


Demo2:
Run it.


With ColdFusion 9 local is supposed to be private to the method. In Demo 2 the code behaves as expected but in Demo 1 the local in the variables scope is over written.

I consider this a bug with the local scope but I'd like some feed back.

BTW how did I find this? A friend on mine had code similar to the example and was wondering why local went blank half way through a page. I tracked it back to a UDF that had:

cfset local = {}

OK so calling a variable in a .cfm local not all the common but it could ( and did ) happen.

Thoughts?

27 comments:

Paul Kukiel said...

Ignore the < br />'s the syntax highligter adds them and I havn't got around to fixing it yet.

Anonymous said...

Paul, this is not a bug. However it is pretty silly code if you are setting the local scope to a struct.

Dave Ferguson said...

Nice find.. Also, to add another angle to this issue. If you do this:



in the function it blanks the struct entirely.

Paul Kukiel said...

@Anon

How is it not a bug?

Paul Kukiel said...

@Dave

Sorry Blogger strips out the tags.

I assume you did:

cfset local = ""

Dave Ferguson said...

Dang it.. code wiped.. should have been:

<cfset local = '' />

Dean Lawrence said...

Paul, I think your problem is that in example one, you are not actually altering the local scope, but a variable called local. If you look at Ben Forta's blog entry from back in June http://forta.com/blog/index.cfm/2009/6/21/The-New-ColdFusion-LOCAL-Scope, if you define a variable called var local, you are actually creating a variable Local.local. Since you did not var the local variable name, you are creating the local variable in the variable scope variable.local, which would overwrite your original value.

Dean

Paul Kukiel said...

@Dean

That's not correct

< cfset var local /> within a method in ColdFusion 9 is ignored. It dosn't create local.local

Dean Lawrence said...

@Paul,

I misspoke, apparently this changes since the release. However on those same lines, if you name a variable called local without the var keyword (which apparently is ignored anyway), it places it into the variable scope.








Either way, it's odd behavior.

Dean Lawrence said...

Interesting... I just tried setting one of the other scopes to an empty structure and it treated it the exact same way.

URL = {}

When I dumped the variable scope it was located there. I don't know if this is something new to CF9 or if it has always treated direct setting of protected structure (without key names) in this manner.

Tony Nelson said...

Both demos worked as expected on my machine.

Glen Dunlop said...

Its not a bug because you need to understand what you are doing.

This may change with the release of updater 1, but here is what you are doing. In the CFM page you are defining a local scope to a struct. ColdFusion has in its wisdom made a decision that it will convert this to a variable, and place it into the variables scope.

In you function because the scope doesn't exist, you are referencing the variable as variables.local.name without the variables scope.

Does that make more sense!

Sorry I went Annonymous before, because it refused to save my comment, by throwing an error.

Paul Kukiel said...

But in my function which is CF9 local always exists? Its a scope so it has to exist?

Glen Dunlop said...

Paul,

If you set local to a struct you are defining it back to the variables scope. That is by design.

Paul Kukiel said...

Consider this:

< cfset request = {} /> or < cfset session = {} />

It's ignored as thats nto that way to clear a scope.

Why if local is a scope withing a method is

< cfset local = {} /> behaving different to the way all scopes are treated?

Glen Dunlop said...

Because Adobe wanted to be backward compatible on this, and chose to try to be smart about it. Unfortunetly they got it wrong.

This is also tied to the local bug described on a few blogs a few months ago.

I would say it is related, but the local scope is different to other scopes. Due to trying to be backward compatable.

If you ran this over a line debugger, you would see the problem that Adobe tried to address here.

Paul Kukiel said...

OK I see so it's intended then by Adobe for compatibility its just mighty confusing :)

I think I'm going to stick with leaving :

< cfset var local = {} />

At the top on my methods just incase ( also so it will work on other engines ).

Glen Dunlop said...

Or just dont reset the local scope to a struct, there is no need to do that in a function with the local scope.

Why you even tried is beyond me.

But as I said you may find it fixed, in CF 9 updater 1, because of the local bug blogged a few months ago.

But like I stated,

set local = {} says I am setting the variable local into the variables scope.

Where var local = {} says you are then creating a local.local variable instead.

And yes it is confusing if you don't understand what is happening.

Paul Kukiel said...

@Glen I didn't try LOL I was working with someone who said "Why did local just become empty half way down the page?" I tracked it down to this. By var scoping local = {} in the UDF or simply removing the line local = {} its worked fine.

Also < cfset var local = {} /> In a method will not create local.local its simply ignored by the engine.

Glen Dunlop said...

Explain ignored Paul!!

Paul Kukiel said...

Sure:

< cfscript>

tester();

void function tester() {
var local = {};
local.name = "Paul";
writeDump(local);
}



There is no local.local created see: http://cf9.kukiel.net/demos/local/demo3.cfm for the output.

Glen Dunlop said...

Paul,

If this is ignored, then why can I do this?

var local = {firstName='Glen', lastName='dunlop');

How is it being ignored then, the engine is basically taking the line and converting it to a private scope for the function. This is not what I would call being ignored.

Paul Kukiel said...

Your correct seems it's not ignored.

But var local = {} doesn't create local.local but that's a different story. I think I'm happy with the original issue not being a bug but an intended outcome. Regardless it was an interesting journey to back track the original issue to this and goes to show why scoping is important.

Glen Dunlop said...

Actually it does.

Lets take this example inside a function for a minute.

local.test = {firstName='Glen', lastName='dunlop');
writeDump(local);

This will dump the local scope out.

Now lets take these lines
var local = {firstName='Glen', lastName='dunlop');
writeDump(local);

It too will dump the local scope out.

So what is hapenning here is that, its easy to assume and I had to double check this myself. But in a sense you are typing local.name, and you are referencing it from the local scope. However you can't dump local.local, because the engine is smart enough to know what you are asking from it.

But it boils down to that this is not a bug, and it is working as expected.

Paul Kukiel said...

Interesting. I guess what we think and what is really happening behind the scene can be 2 different things. Thanks for taking the time.

Paul Kukiel said...

Here is a follow up:

http://blog.kukiel.net/2009/12/coldfusion-9-and-local-scope-continued.html

Anonymous said...

to add another angle to this issue. If you do this: in the function it blanks the struct entirely.

if you are looking for a cheap vps that is reliable and the uptime is 99.9%

Post a Comment