Rebol: почему get-access-modifier вызывается дважды, тогда как должен вызываться только один раз - PullRequest
0 голосов
/ 02 июля 2010

При наборе в консоли реболя

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
]

Я действительно не понимаю, почему, не так ли?

Оригинальный код здесь (интернет-архив)

Ответы [ 2 ]

1 голос
/ 02 июля 2010

Да.Есть только один вызов, но он внутри 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 для запуска цикла.

Просто нюанс того, как вы могли иметь вызов, который, кажется, находится внутри цикла и все же выполняетсятолько однажды.Я бы не предложил использовать его для чего-то подобного.

То, что я предложил бы , - это изучение того, как сделать вещи менее излишними в вашем коде, путем изучения еще нескольких примитивов Rebol, например REJOIN ...строит серию из блока.Тип серии будет соответствовать первому типу (или строке, если первый элемент не является серией):

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
    ]
]
0 голосов
/ 02 июля 2010

Для решения проблемы я использовал static var, чтобы определить, что он выполняется только один раз (благодаря советам Sunanda возможно ли иметь статическую переменную внутри функции rebol? ).

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