上下文和属性问题

发布于 2024-09-12 16:55:29 字数 2529 浏览 2 评论 0原文

假设我想生成以下输出:

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

我的问题是避免最后一个元素与 {+ "," +} 连接

我的想法是使用 context.build -带有 EOB 属性(块结束)的标记,当处理最后一个元素时,该属性将设置为 true。然后我可以在上面的 template-toString 中使用 not 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
  ]

]

但我的尝试失败了(所以我评论了 ;set in self 'EOB (i = n) 因为它不起作用)。如何更正代码以获得我想要的?

Let's say I want to generate this output:

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

from the template below and a custom recursive build-markup function:

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

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

My problem is to avoid the last element to be concatenate with {+ "," +}

My idea was to use a context.build-markup with an EOB property (End Of Block) that would be set to true when last element is processed. Then I could use in template-toString above either not context.build-markup/EOB [{+ "," +}][""] to concatenate or not with {+ "," +} :

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
  ]

]

But my attempt failed (so I commented ;set in self 'EOB (i = n) because it doesn't work). How to correct the code to get what I want ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

昔梦 2024-09-19 16:55:29

我非常确定您可以通过比这更干净的方式实现您的目标。无论如何,我可以告诉你为什么你所做的事情不起作用!

你的n是表达式长度? block-fields,并且您的 repeat 循环将上升到 n。但是block-fields包含单个参数[property]!因此,它从 1 循环到 1。

大概想要测试枚举块值(在本例中范围为 1 到 3)的内容,然后处理它如果索引达到 3,则唯一。换句话说,您的 set in self 'EOB 表达式需要成为 block-values 枚举的一部分,而不是 block-字段

这会给你你想要的行为:

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) 为真。因此,您获得的“actions”元代码是这样的:

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

接下来,您使用多余的组合运行代码(因为没有 PAREN!,您可以省略 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 擅长转储变量等......

I'm quite certain you could be achieving your goal in a cleaner way than this. Regardless, I can tell you why what you're doing isn't working!

Your n is the expression length? block-fields, and your repeat loop goes up to n. But block-fields contains the single parameter [property]! Hence, it loops from 1 to 1.

You presumably wanted to test against something enumerating over block-values (in this example a range from 1 to 3) and then handle it uniquely if the index reached 3. In other words, your set in self 'EOB expression needs to be part of your enumeration over block-values and NOT block-fields.

This would have given you the behavior you wanted:

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

This absolutely won't work:

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

...because you are dealing with a situation where i and n are both 1, for a single iteration of this loop. Which means (i = n) is true. So the meta-code you get for "actions" is this:

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

Next you run the code with a superfluous composition (because there are no PAREN!s, you could just omit COMPOSE/ONLY):

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

Which adds a line to your actions meta-code, obviously:

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

As per usual I'll suggest you learn to use PROBE and PRINT to look and check your expectations at each phase. Rebol is good about dumping variables and such...

柠檬 2024-09-19 16:55:29

你似乎把简单的事情变得非常复杂:

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

You seem to making something simple very complicated:

>> 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文