2014-12-24 5 views
2

В следующем коде, можно присвоить результат GET-WORD р через SET-WORD, а затем использовать его под новым именем:Как избежать вызова функции в условиях COMPOSE?

p: :print 
p [{Hello} {World}] 

Но что, если вы используете сочинить, и вы находите такую ​​ситуацию?

do compose [p: (:print)] 
p [{Hello} {World}] 

Это дает ошибку:

*** ERROR 
** Script error: -unnamed- is missing its value argument 
** Where: do 
** Near: do compose [p: (:print)] p ["Hello" "World"] 

Так как значения функции в блоке «живет», когда видел в интерпретаторе ... были ли они неправдоподобными как оценочный результат или нет. (Казалось бы, они должны быть инертными, если извлекается или не применяется так или иначе, в противном случае такие назначения не представляется возможным изнутри сочинить или аналогичный.)

Кажется, вы должны процитировать прибудете слов, таких как:

do compose [p: (quote :print)] 
p [{Hello} {World}] 

Это может сделать трюк, чтобы сделать функцию печати. Но можете ли вы сделать это, не пройдя GET-WORD или аналогично прокси?

ответ

3

Да, вы можете «разоружить» активную функцию!значение с особенностью DO-говор:

>> do probe compose [p: quote (:print)] 
[p: quote make native! [[ 
     "Outputs a value followed by a line break." 
     value [any-type!] "The value to print" 
    ]]] 

>> p [{Hello} {World}]     
Hello World 

Они Ключевым моментом здесь является аргументом, проходящий специальный режим, используемый для одного аргумента Цитата:

>> source quote 
quote: make function! [[ 
    "Returns the value passed to it without evaluation." 
    :value [any-type!] 
][ 
    :value 
]] 

Этот аргумент режим прохождения, лишено воображения называется «получить аргументы ", запрещает оценку значения аргумента. Поэтому в нашем конкретном случае он предотвращает «активный» характер функции! ценность.

Для получения дополнительной информации о режимах передачи аргументов вы можете ознакомиться с этим недавним treatise about literal and get arguments, в котором сравниваются различия между Rebol 2 и Rebol 3, чтобы дать историческую перспективу.

+0

Хорошо, чтобы указать. Я не думал процитировать цитату вне круглых скобок, и это лучше, чем другие способы, которыми я занимался. Хотя мой технический вопрос конкретно, если я могу помещать в круглые скобки COMPOSE и снаружи, чтобы разоружить его, так что ответ (по крайней мере, на то, что я хотел спросить) - «нет». – HostileFork

+1

Нет, вы, конечно, не можете. Потому что это не КОМПОЗ, а «оружие». Для COMPOSE активные и неактивные значения не существуют в качестве различия. Это только одна особенность диалекта DO, которую вы затем явно вызываете через DO. – earl

+1

Мне кажется, что то, что вы на самом деле хотите сделать, представляет собой сплайсинг значения в блок и требует, чтобы это значение было «неактивным» в отношении диалекта DO. В этом конкретном примере вы хотите, чтобы вы могли быть уверены, что значение всегда будет назначаться в контексте предыдущего заданного слова !. Чтобы достичь этого, вы должны создать такую ​​же конструкцию, которая имеет желаемую семантику на диалекте DO, или выполнить контроль над окружающим кодом (например, введя QUOTE в нужном месте, как в моем ответе). – earl

0

Первый вопрос: зачем вам это нужно?

Потому что он работает без составления.

Do [p: :print] 
P 1 

И без GET-слова

Do [p: get first [print]] 

Edit:

Я не понимаю последствия для C++ связывания, но «Compose используется для оценки части блока выборочно , В вашем примере вы хотите оценить часть, но все еще хотите, не оцениваются, так что вам не нужно, чтобы остановить его от оцениваемых слишком рано, например:

do compose [p1: (to get-word! 'x)] 

Если вы хотите использовать COMPOSE, и не выйдут -/освещено слово !, вы можете попробовать цитаты:

do compose [p4: get quote (quote print)] 

внутренней печать «назначенные охранниками из оцениваемых в композе, внешние один охранники durng«сделать так, чтобы»получить можно получить значение.

+0

Он влияет на назначение значений функций в [привязке C++] (https://github.com/hostilefork/rencpp/blob/09dca1a36737a2445de62b2b05ed10019a18e436/examples/extension-test-1.cpp). Я сформулировал это здесь более широко, если вы что-то сочиняете и хотите, чтобы результат попал в задание. – HostileFork

+0

Я все еще не уверен, что понимаю реальный вопрос, но я отредактировал свой первоначальный ответ. – ingo

2

Используйте следующий способ создать Get-слово, он покупает вам дополнительный уровень косвенности:

>> do compose [p: (to-get-word 'print)] 
>> p [{Hello} {World}] 
Hello World 

Если вы хотите присваивание быть сделано с помощью DO [...] формы, то вам нужно слово, назначенное анонимной функции, чтобы управлять им пассивным способом.

Альтернативным вариантом является выполнить задание за пределами блока, состоящего:

p: first compose [(:print)] 
+0

Если вы хотите, чтобы назначение выполнялось с использованием формы DO [...], тогда да, вам нужно слово, назначенное анонимной функции, чтобы управлять им пассивным способом. Альтернативным вариантом является выполнение задания вне сложенного блока: ** p: сначала составить [(: print)] **. – DocKimbel