Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re: Re: Perl applications

by dragonchild (Archbishop)
on Apr 25, 2004 at 02:23 UTC ( #347916=note: print w/replies, xml ) Need Help??

in reply to Re: Perl applications
in thread Perl applications

Your code/style guide looks really good. A few notes:
  1. Leave warnings on in production. They are often your only indication that something went wrong. And, if you're sharing your logspace with another app, you have bigger problems.
  2. Don't use Error in production code. It does its work with closures, which can (and does) cause memory leaks. Better is to just do it yourself with eval/die. Example:
    eval { # Code that might die }; if ($@) { # Catch area }
    Perl 5.6+ even allows you to die with an object. (This is what Error utilizes. Read the code sometime, it's not that difficult.)
  3. return undef; will not do what you want. Better is just return;. Here's an example why:
    sub foo { return undef; } my @x = foo(); if (@x) { print "foo() succeeded\n" } else { print "foo() failed\n";
    You even talk about this, but don't realize the issue.
  4. Importing isa() can be neat, but I would still use UNIVERSAL::isa(), anyways, just to be anal. Also, there are many classes that, for whatever reason, need to overload both can() and isa(). Be mindful of them.
  5. You use the word "local" when discussing keeping variables with what they're working on. Use the word "lexical". local means something specific in Perl.
  6. When talking about map, grep, sort, and conditionals, you refer to saving 600 bytes of memory. That's the first time in about 15 years I've seen someone talk about saving bytes of memory, other than my compulsory ASM class in college. bytes!! You seriously think that this is a reason for or against anything? If I'm worried about 600 bytes of RAM, I shouldn't be using Perl. Remember - Perl doubly-indirects every single variable. That's 8 extra bytes overhead, just to even start having a variable. (There's more to it than that ... it's actually like 40 bytes just to have space for a variable, let alone the actual values.)

    The real reason to use post-ifs, as you call them, is to improve readability. You want to have the important bits on the left hand side, closest to the margin. That stands out more. Error conditions should be on the right, where they can get out of the way of reading the main flow of the code.

  7. Don't use a regex to test against many values, use a hash. Not only does it improve readability, but you are documenting why you're testing against these thing. (And, it's faster.)
  8. In your regex-in-a-map, you don't explain why it's important to have $_ at the end. It's because s/// returns the number of changes, not the value changed. (Plus, in your example, the stripping of surrounding whitespace should be in a function.)
  9. I agree with map in your list -> hash example. However, it might be more readable as such:
    # Create an ID to name hash my %hash = map { $_->id, $_->name } @Objects; Becomes: # Create an ID to name hash my %hash = map { $_->id => $_->name } @Objects;
  10. The double boolean negative. Never heard of it. If I saw it, I'd want to hunt you down with an axe. Try $foo = $bar && 1; - simple, clean, and is used in more places.

We are the carpenters and bricklayers of the Information Age.

Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

Replies are listed 'Best First'.
Re: Re: Re: Perl applications
by adamk (Chaplain) on May 02, 2004 at 00:52 UTC
    A lot of this is good stuff. To continue

    1. I guess it depends on the context. Certainly in a situation where you can assume full server control, seperate logging would mean warnings can be turned on. I've done a lot of work in shared log uncontrollable server situations, and I've found that in that case more often that not the warnings are just getting in the way in that case, particularly when there's a warning that is relatively unimportant, but which end up filling up 95% of the log.

    2. Interesting. I'll add that in. In my case, I've ended up with my own somewhat lighter Exception class, based around the die'able object ability.

    3. Returning things by list like that has some major problems. Returning by list gives us no way of differentiating a legal null list from an error state. Take a better look at the suggested full map of return conditions, based on the return type and whether it can fail or not.

    My standard is that when a method can error, undef is the error response, 0 the null response, and a list is returned by reference.

    Only in the case of a list return with no possibility for error is the subroutine allowed to be written such that it returns a list.

    Also, consider the problem of 'return' being inconsistent, for example in

    Foo::maximum( $foo->value, $bar->value, $baz->value );
    If an error was returned with just 'return', that code does not fail, but rather continues with an incorrect result. The alternative is create three new variables, save the values to them, check them, and THAN call Foo::maximum.

    In the long term, over thousands of methods, I consider the predictability of having methods ALWAYS return error as undef outweighs any potential for the bug you mention. Return by list has it's own problems, and I choose to go with consistency.

    4. I concur with the be careful, and I certainly agree. Within _my_ code, I generally don't overload isa, so it's save for me. And the VERY large number of times I use UNIVERSAL::isa means that the code is far more readable. When testing external modules, yes, there is reason to be careful.

    5. Point taken

    6. I agree, sort of. Certainly about the legibility being the main reason.

    As for the memory saving, I measure a largish API once, and found 1500 post-ifs ( mostly 'or return undef' though ). That's heading towards a meg of extra overhead. I'm a little more paranoid about saving memory than most I guess. Note Config::Tiny and CSS::Tiny :)

    7. I've swung either way on this one... At the moment I'm still leaning slightly towards regex still, from a flexibility viewpoint ( you can use the regexs for regex stuff ) and for their compactness. ( And they are quite legible )

    8. I concur, I'll add a note. The whitespace example is really just that, and example. I should probably add the grep { regex; 1 } alternative, although using map {} makes it much more obvious as to the intent.

    9. That is much nicer, and I really should have known that :)

    10. The && 1. Never heard of it. If I saw it, I'd want to hunt you down with an axe. Try !!; simple, clean, only two ops, and each to teach as the "boolean context" operator.

    Thanks for all the suggestions

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (6)
As of 2019-02-21 14:14 GMT
Find Nodes?
    Voting Booth?
    I use postfix dereferencing ...

    Results (112 votes). Check out past polls.

    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!