Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re^2: Named Subroutine Parameters: Compile-time errors vs. Run-time warnings

by TheDamian (Vicar)
on May 29, 2009 at 06:29 UTC ( [id://766817]=note: print w/replies, xml ) Need Help??


in reply to Re: Named Subroutine Parameters: Compile-time errors vs. Run-time warnings
in thread Named Subroutine Parameters: Compile-time errors vs. Run-time warnings

Yep. It's just a mistake. A dumb one too, since it was so easy to test. :-(

Chalk it up to wishful thinking on my part. Or maybe just too much blind faith in the compiler: "It's something that would be easy to test at compile-time, ergo it must be tested at compile-time".

Still, at least it's not the worst mistake I made in PBP. ;-)

Damian

PS: I stand by the overall recommendation though. Error messages that point users to the right place are definitely worth the (tiny) overhead of passing named args in a hash.

Replies are listed 'Best First'.
Re^3: Named Subroutine Parameters: Compile-time errors vs. Run-time warnings
by shmem (Chancellor) on May 29, 2009 at 18:31 UTC
    Still, at least it's not the worst mistake I made in PBP. ;-)

    Uh-oh. Whats next? Have a list? ;-)

    I stand by the overall recommendation though. Error messages that point users to the right place are definitely worth the (tiny) overhead of passing named args in a hash.

    Definitely. The recommendation of passing named args in a hash is fine, the one of the MTOW you promote TDI is, if not wrong, then sub-optimal.

    my %hash = ( foo => 1, bar => quux($blorf), ); my $result = frobnitz(\%hash); # ok my $result = frobnitz( %hash); # also ok # --- my $hashref = ( foo => 1, bar => quux($blorf), ); my $result = frobnitz( $hashref); # ok # --- frobnitz( { foo => 1, bar => scalar bar($quux) } ); # not ok

    In the above examples, both of the costly structures for %hash and $hashref are allocated at the pad of the current scope and populated at run time. In the last example, that structures are set up and teared down at every call to frobnitz() :

    use Devel::Peek; sub f{ Dump $_[0] }; f( {o=>1} ) for 1..3; __END__ SV = RV(0x8c17080) at 0x8c17074 REFCNT = 1 FLAGS = (ROK) RV = 0x8bfd7a4 SV = PVHV(0x8c02d04) at 0x8bfd7a4 REFCNT = 1 FLAGS = (SHAREKEYS) ARRAY = 0x8c1bb0c (0:7, 1:1) hash quality = 100.0% KEYS = 1 FILL = 1 MAX = 7 RITER = -1 EITER = 0x0 Elt "o" HASH = 0xc74f0e7f SV = IV(0x8c17060) at 0x8c17064 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 1 SV = RV(0x8c17070) at 0x8c17064 REFCNT = 1 FLAGS = (ROK) RV = 0x8c17074 SV = PVHV(0x8c02d04) at 0x8c17074 REFCNT = 1 FLAGS = (SHAREKEYS) ARRAY = 0x8c1bb0c (0:7, 1:1) hash quality = 100.0% KEYS = 1 FILL = 1 MAX = 7 RITER = -1 EITER = 0x0 Elt "o" HASH = 0xc74f0e7f SV = IV(0x8bfd7a0) at 0x8bfd7a4 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 1 SV = RV(0x8bfd7b0) at 0x8bfd7a4 REFCNT = 1 FLAGS = (ROK) RV = 0x8c17064 SV = PVHV(0x8c02d04) at 0x8c17064 REFCNT = 1 FLAGS = (SHAREKEYS) ARRAY = 0x8c1bb0c (0:7, 1:1) hash quality = 100.0% KEYS = 1 FILL = 1 MAX = 7 RITER = -1 EITER = 0x0 Elt "o" HASH = 0xc74f0e7f SV = IV(0x8c17070) at 0x8c17074 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 1

    Some of the above pointer being equal is just an artefact of the subsequent call of the same sub (I guess here).

      ...one of the MTOW you promote TDI is, if not wrong, then sub-optimal

      One of the points I make in PBP is that "sub-optimal" is not a easy thing to judge as soon as you have more than one metric to optimize. PBP suggests at least four: maintainability, robustness, performance, and conciseness (and argues that that is the approximate order of importance of the four).

      The recommendation to use anonymous hashes when passing one-off argument lists trades a little less performance for a little more conciseness, some improved robustness, and (if used consistently throughout the code) better maintainability.

      Of course, you're perfectly correct to factor out the hash memory reallocations into a single declaration if you're going to repeat the same call hundreds (or millions) of times, but as a default habit, just building an anonymous hashref at the point you need it is cleaner, less error prone, and more concise. And the performance cost on a single call at modern processor speeds isn't worth the hassle of coordinating between separate hash declarations and uses.

      All of which is why inlined hashes were the default recommendation in PBP.

      PS: You also asked what worse mistakes I made in PBP. One of them was not finding a way to adequately get across that the advice in the book is meant to be a starting point, a default zero-state, an initiator of conscious thought, rather than an end-point of discussion. Gods know, I tried to convey that (devoting most of the first chapter to the idea), but I stupidly didn't put any code in that chapter, so most readers just seem to skip straight over it. :-(

Re^3: Named Subroutine Parameters: Compile-time errors vs. Run-time warnings
by LanX (Saint) on Jun 02, 2009 at 22:45 UTC
    "It's something that would be easy to test at compile-time, ergo it must be tested at compile-time".

    Maybe the edge case that it's not possible to decide at compile-time if this hash  %h = (  key => @arr ) has a well-formed list at RHS with an even number of elements (how many elements will @arr have ???) makes it not so easy to test it generally at compile-time?

    A good work-around might be to throw a warning if arrays are used as hash-values after a fat comma... I would really like it this way, since list-flattening in values really seems too "odd" to me!

    Cheers Rolf

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2024-03-19 11:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found