this var'ing the local scope variables within functions business...

I'd actually like to suggest this as a feature request:

instead of

<cffuncion...
  <cfset var whatever = ... />

and forgetting the "var", causing grief

functionality is added to the humble CFPARAM tag so it can be used to
set local function variables.

<cffuncion...
  <cfparam name="whatever" value="" ... />

and to take it a step further, all CFC "variables" and "this" need to
be required to be "CFPARAM"ed too.

when compiling/running, any variables that are used without being
"CFPARAM"ed somewhere first before being used in a CFSET generate at
least a warning (if not error).

sure this could (would) break existing code so by adding a
  <cfcomponent varsafe="true"
flag could switch from existing unsafe practices and "strict"
coding...hell, you could even bring type checking into this as well
(...maybe not)

poor old CFPARAM...it's like it's fallen out of favour...

any reasons why this couldn't work?

eh, my 2c worth, nothing more...
barry.b


PS: I'd also like ot see the ability to add additional custom/made up
attributes to CFPARAM for documentation/metadata. it seems a pity that
you can with cfcomponent, cfargument, etc but not cfparam..




On 11/01/06, Jason Daiger <[EMAIL PROTECTED]> wrote:
> Those were my thoughts exactly after reading Gary's post.  If performance
> became an issue, at least I have 1 place I know to look in order to attempt
> to gain some improvement.  And from a maintenance position, you know exactly
> which vars are local and which are not given the approach.  Also, given some
> of the discussions about how much folks are loading in to application level
> structures, a small hit on the local level seems likes peanuts in
> comparison.
>
> -Jason
>
> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf
> Of Bill Rawlinson
> Sent: Tuesday, January 10, 2006 8:57 AM
> To: [email protected]
> Subject: Re: [CFCDev] Dirty reads from QoQ in component
>
> a while ago someone posted a test using tens of thousands of variables and
> index lookups and the difference between using a struct and not using one
> was minimal.  So if using a struct to store your vars makes it easier for
> you don't let performance concerns worry you.
>
> In fact, even if they weren't so equivilant I would suggest you use a struct
> if it will make scoping all of your variables a more consistent and
> trustworthy process becuase then your software would be less prone to
> threading issues and thus more stable.
>
> Aim for stability before you try to optimze.  It just works out in this case
> that you aren't losing much by trying to be stable.  A win-win :O)
>
> Bill
>
> On 1/9/06, Gary Menzel <[EMAIL PROTECTED]> wrote:
> > I know other people dont like the approach suggested by Ed.  The claim
> > being that you are increasing the overhead by using an associative key
> > lookup to get your variable.  But - this is Coldfusion - so you are
> > probably still using an associative lookup even without the additional
> struct.
> >
> > But - that said - we have been using it here for 2 years now - and it
> > DOES save much heartache.
> >
> > Effectively you are creating your own "local" scope.  All you have to
> > do then is be consistent about using it.
> >
> > Regards,
> > Gary
> >
> >
> >
> > On 1/10/06, Ed Griffiths <[EMAIL PROTECTED]> wrote:
> > > Yes, unless you specifically intend to provide those queries or
> > > indexes to other methods within your CFC.
> > >
> > > A quick way to do this is to var-scope a local struct in each
> > > method. Use this var-scoped local struct to store indexes and
> > > queries - saves having
> > to
> > > explicitly var-scope every variable.
> > >
> > > <cffunction name="myFunction"...>
> > >   <cfset var local = StructNew()>
> > >   <cfloop from="1" to="10" index="local.i">
> > >     ...do something...
> > >   </cfloop>
> > >   <cfquery name="local.myQuery"...>
> > >     ...do something...
> > >   </cfquery>
> > > </cffunction>
> > >
> > > Get into the habit or store that code as a snippet in CFEclipse and
> > > save yourself from a whole world of debugging pain later!
> > >
> > > -----Original Message-----
> > > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> > > Behalf Of Jason Daiger
> > > Sent: 09 January 2006 15:31
> > > To: [email protected]
> > > Subject: RE: [CFCDev] Dirty reads from QoQ in component
> > >
> > >
> > > Am I understanding that as a best practice, as well as to address
> > > 'scoping issues', all query names and and all looping index
> > > variables should be declared in var scope w/in a cffunction prior to
> use?
> > >
> > >
> > > -----Original Message-----
> > > From: [EMAIL PROTECTED] [mailto: [EMAIL PROTECTED] On
> > Behalf
> > > Of Ed Griffiths
> > > Sent: Monday, January 09, 2006 9:08 AM
> > > To: [email protected]
> > > Subject: RE: [CFCDev] Dirty reads from QoQ in component
> > >
> > > We recently experienced a similar issue. Traced back to a single
> > > loop
> > index
> > > that should have been VAR scoped and wasn't.
> > >
> > > Nando recently posted this useful technique for ensuring that the
> > Variables
> > > scope doesn't contain anything it shouldn't (thanks Nando), might be
> > helpful
> > > during refactoring:
> > >
> > > "To make absolutely sure that all your variables are var scoped, use
> > > a
> > > dumpMe() function in your object ...
> > >
> > > <cffunction name="dumpMe" access="public" returntype="any" output="yes">
> > >         <cfdump var="#variables#" /> </cffunction>
> > >
> > > And look carefully to see if you missed any of the parameters you
> > > should have set as local to the function, like the iterator in
> > > loops, or query names. They will show up persisted within the
> > > variables scope of the
> > object.
> > > Obviously, you want to call dumpMe() after all of the methods in the
> > object
> > > have run."
> > >
> > >
> > > -----Original Message-----
> > > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> > > Behalf Of Cliff Meyers
> > > Sent: 09 January 2006 13:43
> > > To: [email protected]
> > > Subject: Re: [CFCDev] Dirty reads from QoQ in component
> > >
> > >
> > > It looks like there are a lot of variables in your component that
> > > are not declared function local with the "var" keyword.  If you're
> > > storing this component in the application scope this will almost
> > > certainly cause
> > problems
> > > along the way.  In particular it looks like "rc", "conn" and "idx"
> > > could cause big problems by not being function local.
> > > That aside, you should never create variables in a component that
> > > *aren't* function local unless they're actually component "properties"
> > > or "attributes" in the true sense of the word that multiple methods
> > > would need access to.  HTH.
> > >
> > >
> > > On 1/9/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> > > > I have a component in the application scope that is returning a
> > > > list of
> > > fees due on a given transaction.
> > > >
> > > > The problem is that on occassion the query will return "dirty" data.
> > > > The
> > > application is processing fine on the oracle back end and there is
> > > no indication that the data being returned to and displayed on the
> > > page was ever in the database. There is a transaction that is being
> > > processed at
> > the
> > > same time that seems to have the same data that was returned in the
> > "dirty"
> > > read.
> > > >
> > > > I am wondering if a lock around the portion of code that sets the
> > > > initial
> > > query that is used in the QoQ would prevent this or if there is
> > > another
> > way
> > > to prevent this from happening while still keeping the component in
> > > the application scope.
> > > >
> > > > Here is the function:
> > > >
> > > >     <cffunction name="getFeeInfo" access="public" returntype="struct"
> > > hint="Input the transaction number and the newedb connection string
> (cms).
> > > Returns a structure containing the return code and description,
> > > input params, and a query containing the fee info for the
> > > transaction.">
> > > >
> > > >         <cfargument name="inout_trans_number" type="string"
> > > required="yes">
> > > >         <cfargument name="sid" type="string" required="yes">
> > > >         <cfset var fee_info = "">
> > > >         <cfset var cashinfo = "">
> > > >         <cfset var charges = "">
> > > >         <cfset var txn_charges = "">
> > > >         <cfset var total_charges = "0">
> > > >
> > > >         <cfparam name="out_return_code" default="0" type="numeric">
> > > >         <cfparam name="out_return_desc" default=""  type="string">
> > > >         <cfparam name="total_charges"   default="0" type="numeric">
> > > >
> > > >         <cfset fee_info =
> > >
> > QueryNew("cde_product_acct_code,desc_product_type,amt,numeric_amt")>
> > > >         <cfset rc = QueryAddRow(fee_info)>
> > > >         <cfset rc =
> > QuerySetCell(fee_info,"cde_product_acct_code","",1)>
> > > >         <cfset rc =
> > QuerySetCell(fee_info,"desc_product_type","",1)>
> > > >         <cfset rc = QuerySetCell(fee_info,"amt",0,1)>
> > > >         <cfset rc =
> > QuerySetCell(fee_info,"numeric_amt",0,1)>
> > > >
> > > >         <cfset conn =
> > >
> >
> CreateObject("component","components.JavaUtilities").getAkcConn("#arguments.
> > > sid#")>
> > > >
> > > >         <cfif not isDefined("conn")>
> > > >             <cfset out_return_code = "101">
> > > >             <cfset out_return_desc = "Unable to obtain remote
> > connection">
> > > >         <cfelse>
> > > >
> > > >             <cfset cashinfo =
> > CreateObject("Java","CashInfo")>
> > > >             <cfset charges =
> > > cashinfo.getCashInfo(conn,"#TRIM(arguments.inout_trans_number)#")>
> > > >             <cfif not isDefined("charges")>
> > > >                 <cfset out_return_code = "102">
> > > >                 <cfset out_return_desc ="Record set not returned
> > > > from
> > > java">
> > > >             <cfelse>
> > > >
> > > >                 <cfset txn_charges =
> > > CreateObject("component","
> > components.JavaUtilities").ResultSetToQuery(charge
> > > s)>
> > > >                 <cfif not isDefined("txn_charges")>
> > > >                     <cfset out_return_code = "103">
> > > >                     <cfset out_return_desc ="Record set not
> > > > converted to
> > > CF Query">
> > > >                 <cfelse>
> > > >                     <cfset void =
> > > CreateObject("component","
> > > components.JavaUtilities").closeAkcConn(conn)>
> > > >
> > > >                     <cfif txn_charges.recordcount gt 0>
> > > >                         <cftry>
> > > >                         <cfquery name="fee_info" dbtype="query">
> > > >                                 select
> > cde_product_acct_code,
> > > >
> > desc_product_type,
> > > >                                        sum(num_amount)
> > as amt,
> > > >                                        sum(num_amount)
> > as numeric_amt
> > > >                                 from txn_charges
> > > >                                 where cde_payment_type
> > = ''
> > > >                                 group by
> > > cde_product_acct_code,desc_product_type
> > > >                                 order by
> > cde_product_acct_code desc
> > > >                         </cfquery>
> > > >                         <!--- where cde_product_acct_code not in
> > > ('VISA','MASTER','DISCVR','AMEX') --->
> > > >                         <cfcatch>
> > > >                             <cfset out_return_code = "104">
> > > >                             <cfset out_return_desc =
> > > > "#cfcatch.message# -
> > > #HTMLCodeFormat(cfcatch.detail)#">
> > > >                         </cfcatch>
> > > >                         </cftry>
> > > >                     </cfif>
> > > >                 </cfif>
> > > >             </cfif>
> > > >         </cfif>
> > > >         <cfset idx = 0>
> > > >         <cfoutput query="fee_info">
> > > >             <cfset idx = idx +1>
> > > >             <cfset total_charges = total_charges + numeric_amt>
> > > >             <cfset rc =
> > >
> > QuerySetCell(fee_info,"amt",#DollarFormat(Abs(numeric_amt))#,#idx#)>
> > > >         </cfoutput>
> > > >
> > > >         <cfset FeeInfo.out_struct.fee_info = fee_info>
> > > >         <cfset FeeInfo.out_struct.total_charges =
> > abs(total_charges)>
> > > >         <cfset FeeInfo.out_struct.out_return_code =
> > out_return_code>
> > > >         <cfset FeeInfo.out_struct.out_return_desc =
> > out_return_desc>
> > > >         <cfset FeeInfo.out_struct.ChargedFeeInfo =
> > >
> > duplicate(getChargedFeeInfo(arguments.inout_trans_number,arguments.sid
> > ).fee_
> > > info)>
> > > >         <cfset FeeInfo.out_struct.in_params = arguments>
> > > >
> > > >         <cfreturn FeeInfo.out_struct>
> > > >     </cffunction>
> > > >
> > > > Thanks,
> > > >  Frederick
> > > >
> > > >
> > __________________________________________________________________
> > > > Switch to Netscape Internet Service.
> > > > As low as $9.95 a month -- Sign up today at
> > > http://isp.netscape.com/register
> > > >
> > > > Netscape. Just the Net You Need.
> > > >
> > > > New! Netscape Toolbar for Internet Explorer Search from anywhere
> > > > on the Web and block those annoying pop-ups.
> > > > Download now at
> > http://channels.netscape.com/ns/search/install.jsp
> > > >
> > > >
> > > >
> > ----------------------------------------------------------
> > > > You are subscribed to cfcdev. To unsubscribe, send an email to
> > > [email protected] with the words 'unsubscribe cfcdev' as the
> > > subject of
> > the
> > > email.
> > > >
> > > > CFCDev is run by CFCZone (www.cfczone.org) and supported by
> > > > CFXHosting
> > > (www.cfxhosting.com).
> > > >
> > > > An archive of the CFCDev list is available at
> > > www.mail-archive.com/[email protected]
> > > >
> > > >
> > > >
> > >
> > >
> > >
> > ----------------------------------------------------------
> > > You are subscribed to cfcdev. To unsubscribe, send an email to
> > > [email protected] with the words 'unsubscribe cfcdev' as the
> > > subject of
> > the
> > > email.
> > >
> > > CFCDev is run by CFCZone (www.cfczone.org) and supported by
> > > CFXHosting (www.cfxhosting.com).
> > >
> > > An archive of the CFCDev list is available at
> > > www.mail-archive.com/[email protected]
> > >
> > >
> > >
> > >
> > ______________________________________________________________________
> > __
> > > This e-mail has been scanned for all viruses by MessageLabs.
> > >
> > ______________________________________________________________________
> > __
> > >
> > >
> > >
> > >
> > ----------------------------------------------------------
> > > You are subscribed to cfcdev. To unsubscribe, send an email to
> > > [email protected] with the words 'unsubscribe cfcdev' as the
> > > subject of
> > the
> > > email.
> > >
> > > CFCDev is run by CFCZone (www.cfczone.org) and supported by
> > > CFXHosting (www.cfxhosting.com).
> > >
> > > An archive of the CFCDev list is available at
> > > www.mail-archive.com/[email protected]
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > ----------------------------------------------------------
> > > You are subscribed to cfcdev. To unsubscribe, send an email to
> > > [email protected] with the words 'unsubscribe cfcdev' as the
> > > subject of
> > the
> > > email.
> > >
> > > CFCDev is run by CFCZone (www.cfczone.org) and supported by
> > > CFXHosting (www.cfxhosting.com).
> > >
> > > An archive of the CFCDev list is available at
> > > www.mail-archive.com/[email protected]
> > >
> > >
> > >
> > >
> > ______________________________________________________________________
> > __
> > > This e-mail has been scanned for all viruses by MessageLabs.
> > >
> > ______________________________________________________________________
> > __
> > >
> > >
> > >
> > >
> > ----------------------------------------------------------
> > > You are subscribed to cfcdev. To unsubscribe, send an email to
> > [email protected] with the words 'unsubscribe cfcdev' as the subject
> > of the email.
> > >
> > > CFCDev is run by CFCZone (www.cfczone.org) and supported by
> > > CFXHosting
> > (www.cfxhosting.com).
> > >
> > > An archive of the CFCDev list is available at
> > www.mail-archive.com/[email protected]
> > >
> > >
> > >
> >
> >  ----------------------------------------------------------
> >  You are subscribed to cfcdev. To unsubscribe, send an email to
> > [email protected] with the words 'unsubscribe cfcdev' as the subject
> > of the email.
> >
> >  CFCDev is run by CFCZone (www.cfczone.org) and supported by
> > CFXHosting (www.cfxhosting.com).
> >
> >  An archive of the CFCDev list is available at
> > www.mail-archive.com/[email protected]
>
>
> --
> [EMAIL PROTECTED]
> http://blog.rawlinson.us
>
> If you want Gmail - just ask.
>
>
> ----------------------------------------------------------
> You are subscribed to cfcdev. To unsubscribe, send an email to
> [email protected] with the words 'unsubscribe cfcdev' as the subject of the
> email.
>
> CFCDev is run by CFCZone (www.cfczone.org) and supported by CFXHosting
> (www.cfxhosting.com).
>
> An archive of the CFCDev list is available at
> www.mail-archive.com/[email protected]
>
>
>
>
>
>
> ----------------------------------------------------------
> You are subscribed to cfcdev. To unsubscribe, send an email to 
> [email protected] with the words 'unsubscribe cfcdev' as the subject of the 
> email.
>
> CFCDev is run by CFCZone (www.cfczone.org) and supported by CFXHosting 
> (www.cfxhosting.com).
>
> An archive of the CFCDev list is available at 
> www.mail-archive.com/[email protected]
>
>
>


----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email to 
[email protected] with the words 'unsubscribe cfcdev' as the subject of the 
email.

CFCDev is run by CFCZone (www.cfczone.org) and supported by CFXHosting 
(www.cfxhosting.com).

An archive of the CFCDev list is available at 
www.mail-archive.com/[email protected]


Reply via email to