in reply to Recursive map Design Questions

Interesting stuff. I think you have some potential zaps and traps with how you are identifying type and handling seen items. It looks to me that something like this would cause trouble:

my $x=\"foo"; my @array=("$x",$x);

As would any object with stringification overloaded. Can you see the havoc this would cause:

package Bitch; use overload qw("" bitch); my $bitch="Bitch0000"; sub bitch { $bitch++ }; package main; my ($x,$y); $y=bless \$x,'Bitch'; $x=bless \$y,'Bitch';

Also for this type of scenario don't use UNIVERSAL. I know this goes against common advice, but ref and UNIVERSAL are not meant for type checks except in the loosest sense. Just as Abigail-II correctly pointed out that an object of class '0' would cause trouble so too would an object such as would be returned by

bless [],'HASH'

With regard to BrowserUks point on this matter I generally agree that code need not worry about such nasty tricks. If an enduser wants to do such silly things then its their own fault. But with code deliberately designed to traverse a perl data structure correctly IMO should be coded to bypass such foolishness. Especially as it would not be particularly difficult to handle these cases.

What I would do is utilize Scalar::Util (now core as of 5.8), more specifically reftype() and refaddr(). Using refaddr is much more suitable for tracking seen items, and reftype provides a neat and infalable method of determinging an objects underlying type.

Im worried about the protyping trick. I think its cool on face value just for being tricky, but I think its a bit limiting. Why couldnt one provide a hash of types and callbacks for each? Also, $cut is a problem in my eyes. I think I would prefer to just have it return true or false rather than deal with this special variable in user code. (And File::Find and friends trick of localized vars isnt the best plan either IMNSHO.)

A few last minor thoughts are that I don't like the name of the sub (sorry), i prefer 'treemap' to 'do_rec' and I prefer 'apply' to 'treemap', and a little more documentation would have been nice. :-) It took me while to come to grips with what was going on. (IMO you shouldnt have to read the treemap thread first to understand your post... But maybe i'm just hungover. :-) Overall this looks pretty interesting, and leads me to return to thinking about the overall design of Data::Dumper and Data::BFDump. Good stuff. Thanks.

:-)


---
demerphq

    First they ignore you, then they laugh at you, then they fight you, then you win.
    -- Gandhi


Replies are listed 'Best First'.
Re: Re: Recursive map Design Questions
by bsb (Priest) on Oct 04, 2003 at 01:08 UTC
    Thanks for the Scalar::Util pointers

    Im worried about the prototyping trick

    I went down that path so that the leaf case could use the bare block syntax like a map. Also I wanted a variadic function and since the remaining args could be anything... there's not much room. I could have two entry functions, one for leaves and one with a hash mapping of functions.

    I do like the minimal do {this} to @these ... Maybe 3 calling modes, leaf, prototype hack or sub hash. I'll think some more.

    $cut is a problem in my eyes. I think I would prefer to just have it return true or false rather than deal with this special variable

    Again, this was for aesthetics of the simple case. Most of the time you won't be cutting, just tweaking, or at least that the case I want to make easy. (It's also a design hang over from when it was more map-like and used the return value as replacement) Maybe die "cut" could be an appropriate out of band return value.

    I don't like the name either. Still considering traverse, visit, for_tree, apply. I suspect that functional languages have a good name for this, I should research it.

      I went down that path so that the leaf case could use the bare block syntax like a map.

      And I can see your point as well. You already have a wrapper function however. If the underlying implementation used a hash of callbacks then you could provide the neater codeblock style as well as the clunkier but more powerful hash of callbacks style as well. Everybody wins then.

      Maybe die "cut" could be an appropriate out of band return value.

      Yep, I can see that working nicely.

      Cheers,


      ---
      demerphq

        First they ignore you, then they laugh at you, then they fight you, then you win.
        -- Gandhi