【问题标题】:Extending Build-markup with repeat refinement通过重复细化扩展构建标记
【发布时间】:2010-07-24 19:14:31
【问题描述】:

我尝试使用上一个答案向 build-markup 函数添加重复优化: How to bind to foreach context?

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]

输出不是我想要的:

>> 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

正如我所预料的那样

1
2
3
4

那我应该怎么改正呢?

【问题讨论】:

    标签: rebol


    【解决方案1】:

    为:

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

    当您使用foreach :words 时,您正在创建一个新的上下文,重复块将绑定到该上下文。 :wordsword! 内容实际上并未绑定到这个新上下文。您得到的建议值 'a 全局设置为 1,'b 设置为 [a b]。举例说明:

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

    要解决这个问题,请尝试想象对于循环的每次迭代,执行的块是'bind-ed 到循环上下文。您可以像这样抢占绑定:

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

    (为了说明目的留下了探针)

    【讨论】:

    • 非常感谢,这正是我想要的。像往常一样,我需要一些时间来了解原因:)
    【解决方案2】:

    似乎有效:

    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
    

    输出:

    == {<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</...
    >
    

    >

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-09
      • 2022-11-21
      • 1970-01-01
      相关资源
      最近更新 更多