So I happened to loop over a recordset in a function today and one of the
column names had the same name as an argument to the function.  I thought
nothing of it, and assumed that inside my CFLOOP tag, the column's value in
the current record would have the highest priority in the scope search
queue.  But that's NOT the case.

Local variables have a higher priority that columns when looping a
recordset.  Thus, if you want to reference a recordset column within a
function that has either an argument or a local variable with the same name,
you have to do it longhand: #recordsetname.columnname[currentrow]#, rather
that the usual #columnname#

Anyone have any clever insights about this, and/or know if it is/should be a
bug?  I think it should, but we all know my opinions on scoping are
"interesting".

To prove to myself I wasn't crazy, I wrote a simple test case and included
it below.  While it will happen rarely (this is the first time it's happened
to me), it seems counterintuitive that the local variables scope would be
searched before the recordset, since the recordset loop is a narrower scope
than the local variables scope.  Both CFC methods loop the recordset and
create a list of the 'id' field's values for the records.  The output
should, IMHO, be "1,2,3" for all three, but it is in fact "42,42,42",
"37,37,37", and "1,2,3".

test.cfm:
---------
<cfset q = queryNew("id") />
<cfset queryAddRow(q) /><cfset querySetCell(q, "id", 1) />
<cfset queryAddRow(q) /><cfset querySetCell(q, "id", 2) />
<cfset queryAddRow(q) /><cfset querySetCell(q, "id", 3) />
<cfoutput>
#createObject("component", "test").testArg(q, 42)#<br />
#createObject("component", "test").testLocal(q)#<br />
#createObject("component", "test").testFullScope(q)#
</cfoutput>

test.cfc:
---------
<cfcomponent>

   <cffunction name="testArg" output="true">
      <cfargument name="rs" />
      <cfargument name="id" />
      <cfset var result = "" />
      <cfloop query="rs">
         <cfset result = listAppend(result, id) />
      </cfloop>
      <cfreturn result />
   </cffunction>

   <cffunction name="testLocal" output="true">
      <cfargument name="rs" />
      <cfset var id = 37 />
      <cfset var result = "" />
      <cfloop query="rs">
         <cfset result = listAppend(result, id) />
      </cfloop>
      <cfreturn result />
   </cffunction>

   <cffunction name="testFullScope" output="true">
      <cfargument name="rs" />
      <cfset var id = 37 />
      <cfset var result = "" />
      <cfloop query="rs">
         <cfset result = listAppend(result, rs.id[currentRow]) />
      </cfloop>
      <cfreturn result />
   </cffunction>

</cfcomponent>
---
Barney Boisvert, Senior Development Engineer
AudienceCentral
[EMAIL PROTECTED]
voice : 360.756.8080 x32
fax   : 360.647.5351

www.audiencecentral.com
[Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings]

Reply via email to