REBOL layout: Как создать макетные слова автоматически - слово не имеет контекста?
Используя ядро REBOL/View 2.7.8, я хотел бы заранее подготовить макет представления, автоматически назначая слова различным элементам макета, как в следующем примере. Вместо
prepared-view: [across
cb1: check
label "Checkbox 1"
cb2: check
label "Checkbox 2"
cb3: check
label "Checkbox 3"
cb4: check
label "Checkbox 4"
]
view layout prepared-view
Я хотел бы таким образом слова cb1
через cb5
создаваться автоматически, например:
prepared-view2: [ across ]
for i 1 4 1 [
cbi: join "cb" i
cbi: join cbi ":"
cbi: join cbi " check"
append prepared-view2 to-block cbi
append prepared-view2 [
label ]
append prepared-view2 to-string join "Checkbox " i
]
view layout prepared-view2
Однако пока difference prepared-view prepared-view2
не показывает различий в анализируемом блоке (== []
), второй скрипт приводит к ошибке:
** Script Error: cb1 word has no context
** Where: forever
** Near: new/var: bind to-word :var :var
Я часами пытался понять, почему, и я думаю, что каким-то образом новые слова должны быть связаны с конкретным контекстом, но я пока не нашел решения этой проблемы.
Что мне нужно сделать?
2 ответа
bind prepared-view2 'view
view layout prepared-view2
создает правильные привязки.
И вот еще один способ динамически создавать макеты
>> l: [ across ]
== [across]
>> append l to-set-word 'check
== [across check:]
>> append l 'check
== [across check: check]
>> append l "test"
== [across check: check "test"]
>> view layout l
И затем вы можете использовать циклы для создания различных переменных, чтобы добавить их в свой макет.
Когда вы используете TO-BLOCK для преобразования строки в блок, это низкоуровневая операция, которая не проходит через "обычную" привязку к контекстам "по умолчанию". Все слова будут свободны:
>> x: 10
== 10
>> code: to-block "print [x]"
== [print [x]]
>> do code
** Script Error: print word has no context
** Where: halt-view
** Near: print [x]
Поэтому, когда вы хотите собрать код из необработанных строк во время выполнения, поиск которых будет работать, одним из вариантов является использование LOAD, и он будет выполнять что-то по умолчанию, и это может сработать для некоторого кода (загрузчик показывает, как были сделаны привязки для код, который вы запускаете, который пришел из источника):
>> x: 10
== 10
>> code: load "print [x]"
== [print [x]]
>> do code
10
Или вы можете назвать контексты / объекты явно (или с помощью примерного слова, связанного с этим контекстом) и использовать BIND.