2010-02-03 5 views
2

J'ai une méthode "format" qui fonctionne de manière similaire à la méthode C# String.Format, avec la signature suivante:Passage des arguments facultatifs (... rest) à une autre méthode qui prend des arguments facultatifs dans AS3

Dans une classe nommée StringTools:

/** 
* Formats a string, based on C# String.Format method. 
* @param raw A string with numbered tokens, such as "{0}, {1}" 
* @param rest Values that replace the numbered tokens in raw. 
*/ 
public static function format(raw:String, ...rest:*):String; 

StringTools.format ("{0}, {1}", "Bonjour", "World") renvoie la chaîne "Bonjour, monde" comme prévu. Maintenant, j'essaie de faire en sorte que ma classe de journalisation utilise cette méthode, mais j'ai du mal à passer les variables optionnelles. La signature de la méthode dans la classe d'enregistrement est:

public static function infof(raw:String, ...rest:*):String; 

Si je passe « repos » directement dans StringTools.format (brut, repos), il est transmis comme un tableau, et non comme une série de paramètres, donc si je l'appelle comme ceci: infof ("{0}, {1}", "Hello", "World"), j'obtiens la chaîne "Hello, World, {1}", car elle remplace le premier jeton par l'ensemble des valeurs.

J'ai aussi essayé de construire un tableau d'arguments, et appelant la méthode comme ceci:

var collectArgs:Array = [raw]; 

for (var i:Number = 0; i < rest.length; i++) 
{ 
collectArgs.push(rest[i]); 
} 

var callFunction:Function = StringTools.format.call; 

trace(callFunction.apply(null, collectArgs)); 

Cependant, cette trace "du monde, 6". Donc, il semble que les paramètres sont décalés. J'ai donc essayé d'initialiser collectArgs en tant que [null, raw], et j'obtiens "Hello World, 6. Le numéro est {1}" à nouveau.

Est-ce que je fais quelque chose de mal? Quelle est la bonne façon de passer des paramètres optionnels d'une méthode qui attend des paramètres optionnels à une autre méthode qui attend des paramètres optionnels?

Merci!

Répondre

1

Je pense que vous êtes sur la bonne voie en appliquant. Cela semble faire illustrer le comportement que vous voulez:

static function f1(raw:String, ...rest:*):void 
{ 
    trace("f1: "+raw+" "+rest); 
    rest.unshift(raw); 
    f2.apply(null, rest); 
} 

static function f2(raw:String, ...rest:*):void 
{ 
    trace("f2: "+raw+" "+rest); 
} 

function passSomeArguments():void 
{ 
    f1("A",1,2,3); 
} 

EDIT: comme 1er paramètre Vous devez passer « null » à appliquer parce que le premier paramètre est ce qui est considéré comme « ceci » lorsque la fonction est appelée . Puisque les fonctions sont statiques (et n'ont en aucun cas aucune dépendance sur 'this') vous pouvez passer null, mais vous devez passer quelque chose.

0

En fait, je viens de trouver que c'est mon problème. Cela devrait fonctionner correctement en utilisant la méthode de collection d'arguments décrite, tant que le premier élément du tableau d'arguments est null. Je ne suis pas sûr pourquoi nul est nécessaire, mais cela fonctionne bien de cette façon.

+0

Vous n'aurez pas besoin de "null" si vous remplacez callFunction par StringTools.format au lieu de StringTools.format.call. http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/Function.html#call%28%29 – sberry

1

Vous pouvez également faire quelque chose comme ça (bien sûr, ce n'est pas la meilleure mise en œuvre pour la mise en forme de chaîne):

public static function format(raw:String, ...rest:*):String { 
    if (rest[0] is Array && rest.length == 1) { 
     rest = rest[0]; 
    } 
    var r:RegExp = /(\{\d+\})/g; 
    var matches:Array = raw.match(r); 
    for (var i:Number = 0; i < rest.length; i++) { 
     raw = raw.replace(matches[i], rest[i]); 
    } 
    return raw; 
} 

Ensuite, votre fonction infof serait tout simplement ressembler à ceci:

public static function infof(raw:String, ...rest:*):void { 
    var formatted = StringTools.format(raw, rest); 
} 

Comme mentionné dans mon commentaire, si vous supprimez la méthode d'appel de la fin de votre callFunction setter, alors vous n'avez pas besoin de fournir null comme premier argument. Voir http://livedocs.adobe.com/ pour comprendre ce que la méthode d'appel fait réellement, et à quoi sert le premier paramètre. Comme mentionné ci-dessus, il est beaucoup plus simple de décaler votre var raw sur le tableau rest, plutôt que d'en créer un nouveau.

Questions connexes