上下文和属性的问题

时间:2010-08-02 19:14:02

标签: rebol

假设我想生成此输出:

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

来自下面的模板和自定义递归构建标记函数:

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

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

我的问题是避免最后一个元素与{+“,”+}

连接

我的想法是使用带有EOB属性(End Of Block)的context.build-markup,当处理最后一个元素时,该属性将设置为true。然后我可以使用上面的template-toString,而不是context.build-markup / EOB [{+“,”+}] [“”]连接或不连接{+“,”+}:

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
  ]

]

但我的尝试失败了(所以我评论说;设置为自我'EOB(i = n),因为它不起作用)。如何纠正代码以获得我想要的东西?

2 个答案:

答案 0 :(得分:2)

我很确定你能以比这更清洁的方式实现你的目标。无论如何,我可以告诉你为什么你在做什么不起作用!

n表达式length? block-fieldsrepeat循环上升到n。但block-fields包含单个参数[property]!因此,它从1循环到1。

想要想要针对枚举block-values(在此示例中范围从1到3)的内容进行测试,然后在索引达到3时唯一地处理它。换句话说,您的set in self 'EOB表达式必须是block-values而不是block-fields的枚举的一部分。

这会给你你想要的行为:

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

这绝对不行:

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

...因为您正在处理in均为1的情况,对于此循环的单次迭代。这意味着(i = n)是真的。因此,您为“行动”获得的元代码就是:

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

接下来,您使用多余的组合运行代码(因为没有PAREN!s,您可以省略COMPOSE / ONLY):

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

这显然会为您的actions元代码添加一行:

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

按照惯例,我建议您学会使用PROBE和PRINT来查看并检查每个阶段的期望。 Rebol很适合转储变量等......

答案 1 :(得分:0)

你似乎把简单的东西弄得很复杂:

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