2010-08-02 20 views
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"] 

我的問題是要避免最後一個要與{+「,」+}連接的元素

我的想法是使用帶EOB屬性(End Of Block)的context.build-markup,在處理最後一個元素時將設置爲true。然後我可以在模板的toString使用上面要麼不context.build的標記/ 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

我相當肯定,你可以在比這更清潔的方式來實現自己的目標。無論如何,我可以告訴你爲什麼你在做什麼不工作!

您的n是表達式length? block-fields,並且您的repeat循環上升到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 /只!):

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 
] 

按通常我會建議你學會使用探頭和PRINT看,並在每個階段檢查您的期望。 Rebol擅長傾銷變量等...

+0

謝謝你將進一步調試。 – 2010-09-05 11:40:02

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

如何設置自我'EOB(i = n)被認爲是複雜的? – 2010-08-03 18:05:42

+0

但是你的解決方案不起作用,我已經測試過了。問題是讓這些東西在編寫/僅使用的環境下工作,使用build-markup不使其獨立工作。 – 2010-08-03 18:07:31