http://www.perlmonks.org?node_id=219765


in reply to Re: (my?) problem with re-blessed references(?)
in thread (my?) problem with re-blessed references(?)

Once any behavior is added, the simple use of can to test for attributes is no longer robust. For instance these classes beg for a display method.

Replies are listed 'Best First'.
Re: Beware can for attrs
by runrig (Abbot) on Dec 14, 2002 at 16:56 UTC
    Once any behavior is added, the simple use of can to test for attributes is no longer robust.

    You're right and I thought about this a bit. If every package and ISA package has a %HAS (or HASA) hash containing valid attributes as keys, and defines a 'has' method, then its fairly simple to validate attributes in any package (and the attribute accessor/mutator methods could even be AUTOLOAD'ed if desired). The 'has' method would go something like this (untested):

    sub has { my ($self, $attr) = @_; return 1 if exists $HAS{$attr}; return 1 if ${_}::has($self, $attr) for @ISA; return; } # Then in initialization or in AUTOLOAD... ... if ($self->has($attr)) { ...#set attr }
    I'm not yet saying that this is a good idea, just throwing it out there for comments/opinions/better options.

      One problem with %HAS is that you have to duplicate the list of attributes.

      # type them once... my %field1; my %field2; my %HAS; # type them twice... {$HAS{$_}=1} foreach qw(field1 field2);

      As soon as you start typing field1, field2, etc. more than once you give yourself a problem when you change one and forget to change the other, etc.

      For example, a typo in %HAS will foul up your new() method without any warnings, etc... and we suddenly start having some of the effects that we switched to inside-out-objects to avoid ;-)

      There's also the fact that you don't want the user to fiddle with every attribute in your object.

      This leads to the more general point that I don't think that a totally generic object construction subroutine is practical. What ever method you pick is going to be inappropriate/annoy one or more groups of people.

      So - don't sweat it! Do something that works for the code that you're writing. Don't worry too much about the platonic one-true-new. There ain't no such beast :-)