Passing values by reference or value

January 27, 2010

This has been posted many time before, but it still catches me out every now and then, so thought it was worth a post for anyone who doesn't know.

ColdFusion passes some data types by value and others by reference. What do I mean? Well, the easiest way is to demonstrate, so here is some quick demo code.


<cfscript>

// test strings
WriteOutput( "
<p>Strings are passed by value</p>" );

mystring = "John";

WriteDump( mystring );

changeString( mystring );

WriteDump( mystring );


// test arrays
WriteOutput( "<p>Arrays are passed by value</p>" );

myarray = [ "John" ];

WriteDump( myarray );

changeArray( myarray );

WriteDump( myarray );


// test structs
WriteOutput( "<p>Structs are passed by ref</p>" );

mystruct = { name="John" };

WriteDump( mystruct );

changeStruct( mystruct );

WriteDump( mystruct );


// test queries
WriteOutput( "<p>Queries are passed by ref</p>" );

myquery = QueryNew( "name" );

QueryAddRow( myquery );
QuerySetCell( myquery, "name", "John" );

WriteDump( myquery );

changeQuery( myquery );

WriteDump( myquery );


// test objects
WriteOutput( "<p>Objects are passed by ref</p>" );

myobject = new Person();

myobject.setName( "John" );

WriteDump( myobject);

changeObject( myobject );

WriteDump( myobject );



// these functions change the data passed to them and return nothing (void)
function changeArray( value )
{
arguments.value[ 1 ] = "Aliaspooryorik";
}

function changeStruct( value )
{
arguments.value.name = "Aliaspooryorik";
}

function changeQuery( value )
{
QuerySetCell( arguments.value, "name", "Aliaspooryorik" );
}

function changeObject( value )
{
arguments.value.setName( "Aliaspooryorik" );
}

function changeString( value )
{
arguments.value = "Aliaspooryorik";
}

</cfscript>

The code for the Person object is:


component accessors=true
{
property name;
}

When you run it you will get:

 byref byval dump

As you can see; Strings and Arrays are passed by value, meaning that inside the function is a deep copy of the original variable. So, we you change the variable inside the function, you do not change the original variable.

However, all the other tests show that the original variable is affected, as they are passed by reference (a reference or pointer to the original variable in memory is passed), so you are manipulating the original variable and not a copy.

That's it, but if you don't know what is going on it's very confusing!


7 comments

  1. Nice round-up.

    Comment by Ben Nadel – January 27, 2010
  2. Thanks - It's a bit like a weak facsimile of a Ben Nadel post :D

    Comment by John Whish – January 27, 2010
  3. Ha ha ha :) Hey, you gotta take a break from all the ORM magic you've been rocking.

    Comment by Ben Nadel – January 27, 2010
  4. Haha As I was reading this, I too was thinking to myself: this sort of feels like a Ben Nadel post. It has "Ben vibes". haha

    Good post though John!

    Comment by Grant Copley – January 27, 2010
  5. How does it work when items are nested? e.g. an array of structs of arrays, etc.? Thinking about the permutations makes my head hurt...

    Comment by Andy – January 28, 2010
  6. Ack, ARRAYS are passed by value??! No one sent me the memo..! How did I miss this??

    Comment by Joshua Curtiss – January 29, 2010
  7. @Andy, Good question - I started writing a comment, but decided to turn it into a post:
    www.aliaspooryorik.com/blog/index.cfm/e/posts.details/post/by-value-and-by-ref-with-nested-data-types-250

    @Joshua, yeah arrays are the odd one out. Hope I haven't caused you too much pain :)

    Comment by John Whish – January 29, 2010

Leave a comment

If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)

Please note: If you haven't commented before, then your comments will be moderated before they are displayed.