2

I have a question about cfargument. If I am sending a parameter when calling a .cfc, is there any benefit to defining it as argument first?

<cffunction name="someFunction" ....>
    <cfargument name="myArg" required="no">

Or can I just use IsDefined() inside the function, without defining an argument?

<cffunction name="someFunction" ....>
   ...
   <cfif isDefined("arguments.myArg")>
      do something
   </cfif>

I tried them and know that they both work. However, what is a difference between defining the argument and using isDefined()? Can that affect efficiency?

James A Mohler
  • 11,060
  • 15
  • 46
  • 72
espresso_coffee
  • 5,980
  • 11
  • 83
  • 193
  • @KevinB that's not my question. – espresso_coffee Nov 02 '16 at 15:00
  • 2
    @KevinB's comment is a path to the answer. – Dan Bracuk Nov 02 '16 at 15:01
  • 1
    @DanBracuk *gong "Ohmmmmmmmm" – Adrian J. Moreno Nov 02 '16 at 15:10
  • What happened when you actually tried it that did not make sense to you? – Leigh Nov 02 '16 at 15:12
  • @Leigh it makes sense and I know that works but what is a difference between defining the argument and using isDefine()? Can that affect efficiency? – espresso_coffee Nov 02 '16 at 15:15
  • 1
    @espresso_coffee - IMO, it should be included in the cfarguments. The function signature is a contract that tells consumers what type of information it requires and/or accepts. If you use isDefined the caller has no idea what type of values to supply, which is bad form. Side note, use structKeyExists rather than IsDefined. The former is more precise. – Leigh Nov 02 '16 at 15:23
  • BTW, not being sarcastic but you should put that last comment in your question. So it is clear what you are *really* asking and sounds less like a request for someone else to run code for you. Not saying that was your intent, but .. that is kinda' how the question reads right now ;-) – Leigh Nov 02 '16 at 15:26
  • @Leigh also if I use structKeyExists() I was getting an error 'Element MYARG is undefined in URL'. This argument is passed after user click on the button. So arguments doesn't exist before that. – espresso_coffee Nov 02 '16 at 15:52
  • Using option 1, the argument would be visible when you inspect the component, whereas if you didn't define it as an argument you wouldn't know it existed unless you read the source. – Kevin B Nov 02 '16 at 15:53
  • @What is the option 1? – espresso_coffee Nov 02 '16 at 15:55
  • defining the argument, vs not defining it. option 1 is defining it, the first snippet in your question. – Kevin B Nov 02 '16 at 15:55
  • 1
    @espresso_coffee - KevinB is referring to my [edits to the question](http://stackoverflow.com/posts/40383028/revisions). Hopefully it better reflects what you were really asking. If not, feel free to change it. – Leigh Nov 02 '16 at 16:01
  • 1
    `structKeyExists(ARGUMENTS, 'myArg')` should always work within a function. If you're getting an error involving the URL scope, there's something you're not doing right. I can't tell you exactly because I can't see your code... I always define any possible argument with `cfargument`. It helps the next developer know what they can expect in the function. One other benefit is that if you define the type attribute in `cfargument` it will validate on that type if the argument is passed in (e.g. `type="numeric"` for numeric values). – beloitdavisja Nov 02 '16 at 16:38

1 Answers1

10

It's not about efficiency, it's about documentation. Here's an exceprt from my company's coding standards document on cfargument.

When using the CFARGUMENT tag in a ColdFusion function, the following attributes are required:

  • Name
  • Type
  • Required
  • Hint

ColdFusion does not require that you use cfargument tags but they provide validation (type safety) and act as additional documentation, therefore always provide a cfargument tag for each named argument your function expects.

Rules:

  1. The name of an argument does not have to be prefixed with a data type (avoid Hungarian Notation).
  2. Always specify the type attribute in your cfargument tags. Try to avoid using type="any".
  3. If an argument is required, specify required="true" but do not specify a defaultattribute value.
  4. If an argument is not required, specify required="false" and specify a default attribute value.
  5. If you need to detect whether a non-required argument was provided, do not specify default, but instead use structKeyExists(arguments,"ARGNAME") in the function body (remember that when you specify default, you cannot tell the difference between the caller omitting that argument and the caller providing that same default value as an argument).
  6. When referring to a variable passed into a function as an argument, ALWAYS reference the arguments scope. (Don't reference foo, reference arguments.foo.)
  7. Do not manipulate the value of an argument passed into a function. CF passes some variable data types by reference and any manipulation done within a function alters the value of the variable at the level from which it was called. Copy the arguments struct to a function local variable using duplicate() to avoid conflicts, then manipulate the function local variable as needed.
  8. Do not add keys to the arguments struct that were not originally passed into the function. Adding new keys can make debugging very difficult. Instead, copy the arguments struct to a new function local variable using duplicate to avoid conflicts and add new keys to that struct.

HTH

Adrian J. Moreno
  • 14,350
  • 1
  • 37
  • 44
  • 1
    This would be a great addition to the SO's coldfusion documentation page: http://stackoverflow.com/documentation/coldfusion/topics – beloitdavisja Nov 02 '16 at 19:09
  • 1
    Not judging your company's guidelines, but rule #7 might cause heavy overhead with large sets of data. One should think about what provided arguments are actually used for. There's nothing wrong with passing stuff by reference (having a non-deterministic function), if it is documented accordingly. A general enforcement such as "always duplicate arguments scope" might backfire one day. – Alex Nov 02 '16 at 22:16
  • #7 is only in the situation that they want to manipulate the value of an argument -WHEN- it's passed by reference (e.g. a struct). We have multiple levels of code review, performance review and tesitng in multiple environments that will catch any issues like you describe. Still, well worth brining up the potential hazards. – Adrian J. Moreno Nov 02 '16 at 22:32