Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: eval-blocks and Test::Builder

by fergal (Chaplain)
on Feb 25, 2006 at 00:11 UTC ( [id://532708]=note: print w/replies, xml ) Need Help??


in reply to eval-blocks and Test::Builder

I try to avoid using eval and code that can dies (exceptions being the exception). Why wasn't this written as something like

package DBM::Deep::Array; sub _get_self { ref $_[0] eq ARRAY ? tied( @{$_[0]} ) : $_[0] }
possibly with a Scalar::Util::reftype()?

eval is reasonably expensive as it creates a new lexical scope and dieing and unwinding the stack is also expensive. Is there an advantage to using it rather than the code above? updated:silly benchmark added and removed!

Replies are listed 'Best First'.
Re^2: eval-blocks and Test::Builder
by dragonchild (Archbishop) on Feb 25, 2006 at 00:51 UTC
    Actually, the nearly-equivalent code is:
    sub _get_self { my $reftype = Scalar::Util::reftype( $_[0] ); $reftype = '' unless defined $reftype; if ( $reftype eq 'ARRAY' ) { return tied( @{ $_[0] } || $_[0] } return $_[0]; }
    (Your version misses the fact that 'ARRAY' is a legal classname and that the value returned from tied() is a blessed hashref which makes the _get_self() for DBM::Deep::Hash more complex.)

    (Yes, my code could be shortened if I was able to use // for defined-or. That's a 5.10ism and DBM::Deep runs on practically every Perl version since 5.004, we think.)

    I don't like that code for three reasons:

    1. It's 6 times longer and has at least twice the number of codepoints. This makes it at least 4 times harder to comprehend at a glance.
    2. Writing that code correctly to function in all cases is hard. I had to edit my version twice as I was writing this reply because I found edge cases.
    3. It assumes that $_[0] will never be something that wants to pretend it's an array using overload. For example, using Contextual::Return or some other magic.

    By using an eval-block, you allow the item to behave the way it wants to behave, if it wants to behave that way, plus you let Perl worry about the edgecases. To get truly equivalent code would be about 40 lines and I don't think I could get it all correct. At that point, an eval-block is quicker.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

      I'm not familiar with DBM::Deep but are you really expecting to have a $_[0] that's a Contextual::Return object? If _get_self is a method in the DBM::Deep::Array package then I don't see how any of the edge cases you have catered for could actually happen.

        A couple of the features that we're working towards are subclassibility and multiple engines. Which means DBM::Deep::Array could be subclassed by something that masquerades as an array using Contextual::Return or some other class that overloads @{}. Why should I prevent that when I prefer to use code that ducktypes $_[0] vs. explicit-types it?

        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://532708]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2024-04-20 04:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found