Here it is slightly clearer description of the problem, you cannot find out what the type is -- attributes calls the appropriate MODIFY handler and that is it, but you can't do FETCH-ing outside of the class, attributes::get will call the wrong FETCH based on caller
#!/usr/bin/perl --
use strict; use warnings;
use attributes();
use Data::Dump;
BEGIN {
package Junk;
$INC{'Junk.pm'}=__FILE__;
use Scalar::Util();
sub Junk::MODIFY_SCALAR_ATTRIBUTES {
print "Junk::MODIFY_SCALAR_ATTRIBUTES! @_\n";
my($package, $scalarref, @attrs) = @_;
$Junk::attrs{ Scalar::Util::refaddr $scalarref } = \@attrs;
return;
}
sub Junk::FETCH_SCALAR_ATTRIBUTES {
print "Junk::FETCH_SCALAR_ATTRIBUTES! @_\n";
my($package, $scalarref) = @_;
my $attrs = $Junk::attrs{ Scalar::Util::refaddr $scalarref };
return $attrs ? @$attrs : ();
}
}
BEGIN {
package Foo;
use Scalar::Util();
sub MODIFY_SCALAR_ATTRIBUTES {
print "Foo::MODIFY_SCALAR_ATTRIBUTES! @_\n";
my($package, $scalarref, @attrs) = @_;
$Foo::attrs{ Scalar::Util::refaddr $scalarref } = \@attrs;
return;
}
sub FETCH_SCALAR_ATTRIBUTES {
print "Foo::FETCH_SCALAR_ATTRIBUTES! @_\n";
my($package, $scalarref) = @_;
my $attrs = $Foo::attrs{ Scalar::Util::refaddr $scalarref };
return $attrs ? @$attrs : ();
}
sub MODIFY_REF_ATTRIBUTES {
print "Foo::MODIFY_REF_ATTRIBUTES! @_\n";
my($package, $scalarref, @attrs) = @_;
$Foo::attrs{ attributes::refaddr $scalarref } = \@attrs;
return;
}
sub FETCH_REF_ATTRIBUTES {
print "Foo::FETCH_REF_ATTRIBUTES! @_\n";
my($package, $scalarref) = @_;
my $attrs = $Foo::attrs{ Scalar::Util::refaddr $scalarref };
return $attrs ? @$attrs : ();
}
sub new {
print "Foo::new! @_\n";
my $class = shift;
return bless { yo => [@_] }, $class ;
}
}
sub FETCH_SCALAR_ATTRIBUTES {
print "\nCalling me is a mistake? bug?\n@_\n@{[caller]}\nSince the
+re is no object, you don't know type(package)\n\n";
return;
}
BEGIN { * FETCH_REF_ATTRIBUTES = \&FETCH_SCALAR_ATTRIBUTES ; }
my Junk $bar :STOOL :CHAIR = 42;
my Foo $new :AND :CHEWY = Foo->new( 42 );
for my $ref( \$bar, \$new ){
dd [ $ref, attributes::reftype( $ref ) , attributes::_guess_stash
+( $ref ) ],
[ attributes::get($ref) ],
[ attributes::_fetch_attrs($ref) ];;;
print "\n\n";
}
dd \%Junk::attrs , \%Foo::attrs;
__END__
Junk::MODIFY_SCALAR_ATTRIBUTES! Junk SCALAR(0xa38c14) STOOL CHAIR
Foo::new! Foo 42
Foo::MODIFY_SCALAR_ATTRIBUTES! Foo SCALAR(0xa38ca4) AND CHEWY
Calling me is a mistake? bug?
main SCALAR(0xa38c14)
attributes C:/perl/5.14.1/lib/MSWin32-x86-multi-thread/attributes.pm 9
+2
Since there is no object, you don't know type(package)
([\42, "SCALAR", undef], [], [])
Calling me is a mistake? bug?
main REF(0xa38ca4)
attributes C:/perl/5.14.1/lib/MSWin32-x86-multi-thread/attributes.pm 9
+2
Since there is no object, you don't know type(package)
([\bless({ yo => [42] }, "Foo"), "REF", undef], [], [])
(
{ 10718228 => ["STOOL", "CHAIR"] },
{ 10718372 => ["AND", "CHEWY"] },
)
|