以下が機能しない理由は何ですか?(R3)
o: make object! [
foo: does [do "bar"]
bar: does [print "hello from bar"]
]
o/foo
** Script error: bar has no value
** Where: catch either -apply- do foo
** Near: catch/quit either var [[do/next data var]] [data]
これを試して:
o: make object! [
foo: does [do get bind load "bar" self]
bar: does [print "hello from bar"]
]
o/foo ;this will work
「バー」はグローバルスコープではなくオブジェクトに存在するため、そのバインドが必要です。
これもチェックしてください:
my-func: does [print "ok"]
o: make object! [
foo: does [do "my-func"]
bar: does [print "hello from bar"]
]
o/foo ;this will work too
文字列なのでLOADする必要がありますが、バインドするには単語でなければなりません。したがって、これらも機能します(オブジェクトに入れます):
do get bind to-word "bar" self
また
do get bind 'bar self
「self/bar」が 'BAR の場所を認識できない理由は、Rebol に範囲がないためです(少なくとも従来の CS の意味ではありません)。
Rebol の単語は、静的にコンテキストにバインドされて初めて意味を持ちます。これはオブジェクトを「作る」ときに自動的に発生するため、多くの人は何年も使用した後でも気付かない.
仕様内のすべてのルート セット ワードを取得します (この場合は [FOO: BAR:] )。
それらを現在の内部単語に追加します(SELF:デフォルトでは、オブジェクトをベースとして使用している場合はさらに)
次に、ブロック内のすべての単語を (階層的に) 仕様に追加したセット単語にバインドします。
ブロックを実行します。
ご覧のとおり、ブロックを実行するのが遅すぎると、単語にはすでに意味が割り当てられており、インタープリターが値を要求できるようになっています (これにより、式の評価がトリガーされる可能性があるため、REBOL の E になります)。
DO と LOAD は、グローバル コンテキスト以外に自動的にバインドすることはできません。従来の OOP や命令型言語のような「現在のコンテキスト」は存在しないためです (スコープがないことを思い出してください)。実際、一度実行すると、「現在の」コンテキストを単語にバインドしない限り、その情報はもう存在しません...これは 'SELF が行うことですが、バインドするには、実行時に既にロードされている必要があります。文字列、一度も発生しませんでした。
一見するとわかりにくいかもしれませんが、Object spec ブロックをバインドしている間は、FOO と BAR が実際に何であるかはまだわかりませんでした。実際、FOO と BAR が 'O オブジェクトにアクセスできる唯一の方法は、関数ブロックが 'MAKE を介して実行されたときにオブジェクトにバインドされたためです...そうです、それが関数であることを認識する前に。次に、関数が独自のローカルを定義した場合、そのボディブロックをそれらの新しいローカルに再バインドします..あなたが推測したため...関数は独自の内部コンテキストを作成し、同じ MAKE 処理を取得します(ただし、内部 SELF なし)語)。
これが、より明白な観点から物事を明確にするのに役立つことを願っています.
コードがスコープされていないことの証明は次のとおりです。
a: make object! [
data: "HAHAHAAAAA!!!"
action: does [print self/data]
]
b: make object! [
data: "BUMBLING BEHEMOT"
action: does [print self/data]
]
b/action: get in a 'action
; this will print HAHAHAAAAA!!!
b/action
moliadの答えをもう少し説明するには、次の説明を参照してください。
REBOLの単語には、それらのコンテキストへの参照が含まれています。違いを生むのは単語が評価される場所ではなく、それが宣言される場所です。
http://blog.revolucent.net/2009/07/deep-rebol-bindology.htmlから
これは非常に良い例です:
x: 0
b: [] loop 3 [use [x] [x: random 100 append b 'x]]
;== [x x x] <-- there are three X which looks same words (and they are same actually)
reduce b
;== [95 52 80] <-- but they have different values in their contexts
probe x
;== 0 <-- in global context, it has another value as well
これは一見奇妙に見えますが、実際はそうではありません。USEは、LOOPで毎回新しいコンテキストを作成し、X(USEが作成したコンテキストで)を値に設定してから、WORD(値ではありません!)をブロックに追加します。ブロックに追加するすべての単語は、独自のコンテキストを持っていますが、同じ単語に見えます。
REDUCE(またはPRINTなど)するとき、独自のコンテキストでそれらの値を取得するとき、それらはすべて異なる値を持っていることがわかります!