В качестве общего замечания: строки легко превратить в WORD!s (например, to-word "foo"
). Однако магическим образом составить это СЛОВО может быть сложно! ссылка будет привязана к «переменной, которую вы имели в виду». Коварные причины этого связаны с тем фактом, что отсутствует область действия. Видеть:
Есть ли общее объяснение области определения в Rebol и Red
Так что то, что вы пытаетесь сделать, в любом случае будет немного хитрым. Есть лучшие способы. Но чтобы попытаться не задавать вопрос, я объясню, что здесь происходит и как это исправить в том стиле, в котором вы пытались это сделать.
исправленная версия предназначена только для учебных целей. пожалуйста, сделайте это другим способом.
compose rejoin [namelist/:i "f/text"]
REJOIN применяется к блокам и объединяет содержимое с типом результата свободно на основе первого элемента. (Это сомнительная операция, но исторически популярный в коде Rebol.)
Поскольку namelist/:i
является строкой, ваш REJOIN создаст строку... и эта строка будет передана в COMPOSE. Но COMPOSE предназначен для применения к BLOCK!s... и ищет группы в скобках внутри его, оценивая их, оставляя остальную часть кода в покое. Это своего рода система шаблонов для блоков, не влияющая на другие виды ввода... так что вы получите ту же самую строку.
Таким образом, TO-SET-PATH получает STRING! (например, "var1f/текст"). Я даже не знал, что преобразование пути принимает строки. Я нахожу поведение этой операции озадачивающим, потому что она, по-видимому, ЗАГРУЖАЕТ строку, а затем делает ее единственным элементом длины 1 SET-PATH!.
>> p: to-set-path "foo/bar"
== foo/bar: ;-- huh? really, did that work?
>> type? p
== set-path! ;-- ok, good, I guess.
>> length? p
== 1 ;-- wait, what?
>> type? first p
== path! ;-- a PATH! inside a SET-PATH!...?
>> length? first p
== 2
>> type? first first p
== word!
>> foo: 10
>> get first first p
== 10 ;-- well, at least it's bound
Это не делает вид SET-PATH! ты хочешь; вам нужен SET-PATH! с 2 СЛОВОМ! элементы. Преобразование БЛОКА! к SET-ПУТИ! был бы способ сделать это.
to-set-path compose [(load rejoin [namelist/:i "f"]) text]
Теперь мы видим, что COMPOSE используется правильно, где он запустит оценку внутри круглых скобок и оставит слово text
в покое. Это создает блок с двумя элементами, который легко преобразуется в SET-PATH!. Я использую LOAD вместо TO-WORD, чтобы позаботиться о некоторой «магии» подключения к реальной переменной, чего не может сделать преобразование простого слова. Но это всего лишь обходной путь — ненадежный способ, и он не всегда будет решением проблемы.
Но создание SET-PATH! не значит, что он работает. Если я скажу:
s: to-set-word "x"
probe type? s
НЕ SET-WORD! выполняется, он просто генерируется. И в этом случае хранится в переменной s. Но если бы я не сохранил его в переменной, оценочный продукт был бы просто выброшен... так же, как 2 просто выбрасывается, если я пишу 1 + 1 print "hi"
. Чтобы выполнить SET-PATH!, вам нужно поместить его в контекст, в котором он будет скомпонован в исходный код и оценен.
(Примечание: у Ren-C есть примитив под названием EVAL который может сделать это на лету, например, eval (quote x:) 10
присвоит 10 x.)
Но в Red вам нужно будет сделать что-то вроде этого:
namelist: ["var1" "var2"]
var1: 5
var2: 10
process: [
repeat i length? namelist [
do probe compose [
(to-set-path compose [(load rejoin [namelist/:i "f"]) text])
to-string
(load namelist/:i)
]
]
]
lay: layout [
text "Values to appear here: "
var1f: field "a"
var2f: field "b"
button "Click" [do process]
]
view lay
Теперь ваш внешний COMPOSE строит трехэлементный блок, где первый элемент будет SET-PATH!, а второй — WORD! это было буквально оставлено в покое, чтобы преобразовать ваше целое число в строку, а третье - в СЛОВО! который будет оцениваться до соответствующего целого числа. DO этого блока будет иметь эффект присваивания.
Я изменил to-word namelist/:i
на load namelist/:i
. Опять же, по причине, о которой я упоминал... TO-WORD сам по себе не является "привязкой".
Я оставил PROBE там, чтобы вы могли видеть, что строится и выполняется:
[var1f/text: to-string var1]
[var2f/text: to-string var2]
PROBE — очень полезный инструмент, который выводит свои аргументы, а также передает их. Вы можете вставить его в различные места вашего кода, чтобы лучше понять, что происходит.
(Примечание: если вам интересно, почему я не предлагаю написать узкую вспомогательную операцию EVAL-2, которая работает только для SET-PATH!, это потому, что существует такая штука с более подходящим названием. Она называется SET. Попробуйте. set (quote x:) 10
, затем print x
. На самом деле варианты этого - это то, как вы на самом деле хотите что-то делать... obj: make object! [a: 10]
, затем set (in obj 'a) 20
, затем print obj/a
. Как я уже сказал, есть намного лучшие способы делать то, что вы делаете, но я пытался сосредоточиться на том, чтобы делать это так, как вы пытались.)
person
HostileFork says dont trust SE
schedule
21.09.2017
var1
иvar2
по умолчанию для полей с кнопкой «Нажмите» для сброса, или вы намерены синхронизировать поля сvar1
иvar2
? Из вашего выбора имен не совсем ясно, каковы ваши намерения. - person rgchris   schedule 21.09.2017