Макет REBOL: как автоматически создавать слова макета - слово не имеет контекста?

Используя REBOL / View 2.7.8 Core, я хотел бы заранее подготовить макет представления, автоматически назначив слова различным элементам макета, как в следующем примере. Вместо

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

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

Что мне нужно сделать?


person jjr_    schedule 25.05.2016    source источник


Ответы (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

А затем вы можете использовать циклы для создания различных переменных для добавления в свой макет.

person Graham Chiu    schedule 25.05.2016

Когда вы используете 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.

person HostileFork says dont trust SE    schedule 25.05.2016
comment
... поэтому я просто меняю append prepared-view2 to-block cbi на _2 _... да, это работает! - person jjr_; 25.05.2016