in reply to Re: Why ref() is bad.
in thread Is "ref $date eq 'ARRAY'" wrong?

You're absolutely correct, in that the code is documented as to what it does. However, there is a disconnect between the idea of an array reference and an object which just so happens to be implemented as an array reference.

... reads what he just wrote ...

SIGH

As a Perl hacker, I have problems with the twit who wrote the first part of this reply. I can easily see someone wanting to do something like:

package My::Overloaded::Array; use overload '+=' => 'my_push'; sub my_push { my $self = shift; push @{$self}, @_; }

Now, the hapless coder wants to have HTML::Template use it as an array. I have an object which is an arrayref and I want HTML::Template to treat it as a plain scalar that isn't a reference. And, frankly, there's no way for poor HTML::Template to tell the difference!

... thinks some more ...

Unless our intrepid array-hacking hero overloads @{} (or whatever it's called these days ... []?) ... Or, I'm stuck with my solution of overriding isa(). What are your thoughts? (Maybe there's a meditation in all this rambling I seem to be doing of late ...)

------
We are the carpenters and bricklayers of the Information Age.

Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Replies are listed 'Best First'.
Re: Re: Re: Why ref() is bad.
by BrowserUk (Patriarch) on Dec 19, 2003 at 20:55 UTC

    To be honest, I am not yet sure what the best answer is. In general, I've stayed out of discussions regarding how best to use OO in perl (5) simply because I haven't seen a truely complete approach to putting OO together with perls dwimery such that you don't end up with dilemmas like this.

    This sort of leads to the same set of thoughts that I had in my mind when I wrote this earlier today.

    I've played with various OO techniques and modules from CPAN, but I invariably run up against some barrier, limitation, logical or syntactic inconsistancy that prevents me from getting the interfaces to work quite the way I would like them to.

    • I like overloaded operators, where they make sense.

      I find $complex1 += $complex2; infinitely preferable to

      $complex1->set( $complex1->add( $complex2->get() );
    • I like lvaluable (logical) attributes for objects.

      I prefer

      $file->position = 0 if $file->eof;

      to

      $file->set_position( 0 ) if $file->eof();
    • I like the idea of context sensitivity, on both input and output.

      To my way of thinking the value of this is similar to one of the reasons we use OO in the first place. It is a form of namespace simplification. Polymorphism if you will.

      One of the reasons for using OO, is that it allows us to re-use verbs as function (method) names without having to further qualify those names. I well remember writing C code where every library had its entrypoints prefixed with the name of the datastructure it operated on. thingy_init(), thingy_create(), thingy_destroy() and so on so as to prevent name conflicts. OO removes the need for this.

      Avoiding the need for

      $thingy->set_date_from_string("..."); $thingy->set_date_from_array( localtime ); $thingy->set_date_from_array_ref( [localtime] );

      by using using runtime determination of passed types to a single method seems a logical extension of this.

      Likewise, return context.

    So far, my attempts at trying to put together a clean and consistant implementation of classes that utilise all of these techniques in the same class have always ended up with an inconsistancy, or requiring undesirable copy&paste coding somewhere down the line.

    Even simple things like inside-out objects leave me undecided. If your class has 3 physical attributes, do you code that as

    package MyClass; my %instances; sub new{ my( $class, $attr1, $attr2, attr3 ) = @_; my $self = bless {}, $class; return $instances{ $self } = [$attr1, $attr2, $attr3]; }

    or

    package MyClass; my( %attr1, %attr2, %attr3 ); sub new{ my( $class, $attr1, $attr2, attr3 ) = @_; my $self = bless {}, $class; $attr1{ $self } = $attr1; $attr2{ $self } = $attr2; $attr3{ $self } = $attr3; return $self; }

    The former is shorter and less profligate with space. The latter results in less complex syntax when referencing the attributes with the methods, but relies upon "parallel arrays", which I normally consider a bad idea. It also consumes more memory.

    The complicated syntax of the former can be diffused by using (private) accessors/mutator functions, but that adds to the performance overhead.

    If the objects are largish and few in number and not called in tight loops, neither is too much of a problem, but if the objects themselves are pretty small, but you need to use lots of them and/or call their methods in tight loops, then the overhead in memory and performance is a pain.

    Maybe the answer is to wait until P6 for a clean solution and just muddle through for now?