2013-08-09 11 views
9

Celem poniższej funkcji jest zwrócenie ciągu znaków zawierającego wartość argumentu między dwiema gwiazdami.Co dokładnie się stało, gdy nie używasz "copy" do obsługi ciągu znaków?

star-name: func [name /local stars] [ 
    stars: "**" 
    insert next stars name 
    stars 
] 
print star-name "test" ;*test* 
print star-name "this" ;*thistest*, but what I really want is *this* 

Po drugim wywołaniu funkcji, argument pierwszego wywołania nadal pozostaje wstawiony. Wiem, że odpowiedzią jest użycie copy "**". Moje pytanie brzmi, czy nie przypisuje ponownie zmiennej stars do "**" za każdym razem, gdy wywoływana jest funkcja?

Odpowiedz

6

W przypadku funkcji jest tylko jedna „**” definicja ciąg. Ta definicja jest używana tylko raz przez funkcję Rebol load, ponieważ load jest uruchamiana tylko raz, aby przetłumaczyć kod na wewnętrzną postać Rebola - blok. Prawdą jest, że przypisanie występuje dwa razy, jeśli wywołuje się funkcję dwa razy, ale przydział nie tworzy niczego, tylko sprawia, że ​​zmienna odnosi się do tego samego ciągu ponownie.

W swoim komentarzu powinieneś zauważyć, że faktycznie masz dwie "**" definicje ciągów prowadzące do utworzenia dwóch ciągów przez load. Jeśli używasz

code: [stars: "**" insert next stars something] 
something: "this" 
do code 
something: "that" 
do code 

można zauważyć, że istnieje tylko jedna definicja sznurek i gdy nie ma żadnej funkcji zachowanie jest takie samo jak to było, gdy funkcja została wykorzystana.

+0

Myślę, że mam pomysł. W Rebol funkcje są po prostu blokami. Jest zupełnie inny niż funkcje w innych językach. Wielkie dzięki :) –

+0

Jakiś wgląd w to, dlaczego Rebol zachowuje się w ten sposób: [Czy Rebol to czysty język funkcjonalny] (http://www.rebol.com/article/0206.html) – rgchris

2

Jeśli używasz set-word dla serii, domyślnym zachowaniem jest przydzielenie pamięci dla tej serii tylko jeden raz. To pozwala ci użyć tego jako zmiennej statycznej, która utrzymuje się między wywołanymi funkcjami.

Jeśli nie chcesz tego zachowania, musisz jawnie skopiować serię, aby za każdym razem utworzyć nową serię.

Jest to kolejny sposób można to zrobić jak gwiazdy lokalna nie jest wymagane

star-name: func [ name ][ 
    rejoin [ "*" name "*" ] 
] 
+0

Czy to funkcja funkcji? Ponieważ po prostu piszę: 'gwiazdki:" ** "wstaw następną gwiazdkę" to "drukuj gwiazdki gwiazd:" ** "wstaw następną gwiazdkę", że "gwiazdy druku", nie mają powyższego problemu. –

+1

W tej wersji masz teraz dwie różne serie na dwóch różnych adresach pamięci. –