in reply to Re^3: Class attribute get/set approach flaws?
in thread Class attribute get/set approach flaws?

How do you avoid problems with passing in zero length lists when you're setting a value? How do you distinguish the setting form of $obj->foo( new_value() ) from $obj->foo() if new_value() might return an empty list?

Replies are listed 'Best First'.
Re^5: Class attribute get/set approach flaws?
by sauoq (Abbot) on Nov 29, 2005 at 01:34 UTC

    Why, the obvious way... I avoid the necessity, of course!

    My accessors take a single optional scalar. Period. If I have to pass a reference, I do. If I need to clone it, I do. It's easy. Straight forward. Simple. (And I'm really embracing simplicity as much as possible these days.) Mostly, my accessors look something like:

    sub foo { $self = shift; @_ <= 1 or croak 'Too many arguments (' . @_ . ')'; if (@_) { # do whatever I need to. } return $self->{foo}; # Or whatever. }

    I think the biggest plague among Perl programmers is a drive to be altogether too tricky when there isn't a real good reason to be. I know enough about Perl's quirkier features to believe it's better to avoid most of them much of the time.

    I've taken the Ruby-on-Rails slogan, "Convention Over Configuration" and modified it for my personal use:

    Convention Over Confusion

    † Well, okay... not "period" exactly... There are exceptions to every rule... but relatively few to this one.

    -sauoq
    "My two cents aren't worth a dime.";
    

      That doesn't answer my question. I expected that new_value() would return a single value but if there were an error or if my expectations were wrong, maybe it would return no elements sometimes. That is, $obj->foo( scalar new_value() ) provides different things to ->foo() than $obj->foo( new_value() ).

        I did answer your question (by saying that I avoid being tricky.) I don't code my modules particularly defensively. It's too tricky. You can get sick to your stomach worrying about every contingency. I take what I believe to be a rather Perlish approach: I give you enough rope to hang yourself and the three people closest to you. I.e. For the most part, I assume you know what you are doing. If you are going to call $obj->foo(new_value()), then I trust you know what new_value() is going to give you in list context. And, I trust that you know what context it's being called in.

        Now, if I wrote new_value() then you probably don't have much to worry about because I avoid being tricky. In that case, you could be pretty confident that new_value() wouldn't be context dependent. Either it would (always) return a scalar, or it would (always) return a list.

        For what it's worth, this is a relatively new philosophy for me. Like, within the last year or so. For instance, I used to write separate get/set accessors all much of the time but I can't recall even one single circumstance where it actually helped me or a coworker. Great theory. Limited applicability. (In my experience, anyway.) I think there's lots of that around.

        Now watch me get bit by a bug like this tomorrow, right? But, then my tests will fail, I'll find the bug, fix it, and it'll all be in a day's work.

        -sauoq
        "My two cents aren't worth a dime.";