2010-07-24 5 views
0

j'ai essayé d'ajouter une fonction de raffinement de répétition pour construire de balisage en utilisant la réponse précédente: How to bind to foreach context?Extension Build-marquage avec raffinement de répétition

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

    either not repeat [ 
     content: either string? content [copy content] [read content] 
     out: make string! 126 
     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) 
      ] 
     ] 
    ][   
     probe :block-fields 
     foreach :block-fields block-values [ 
      print get pick :block-fields 1 
      print get pick :block-fields 2 
     ] 
    ] 
    out 
] 

c: [a b] 
template: "<%a%> <%b%>" 
build-markup/repeat template :c [1 2 3 4] 

sortie est pas ce que je veux:

>> c: [a b] 
== [a b] 
>> template: "<%a%> <%b%>" 
== "<%a%> <%b%>" 
>> build-markup/repeat template :c [1 2 3 4] 
[a b] 
1 
1 a b 
1 
1 a b 

alors que je me serais attendu

1 
2 
3 
4 

Alors, comment dois-je correspondre ct?

Répondre

1

Pour:

words: [num] 
vals: [1 2 3] 

Lorsque vous utilisez foreach :words, vous créez un nouveau contexte pour lequel le bloc de répétition sera lié. Les contenus word! de :words ne sont pas réellement liés à ce nouveau contexte. Les valeurs que vous obtenez suggèrent 'a est globalement définie sur 1 et 'b sur . Pour illustrer:

>> num: 9     
== 9 
>> words: [num]   
== [num] 
>> foreach :words vals [ 
[ probe get 'num   
[ probe get first :words 
[ ]      
1 
9 
2 
9 
3 
9 
== 9 

Pour contourner ce problème, essayez d'imaginer que pour chaque itération de la boucle, le bloc qui est exécuté est 'bind -El dans le contexte de la boucle. Vous pouvez préempter la liaison comme ceci:

foreach :words vals probe compose/only [ 
    probe get first (words) 
] 

(sonde gauche à des fins d'illustration)

+0

Un grand merci, c'est exactement ce que je veux ré. Comme d'habitude j'ai besoin de temps pour comprendre le pourquoi :) –

0

semble fonctionner:

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

    out: make string! 126 

    either not repeat [ 
     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) 
      ] 
     ] 
    ][   

     actions: compose/only [ 
      set in system/words (to-lit-word pick (block-fields) 1) get pick (block-fields) 1 
      set in system/words (to-lit-word pick (block-fields) 2) get pick (block-fields) 2 
      probe get in system/words (to-lit-word pick (block-fields) 1) 
      probe get in system/words (to-lit-word pick (block-fields) 2) 
      append out build-markup content 

     ] 
     foreach :block-fields block-values actions   
    ] 
    out 
] 

template1: { <td><%a%></td><td><%b%></td> 
} 
template2: { <tr> 
<%build-markup/repeat template1 [a b] [1 2 3 4]%> 
    </tr> 
} 
template3: {<table> 
<%build-markup/repeat template2 [a b] [1 2 3 4 5 6]%> 
</table>} 
build-markup template3 

sortie:

== {<table> 
    <tr> 
    <td>1</td><td>2</td> 
    <td>3</td><td>4</td> 

    </tr> 
    <tr> 
    <td>1</td><td>2</td> 
    <td>3</td><td>4</... 
> 

>

Questions connexes