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

I wonder if you'd be better off initializing attributes in the constructor like this instead:
if (ref $args eq "HASH") { while(my ($method, $value) = each %$args) { if (my $func = $self->can($method)) { $func->($self, $value); # Update: I think in this case (after # consulting in CB and in the docs # regarding lvalue subs) it should be: # $func->($self) = $value } } }
It seems much more maintainable and inheritable this way. I also wonder about the need for a "new" method (i.e. constructor) in the QuotePlus class. It seems like it should just be inherited from the Quote class.

Replies are listed 'Best First'.
Re: Re: (my?) problem with re-blessed references(?)
by djantzen (Priest) on Dec 13, 2002 at 07:00 UTC

    It would be better written $self->$func($value), where $func in this case is one of those ambiguous methods that is both accessor and mutator, like:

    sub confoosing { my ($self, $arg) = @_; return $arg ? $self->{confoosing} = $arg : $self->confoosing; }

    Your suggested rewrite of the constructor is generic enough to be entirely inheritable, obviating the need for QuotePlus::new, although this method kinda chaps my hide since I like to have a predetermined list of acceptable parameters for each constructor, even those in an inheritance chain. Doing it this way is convenient, except when it comes time for argument checking. I'm also still addicted to Java-style constructor chaining, although generally now I accomplish that by separating instantiation from initialization.

    Cf. inheritance: constructors

Re: Re: (my?) problem with re-blessed references(?)
by BrowserUk (Patriarch) on Dec 13, 2002 at 06:51 UTC

    Nice. I looked for a way to do that but I've never used can so didn't think of that. I had to change it slightly to

    $func->($self) = $value; to accomodate the lvalue accessor/mutators but it seems to work fine.

    It does however make something change in as much as in now only get three lines of output, which suggests that the loop pushing instances is now empty, which is strange as I haven't edited that file at all, but I'll try and work out what else changed tomorrow, for now its time to sleep.

    Your probably right that the is no real purpose to QuotePlus except to explore the inheritance mechanism. If I just moved the data attribute into the Quote class, the problem goes away, but that defeats the purpose of my exploration :^).

    Thanks a lot for your help. BrowserUk.

    Examine what is said, not who speaks.

Beware can for attrs
by rir (Vicar) on Dec 13, 2002 at 21:59 UTC
    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.
      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 :-)