いいえ、ブロック (プロシージャ、ラムダ) は独自のスレッドでは実行されません。ここでの問題は、Ruby が$SAFE
すべてのメソッド (および proc) 呼び出しの前後でレベルを保存および復元することです。のような別の変数でこれを試すと$FOO
、期待どおりの結果が得られます。
> x = ->{ $FOO = 1; puts $FOO }.call; puts $FOO
1
1
これが実装されている場所を次の場所で確認できrb_method_call
ますproc.c
。
const int safe_level_to_run = 4 /*SAFE_LEVEL_MAX*/;
safe = rb_safe_level();
if (rb_safe_level() < safe_level_to_run) {
rb_set_safe_level_force(safe_level_to_run);
}
// ...
// Invoke the block
// ...
if (safe >= 0)
rb_set_safe_level_force(safe);
セーフ レベルが保存され、4 未満の場合は 4 に設定されます。その後、ブロックが呼び出され、変更前のセーフ レベルが >= 0 の場合は、以前のレベルに戻されます。次のようなものを使用して、これを実際に確認できます。
> puts $SAFE; ->{ puts $SAFE; $SAFE = 1; puts $SAFE }.call; puts $SAFE
0
0
1
0
$SAFE
はブロックに向かって 0 であり、ブロックが実行され、ブロック内で 1 になるように変更されているにもかかわらず、ブロックが終了すると 0 に戻ります。