共有変数を使ったらInvalid value for shared scalar at 〜になったでござる


今日も楽しくPerlをいじっていたら、実行中に、

Invalid value for shared scalar at ...

こんなエラー。




コードはこんな感じ。構文チェックは通る。

use threads;
use threads::shared;

my %h : shared =(
	x => {}
);

$h{x}->{y} = 1; 

Invalid value for shared scalar at - line 4.


ハッシュにsharedは使えるはずで、少し前にも試した。
なんでだろーなんでだろーと思いながら少しいじっていたら、少し状況が変わった。

use threads;
use threads::shared;

my %h =(
	x => {}
);

share(%h);

$h{x}->{y} = 1;

Invalid value for shared scalar at - line 10.


どういうことなの・・・
正しくない共有スカラーですか。そうですか。


エラー文で調べてみると、とてもわかりやすいところがHIT。
wakaponさんの備忘帳 | perl 共有変数 threads::shared リファレンス


ハッシュの値はスカラーで、リファレンス自体もスカラーであるけど、
リファレンスの参照先はHASH、ARRAY、SCALAR、CODE、GLOB...を取れるから、
もし、参照先に共有変数でないリファレンスを代入されたら、共有変数から共有変数でない値を参照・書換ができてしまうからですかね。

use threads;
use threads::shared;

my %h : shared =(
	x => &share({}), # 無名のハッシュのリファレンスも共有する
);

$h{x}->{y} = 1; # OK


shared_clone(...);という、
リファレンスの参照先をコピーし、リファレンスのリファレンスも共有変数にしたものを返すという、強力な関数もあるけど、
今入っているPerlは5.8.8で、threads::sharedのバージョン1.12ではサポートされていないようだった。