2009-07-01 9 views
14

J'ai une fonction ColdFusion "foo" qui prend trois args, et le second deux sont en option:Comment spécifier seulement quelques arguments optionnels lors de l'appel de la fonction dans ColdFusion?

<cffunction name="foo" access="public" returntype="any"> 
    <cfargument name="arg1" type="any" required="true" /> 
    <cfargument name="arg2" type="any" required="false" default="arg2" /> 
    <cfargument name="arg3" type="any" required="false" default="arg3" /> 

    ... 

    <cfreturn whatever /> 
</cffunction> 

Je veux appeler foo, en passant arg1 et arg3, mais laissant de côté arg2. Je sais que c'est possible si j'appelle la fonction en utilisant cfinvoke, mais cette syntaxe est vraiment verbeuse et compliquée. J'ai essayé ces deux approches, aucun ne fonctionne:

<cfset somevar=foo(1, arg3=3) /> <!--- gives syntax error ---> 
<cfset somevar=foo(1, arg3:3) /> <!--- gives syntax error ---> 

Répondre

29

Vous devez utiliser des arguments nommés partout. Vous ne pouvez pas mélanger des arguments nommés et positionnels comme vous le pouvez dans d'autres langues.

<cfset somevar = foo(arg1=1, arg3=3) /> 
2

si vous utilisez nommé args vous devez nommer le premier aussi

<cffunction name="foo" access="public" returntype="any"> 
    <cfargument name="arg1" type="any" required="true" /> 
    <cfargument name="arg2" type="any" required="false" default="arg2" /> 
    <cfargument name="arg3" type="any" required="false" default="arg3" /> 

    <cfreturn arg2 & " " & arg3> 
</cffunction> 


<cfset b = foo(arg1:1,arg3:2)> 
<cfoutput>#b#</cfoutput> 
20

Ou .. vous pouvez utiliser ArgumentCollection

En CF9 ou au-dessus ...

<cfset somevar = foo(argumentCollection={arg1=1, arg3=3})> 

En CF8 ou plus ...

<cfset args = {arg1=1, arg3=3}> 
<cfset somevar = foo(argumentCollection=args)> 

Si CF7 ou au-dessous ...

+0

C'est de cette façon que je préfère généralement le faire. Il est plus que probable que je détermine les arguments à inclure lors de l'exécution. C'est sympa et facile d'enrouler dans un bloc . – ale

+1

Comme Al l'indique, vous devez mettre à jour vos exemples pour montrer qu'un avantage majeur de ArgumentCollection est qu'il vous permet de construire/manipuler les structures de manière flexible, avant de les envoyer à la fonction - vos exemples actuels ne sont que longs façon d'utiliser tous les arguments nommés. :) –

+1

Il convient également de noter que vous pouvez mélanger et mettre en correspondance les arguments nommés et ArgumentCollection dans un seul appel de fonction. –

0

Moi aussi, je cherchais des réponses que Kip affiché. Voici ce que j'ai mis en œuvre. J'espère que cela pourrait ajouter à notre chaîne de solutions possibles. J'ai juste ajouté <cfparam> au code de cffunction:

<cffunction name="fn1" access="public" returntype="numeric"> 
    <cfargument name="arg1" type="numeric" required="true"> 
    <cfargument name="arg2" type="numeric" required="true"> 
    <cfargument name="arg3" type="query" required="false"> 
    <cfparam name="arguments.arg1" default=0> 
    <cfparam name="arguments.arg2" default=0> 
    <cfparam name="arguments.arg3" default=0> 
    <cfreturn arguments.arg1 + arguments.arg2 + arguments.arg3> 
</cffunction> 

<cfoutput>#fn1(arg1=1,arg2=2)#</cfoutput> 
+0

Je ne pense pas que cela fonctionnera puisque '' est destiné à "Tester l'existence d'un paramètre (c'est-à-dire une variable), valider ses données et, si une valeur par défaut n'est pas affectée, en fournir une. " Dans ce cas, vous les marquez comme requis, donc au moment où les cfparams sont frappées, vous avez la garantie que les arguments 1-3 existent. (Si ce n'était pas le cas, l'appel de la fonction enverrait une erreur.) Vous pourriez fournir une valeur par défaut dans l'argument et la rendre inutile, mais je suppose dans ce contexte que c'est ce que vous essayez d'éviter. – bean5

Questions connexes