6

これはシェルレベルで機能します:

>> a: "hello" 
== "hello"
>> get to-lit-word "a"
== "hello"

しかし、次のような関数内では:

f: func [ arg1 ] [
    v1: get 'arg1
    ? v1
    v2: get to-lit-word "arg1"
    ? v2
]

>> f "goodbye"
V1 is a string of value: "goodbye"
** Script Error: arg1 has no value
** Where: f
** Near: v2: get to-lit-word "arg1"

「get」を使用して引数の値を取得するにはどうすればよいですか?

4

2 に答える 2

2

手始めに、そのような FUNC でv1v2を使用するときは、それらを囲んでいるコンテキストに書き込んでいることに言及します。したがって、それらは「グローバル変数」のように機能します。FUNC-spec に入れることを抑制するにはfunc [arg1 /local v1 v2]

(注: Rebol3 には、ローカルを自動的にスキャンし、基礎となる FUNC を構築する FUNCTION があります。しかし、FUNCTION は Rebol2 では別の意味を持っているため、FUNCT として利用できます。)


また、あなたが書いているときget 'aは、取得する必要のある言葉を渡していません。それらの明るさは、それらが検索されないようにするものですが、評価者がそれを実行すると...点灯した単語は単語になるように評価されます。

>> type? 'a
== word!

本当にリットワード引数を関数に渡したい場合は、それを引用する必要があります:

>> type? quote 'a
== lit-word!

GET は明らかに lit-word を渡すことを拒否しているわけではありませんが、より厳密に型指定されていればより明確になると思います。いずれにせよ、私はそれを次のように書きget to-word "a"ます。


私はおそらくあなたの主な質問に答えようとするのが悪い人です。ただし、最初のパターンでさえ Rebol 3 では機能しないことを指摘しておきます。

>> a: "hello"
== "hello"

>> get to-word "a"
** Script error: a word is not bound to a context
** Where: get
** Near: get to-word "a"

GET が単語から値を見つけられるようにするには、単に「単語である」だけでは十分ではありません。その単語は、「コンテキスト」として機能するオブジェクトにバインドする必要があります。バインディングは、単語自体に付随するプロパティです。

この点に関して、Rebol 2 は Rebol 3 とは少し異なる動作をします。しかし、情報の消防ホースが必要な場合は、トピックに関する投稿がいくつかあります。

Rebol 2 と 3 のバインディング動作の違いをまとめると、次のようになります。

to-word "some-string"多くの場合、代わりに と言った方がよかった場合でも、うまくいくことがわかりますload "some-string"。したがって、Rebol3 では次のようになります。

>> a: "hello"
== "hello"

>> get load "a"
== "hello"

これらの関数の引数は別の話のようです。変換された単語を、そのコンテキスト内で他の何かをクエリすることによって取得したコンテキストに手動でバインドできます。

f: func [arg1 /local dummy] [
    v2: get bind (to-word "arg1") (bind? 'dummy)
    ? v2
] 

>> f "goodbye"
V2 is a string of value "goodbye"

これは Rebol2 では機能しますが、クロージャーを使用しない限り Rebol3 では機能しません。

f: closure [arg1 /local dummy] [
    v2: get bind (to-word "arg1") (bind? 'dummy)
    ? v2
] 

>> f "goodbye"
V2 is a string of value "goodbye"

Rebol に関する不可思議なステートメント(「変数は存在しない、コロンは代入演算子ではない」など)のカテゴリに、 「Rebol には実際にはスコープがまったくない」を追加できます。

Rebol と Red の定義スコープに関する全体的な説明はありますか

詳細については、チャットで専門家に質問する必要があります...

于 2014-07-25T02:38:53.553 に答える
1

それが良いことのために、これは少し短くすることができます

>> f: func [ arg1] [
[    get bind to-word "arg1" 'arg1
[    ]
>> f "goodbye"
== "goodbye"
于 2014-07-25T13:52:34.287 に答える