172 :
営利利用に関するLR審議中@詳細は自治スレへ :
2012/04/07(土) 01:50:55.99 ハッシュにblessしたオブジェクトのプロパティに対してlvalue属性つきのサブルーチンを用意しようとしています。 単純なアクセサなので呼び出されたときにAUTOLOADで補足してインストールするようにしています。 package Config; sub new { my ($class) = @_; bless { name => 'foo', }, $class; } sub AUTOLOAD { no strict 'refs'; my ($self) = @_; our $AUTOLOAD; if ($AUTOLOAD =~ /.*::(.*)\z/) { *$AUTOLOAD = sub : lvalue { my ($self) = @_; $self->{$1}; }; } goto &$AUTOLOAD; } sub DESTROY {} # 一応・・ package main; my $obj = Config->new; print $obj->name,"\n"; #=>'foo' $obj->name = 'bar'; print $obj->name,"\n"; #=>'bar' これは正常に動作しますが、mainパッケージの最初のprint文をコメントアウトした場合や 新たなプロパティをセットしようとした場合↓にはAUTOLOADが呼ばれず(AUTOLOADに行く前に?)エラーとなります。 $obj->update = '2012/4/8'; => Can't modify non-lvalue subroutine call at... 回避方法あるでしょうか?
173 :
172 :2012/04/07(土) 02:55:30.64
投稿の際に行数を節約しようと修正した部分で動かないところがありました ×*$AUTOLOAD = sub : lvalue { my ($self) = @_; $self->{$1}; }; my $name = $1; *$AUTOLOAD = sub : lvalue { my ($self) = @_; $self->{$name}; };
package _Config; our $AUTOLOAD; sub new { bless { name => 'foo' }, shift } sub AUTOLOAD : lvalue { my ($self) = @_; (my $name = $AUTOLOAD) =~ s/.*://; my $sub = sub : lvalue { shift->{$name} }; { no strict 'refs'; *{$AUTOLOAD} = $sub; } $self->$name(); } sub DESTROY {} ここまで来ると普通のハッシュでよくね? あと、ネタすれなんで、本スレで質問しる。