2014-05-15 9 views
3

map-each может быть использован для оценки какого-то кода для каждого элемента в коллекции, а также агрегировать результаты оценки в блоке:Почему map-each сохраняет последнее значение для ссылок на заданное слово?

>> values: map-each x [1 2] [ 
    print ["Doing mapping for" x] 
    x * 10 
    ] 
Doing mapping for 1 
Doing mapping for 2 
== [10 20] 

я строил блок блоков таким образом. Но я забыл, что, поскольку блоки не вычисляются по умолчанию x не останется, как есть, и не получить значение я хотел:

>> blocks: map-each x [1 2] [ 
    print ["Doing mapping for" x] 
    [x * 10] 
    ] 
Doing mapping for 1 
Doing mapping for 2 
== [[x * 10] [x * 10]] 

никаких сюрпризов. После оценки x не имеет значения - гораздо меньше, способность брать на себя многие ценности:

>> probe x 
** Script error: x has no value 

Так что это слишком поздно, оценка должна быть сделана с УМЕНЬШИТЬ или COMPOSE внутри тела карты-каждый. Но ...

>> reduce first blocks 
== [20] 

>> reduce second blocks 
== [20] 

Оценки элементов в результирующем блоке не выдаст ошибку, но вести себя так, как будто x имел значение последней итерации.

Как это делается? Должно ли это быть этим?

+1

Похоже, что блок по-прежнему связан с анонимным контекстом, созданным картой, и поэтому x сохраняет последнее значение. –

ответ

3

Так же, как «FOREACH» MAP-КАЖДОЙ связывает блок вы даете его в контексте он создает и выполняет его там.

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

по этой причине X используется в вызове к карте, каждый не задействует

** Script error: x has no value 

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

Чтобы проиллюстрировать, как привязка работает более ярко и показать, как «X может пережить существование за ее исходным контекстом, вот пример, который иллюстрирует основание того, как слова связаны в Rebol (и тот факт, что это связывание сохраняется).

взгляд на этот пример:

a: context [x: "this"] 
b: context [x: "is"] 
c: context [x: "sensational!"] 

>> blk: reduce [in a 'x in b 'x in c 'x] 
== [x x x] 

x: "doh!" 
== "doh!" 

>> probe reduce blk 
["this" "is" "sensational!"] 

Мы создали единый блок с тремя «X словами, но ни один из них не связаны с тем же контекстом.

Поскольку привязка в Rebol статична, а область видимости не существует, одно и то же слово может иметь разные значения, даже когда они обрабатываются в одном контексте (в этом случае консоль является глобальным контекстом пользователя) ,

Это предпоследний пример того, почему слово действительно НЕ является переменной в Rebol.

+0

примечание: мой ответ немного больше исходного вопроса, но он дает немного больше информации о том, как Rebol работает внутри, что может быть более полезным для новичков. – moliad

3
blocks: map-each x [1 2] [ 
    print ["Doing mapping for" x] 
    [x * 10] 
] 

probe bound? first blocks/1 

придает этому

Doing mapping for 1 
Doing mapping for 2 
make object! [ 
    x: 2 
]