調べたので自分用のメモ。
perldeltaを見てみると、以下のように書いてます。perl5.10.xから、シンボルテーブルにリファレンスを入れるタイプの定数の実装もあるみたいです*1。
The interpreter internals now support a far more memory efficient form of inlineable constants. Storing a reference to a constant value in a symbol table is equivalent to a full typeglob referencing a constant subroutine, but using about 400 bytes less memory.
サンプルコード。なるほど。
use strict; use warnings; BEGIN { $main::{FOO} = \'foo foo'; } print FOO, "\n"; __END__ 実行結果: foo foo
constant.pm 的には以下のようなコードが。これを見る限りは、上のようなコードは気軽に使わない方がいいのかもしれないです。
# The constant serves to optimise this entire block out on # 5.8 and earlier. if (_CAN_PCS && $symtab && !exists $symtab->{$name}) { # No typeglob yet, so we can use a reference as space- # efficient proxy for a constant subroutine # The check in Perl_ck_rvconst knows that inlinable # constants from cv_const_sv are read only. So we have to: Internals::SvREADONLY($scalar, 1); $symtab->{$name} = \$scalar; ++$flush_mro; }
ちなみに、この動作のせいでシンボルテーブルには型グロブ以外も入っているので、以下のコードは5.8.xでは動きましたが、5.10.x以降のperlではエラーとなりました*2。
use strict; use warnings; use constant FOO => 'foo foo'; print *{$::{FOO}}{CODE}->(), "\n"; __END__ 結果(5.12.1): Not a GLOB reference at - line 4.