Rebol:为什么get-access-modifier被调用两次,而它应该只调用一次

时间:2010-07-01 21:24:54

标签: rebol

在rebol控制台中输入

do read http://askcodegeneration.com/csharp/simple-class/

我得到两次调用get-access-modifier:

Access modifier:
1. private: member can be accessed only by code in the same class
2. protected: member can be accessed only by code in the same class or in a derived  class
3. internal: member can be accessed only by code in the same assembly
4. public: member can be accessed by code in the same assembly or another assembly that references it choice (by default 1): 
Access modifier:
1. private: member can be accessed only by code in the same class
2. protected: member can be accessed only by code in the same class or in a derived  class
3. internal: member can be accessed only by code in the same assembly
4. public: member can be accessed by code in the same assembly or another assembly that references it choice (by default 1):

在源代码中只提到一次:

append fields-template-output form reduce [
    (to-word get-access-modifier) field-layout
]

我真的不明白为什么,可以吗?

Original code here (Internet Archive)

2 个答案:

答案 0 :(得分:1)

是。只有一个电话,但它在foreach内。您的默认值是两个字段,因此会被问两次。输入更多,您会被问到更多。

虽然你可以(并且可能应该)明确地将其保存在变量中,但Rebol还有其他方法。例如,您可以compose代码块:

foreach field-layout fields-layout COMPOSE/DEEP [
    append fields-template-output  "        "
    append fields-template-output  form reduce [
        to-word (get-access-modifier) field-layout
    ]
    append fields-template-output  ";"
    append fields-template-output  newline
]

组合运行一次,查看块中括号的深度,并评估代码。 (当它看到括号时,解析的方式)。剩下的就不管用了。因此,完成替换的块是传递给FOREACH以运行循环的块。

我建议不要将它用于这样的事情。

建议的是通过学习更多像ReJOIN这样的Rebol原语来研究在代码中减少冗余的东西......它构建了一个块的系列。系列类型将匹配它看到的第一个类型(如果第一个元素不是系列,则为字符串):

modifier: get-access-modifier ;-- called only once, stored in variable

foreach field-layout fields-layout [
    append fields-template-output rejoin [
        "        "
        (to-string modifier)
        field-layout
        ";"
        newline
    ]
]

答案 1 :(得分:0)

为了解决这个问题,我使用静态var检测它只执行一次(感谢Sunanda提示is it possible to have static variable inside a rebol function?)。

ask-params: function [config-file [file!] default-class-name default-fields] [
  ;config-file: %askcodegeneration.com/csharp/simple-class/simple-class.params.txt

  either value? 'class-name [
     ans: ask rejoin ["class name" " (by default " class-name ")" ": "]
     if ans <> "" [class-name: ans]
  ][
     class-name: default-class-name
     ans: ask rejoin [{class name (default "} class-name {"): }]
     if ans <> "" [class-name: ans]
  ]

  either exists? it: config-file [
      params-block: copy load it
  ][
      params-block: []
  ]

  either res: find params-block class-name [
      fields: pick res 2
      print [ class-name "found in" it]
  ][

      fields: default-fields
      ans: ask rejoin [{fields (by default } {"} fields {"} {): }]
      if ans <> "" [fields: ans]

      new-param: reduce [
      mold class-name
      mold fields
      ]

      either not exists? config-file [
          create-directory "askcodegeneration.com/csharp/simple-class/"
          write/append config-file reform new-param
      ][
          write/append config-file reform [newline new-param]
      ]

  ]
  append ret-value: [] class-name
  append ret-value fields

  ret-value
]