The amazing adventures of Doug Hughes

Last week, there was a conversation in the #coldfusion channel on Dalnet IRC where one person was pondering if the ‘passed by reference’ behavior of ColdFusion (and just about every other programming language) ‘breaks’ encapsulation when using object oriented (OO) design patterns or architecture.

For those who may not understand what ‘passed by reference’ means, it is a way that programming languages handle complex data types (such as structures, queries or CFC instances in ColdFusion) to save memory. When you create a structure in ColdFusion, it gets stored in memory. Whenever you need to reference this structure or pass it to a function or custom tag, ColdFusion uses a ‘pointer’ to show where in the memory this variable is stored, rather than another instance of the variable. Any changes made to the structure in the function or custom tag, will be reflected in the ‘original’ structure.

Here is some sample code to show how this works.

<cfset struct1 = structNew() />
<cfset struct1.name = "New York Giants" />

<cfset struct2 = struct1 />
<cfset struct2.name = "New York Yankees" />

<cfoutput>#struct1.name#</cfoutput>

This code will actually output ‘New York Yankees’ rather than ‘New York Giants’, as some might expect.

The person who asked the question was concerned about how you can pass an object into a method, modify properties of that object, NOT return the object, yet still see those property changes reflected in the original object. He assumed this ‘broke’ encapsulation. Here is the analogy he used:

“Let’s say my method is a ‘locked room’ and I pass this method arguments by slipping paper under the door. If I pass a piece of paper under the door that represents the object, should I not get back a piece of paper with the changes made to my object?”

I liked this analogy as it represents a method as a kind of ‘black box’, which they should be, where we merely pass in data and that data gets handled and we do not need to worry about it. There were some flaws in the logic, though, as ‘passing by reference’ is not an OO principal, rather a very low level process of the programming language. When we in the channel explained that ‘passed by reference’ is not an OO principal, rather the way programming languages pass around complex data types to save memory, he then asked

“So using my door analogy, I would slide a piece of paper under the door, yet keep a copy for myself and any changes that are made by my method will automatically appear on the piece of paper I keep?”

I thought about this for a little bit as it did not seem to completely explain what was going on. After a few minutes, I think I came up with an analogy that works well (and he said helped him understand a bit more):

“Instead of sliding a piece of paper under the door that represents your object, you merely slide a note under the door that tells the method that the paper (object) it needs is tacked up on the bulletin board in the hall. You do not have that paper either, rather, you also have a note saying that the paper (object) is on the bulletin board.”

I will admit this may not be a perfect analogy either, but it did help this person and I thought it might help clarify this for others as well.

Comments on: "Yet Another 'Passed By Reference' Analogy" (3)

  1. Dutch Rapley said:

    I’ve never really put forth much thought about objects being passed by reference. Thanks for the insight.

    I’ve taken your structure example above and created another one to demonstrate passed by reference.

    ***TeamHelper.cfc***

    ***example.cfm***

    teamHelper = CreateObject(“component”, “TeamHelper”);
    teamOne = {city=”New York”, mascot=”Giants”};
    teamTwo = teamOne;
    teamTwo = teamHelper.changeMascot(teamTwo, “Knicks”);
    teamOne = teamHelper.changeMascot(teamOne, “Yankees”);

    Like

  2. Doug Boude said:

    Here’s yet one more analogy/walk through of the whole byref vs byval thing:
    http://www.dougboude.com/blog/1/2006/07/ByRef-and-ByVal-in-ColdFusion.cfm

    Like

  3. I think you’re right in saying that “byref” or “byval” is prior to the question of object orientation. There are lots of examples of the “black box” in the real world that show the same kind of thing. I think a good one is when you drive up to the bank and they have the pneumatic tube for you to send stuff to the teller and get stuff back. Well if you’re depositing a check and you want to get cache back, you have to put your ID in the tube (black box), *NOT* a piece of paper with your ID number on it or even a photocopy of your ID (by value), your actual ID (by reference).

    Once it’s in the black box, the bank teller could do anything they want with it. They could lose it, they could shred it, they could draw a mustache on your photo with a sharpie. But you have to trust that the teller is going to do the expected thing with it and send it back out of the black box.

    But it still is a black box – there could be any number of record-keeping operations that require their use of the actual card, which by nature of the black box you have no knowledge of or control over.

    The non-black box alternative would be having the teller say “okay, I need you to open your laptop there in the car or your iPhone and go to this website and enter the ID from your driver’s license”. How do they know you have an iPhone? And why should they care? Shouldn’t anything they need to do be done on their end? What would be the advantage of exposing the customer to their process or for that matter adding dependencies by requiring the customer to have extra equipment handy?

    Like

Comments are closed.

Tag Cloud

%d bloggers like this: