I'm trying to write a basic object class for a program I'm writing, and this class will automatically generate getter/setter methods for members given to new using AUTOLOAD. I want it so if a method already exists with the name of a member, the new method will warn them unless the attribute "override" is attached to that method. So here's my code:
#!/usr/bin/perl # Object.pm package Pixie::Object; use strict; use warnings; require v5.6.0; use attributes (); use Exception::Class ('PrivateFieldException' => {isa => 'Exception::C +lass::Base', fields => ['field_name']}, 'NoSuchMemberException' => {isa => 'Exception::Class::Ba +se', fields => ['field_name']}); my %overrides; sub FETCH_CODE_ATTRIBUTES { my ($package, $referrent) = @_; return exists $overrides{$referrent} ? $overrides{$referrent} : () +; } sub MODIFY_CODE_ATTRIBUTES { my ($package, $referrent, @attrs) = @_; my @return; local $_; foreach (@attrs) { if($_ eq 'override') { $overrides{$referrent} = 'override'; } else { push @return, $_; } } return @return; } sub AUTOLOAD { my $this = shift; my $member = our $AUTOLOAD; $member =~ s/.*:://g; return unless($member =~ /[^A-Z]/); return $this->($member, @_); } sub new { my ($class, $members) = @_; my %members; my $this = bless sub { my ($key, $value) = @_; my ($package, $filename, $line) = caller; if($package ne __PACKAGE__) { # Allow protected access? PrivateFieldException->throw(message => 'Direct access of a pr +ivate field was attempted', field_name => $key); } unless(exists $members{$key}) { NoSuchMemberException->throw(message => 'No such member exists +', field_name => $key); } $members{$key} = $value if($value); return $members{$key}; }, $class; if($members) { while(my($key, $value) = each %$members) { $members{$key} = $value; if($this->can($key)) { # Do something more extreme? my @attributes = eval "attributes::get(\\&{\$this->$key})"; print "$key : @attributes\n"; warn "$class already has a method $key; this will be used inst +ead of field access." . " Attach attribute override to that method if you would +like to suppress this message."; } } } return $this; } 1; #!/usr/bin/perl # TestObject.pm # Test subclass for Pixie::Object package TestObject; use strict; use warnings; require Pixie::Object; our @ISA = qw(Pixie::Object); our $VERSION = 1.0; sub new { my $class = shift; return Pixie::Object::new($class, {foo => 56}); } sub foo : override { return "Howdy"; } 1;
Now, I thought that attribute handlers persisted throughout the ISA hierarchy. However, when I test this code, I get the following message:
Invalid CODE attribute: override at TestObject.pm line 19
BEGIN failed--compilation aborted at TestObject.pm line 21.
Compilation failed in require at ./test.pl line 6.
What's the deal? Is there a special mechanism I have to use to allow the attribute handlers to be inherited? Thanks, Rob

In reply to subroutine attributes and ISA by hoelzro

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.