2010-08-02 2 views
0

Disons que je veux générer cette sortie:problème avec le contexte et la propriété

public String toString() { 
     return this.getFirstName() + "," + this.getLastName() + "," + this.getAge(); 
    } 

du modèle ci-dessous et une fonction build-markup récursive personnalisée:

template-toString: {this.get<%property%>() <%either not context.build-markup/EOB [{+ "," +}][""]%> } 

    build-markup/vars template-toString [property] ["FirstName" "LastName" "Age"] 

Mon problème est d'éviter la dernier élément à concaténer avec {+ "," +}

Mon idée était d'utiliser un context.build-markup avec une propriété EOB (End Of Block) qui serait définie sur true lorsque le dernier élément est traité. Ensuite, je pourrais utiliser dans le modèle ci-dessus-toString soit pas context.build balisage/EOB [{+ "" +}] [ ""] à concaténer ou non avec {+ "" +}:

context.build-markup: context [ 

    EOB: false 

    set 'build-markup func [ 
     {Return markup text replacing <%tags%> with their evaluated results.} 
     content [string! file! url!] 
     /vars block-fields block-values 
     /quiet "Do not show errors in the output." 
     /local out eval value n max i 
    ][ 

    out: make string! 126 

    either not vars [ 
     content: either string? content [copy content] [read content] 

     eval: func [val /local tmp] [ 
      either error? set/any 'tmp try [do val] [ 
       if not quiet [ 
        tmp: disarm :tmp 
        append out reform ["***ERROR" tmp/id "in:" val] 
       ] 
      ] [ 
       if not unset? get/any 'tmp [append out :tmp] 
      ] 
     ] 
     parse/all content [ 
      any [ 
       end break 
       | "<%" [copy value to "%>" 2 skip | copy value to end] (eval value) 
       | copy value [to "<%" | to end] (append out value) 
      ] 
     ] 
     ][   


      n: length? block-fields 

      self/EOB: false 

      actions: copy [] 

      repeat i n [ 



      append actions compose/only [ 

       ;set in self 'EOB (i = n) 
       set in system/words (to-lit-word pick (block-fields) (i)) get pick (block-fields) (i) 
      ] 

      ] 
      append actions compose/only [    
       append out build-markup content    
      ] 
      foreach :block-fields block-values actions 



      if any [(back tail out) = "^/" (back tail out) = " " (back tail out) = "," (back tail out) = ";" (back tail out) = "/" (back tail out) = "\"] [ 
      remove back tail out 
      ]   
     ] 
     out 
    ] 

] 

Mais ma tentative a échoué (donc j'ai commenté, mis en self 'EOB (i = n) parce que ça ne marche pas). Comment corriger le code pour obtenir ce que je veux?

Répondre

2

Je suis tout à fait certain que vous pourriez atteindre votre objectif d'une manière plus propre que cela. Quoi qu'il en soit, je pouvez vous dire pourquoi ce que vous faites ne fonctionne pas!

Votre n correspond à l'expression length? block-fields et votre boucle repeat à n. Mais block-fields contient le seul paramètre [property]! Par conséquent, il boucle de 1 à 1.

Vous probablement voulait tester contre quelque chose sur block-values énumération (dans cet exemple une plage de 1 à 3), puis le traiter uniquement si l'indice atteint 3. En d'autres termes , votre expression set in self 'EOB doit faire partie de votre énumération sur block-values et NON block-fields.

Cela vous aurait donné le comportement que vous vouliez:

n: length? block-values 
i: 1 
foreach :block-fields block-values compose/only [ 
    set in self 'EOB equal? i n 
    do (actions) 
    ++ i 
] 

Ce absolument ne fonctionnera pas:

append actions compose/only [ 
    set in self 'EOB (i = n) 
    set in system/words (to-lit-word pick (block-fields) (i)) get pick (block-fields) (i) 
] 

... parce que vous avez affaire à une situation où i et n sont both 1, pour une seule itération de cette boucle. Ce qui signifie (i = n) est vrai. Ainsi, le méta-code que vous obtenez pour « actions » est la suivante:

[ 
    set in self 'EOB true 
    set in system/words 'property get pick [property] 1 
] 

Ensuite, vous exécutez le code avec une composition superflue (car il n'y a pas PAREN s, vous pouvez simplement omettez COMPOSER/SEULEMENT!):

append actions compose/only [ 
    append out build-markup content 
] 

qui ajoute une ligne à votre actions méta-code, évidemment:

[ 
    set in self 'EOB true 
    set in system/words 'property get pick [property] 1 
    append out build-markup content 
] 

Comme d'habitude, je vous suggère d'apprendre à utiliser la sonde et PRINT pour regarder et vérifier vos attentes à chaque phase. Rebol est bon sur le dumping des variables et ...

+0

Merci débogage plus loin. –

0

Vous semblez faire quelque chose de simple très compliqué:

>> a: make object! [       
[ b: false     
[ set 'c func[i n] [b: i = n] 
[ ] 
>> a/b 
== false 
>> c 1 4 
== false 
>> a/b 
== false 
>> c 1 1 
== true 
>> a/b 
== true 
+0

Comment définir dans self 'EOB (i = n) est soi-disant compliqué? –

+0

Mais votre solution ne fonctionne pas, je l'ai testé. Le problème est de faire fonctionner ces choses dans le contexte de composer/only et build-markup de ne pas le faire fonctionner de manière autonome. –

Questions connexes