Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Return $self, but what if I don't wanna?

by asoftware (Novice)
on Mar 10, 2010 at 02:04 UTC ( [id://827673]=perlquestion: print w/replies, xml ) Need Help??

asoftware has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, Usually when you are writing a method you make the return value $self, particularly important if you have modified one or more of the objects data members.
What is the best way to return some other value, while still updating $self?

Often I come across code where I work that does this sort of thing (Moose style OO).
# The actual method to be called: sub calculate_foo { my $self = shift; $self->_calculate_foo(); return $self->foo; } # A private method that actually updates $self->foo sub _calculate_foo { my $self = shift; $self->foo($self->foo + 999); return $self }
So my question's are these:
1) Is it possible to update $self->foo while returning something other than $self, I doubt it. but asking just in case.

2) If not, is the above example the correct 'convention' for returning arbitrary values from a method.

3) When does it make sense to simply update an objects attributes, and expect the caller to use them instead of return values.

Any thoughts you have on this subject would be greatly appreciated.
-- Cam

Replies are listed 'Best First'.
Re: Return $self, but what if I don't wanna?
by ikegami (Patriarch) on Mar 10, 2010 at 02:56 UTC

    Generally speaking, returning $self is by no means necessary. It's a convenience, as it allows

    my $d = Date->new(); $d->year(2010); $d->month(3);

    to be written as

    my $d = Date->new() ->year(2010) ->month(3);

    In your case, _calculate_foo is only called internally and its result is discarded. There's no reason to return $self.

    If you continued to have _calculate_foo return $self, you could simplify calculate_foo. But since you're likely going to use the value you calculated, why not return it instead?

Re: Return $self, but what if I don't wanna?
by JavaFan (Canon) on Mar 10, 2010 at 10:13 UTC
    Usually when you are writing a method you make the return value $self, particularly important if you have modified one or more of the objects data members.
    Usually? The majority of the code I see doesn't. And important? It allows you to write:
    $obj->name("John Doe")->birthday("1969-07-20")->income(53_389.86);
    but I see most people write that as
    $obj->name("John Doe"); $obj->birthday("1969-07-20"); $obj->income(53_389.86);
    even if they could chain. I wouldn't call it "important". And you really have to play dirty tricks if all your methods would return $self. Accessors to get the value of attributes are a pain in the ass to write (and use) if all they are supposed to return is $self.
Re: Return $self, but what if I don't wanna?
by Svante (Sexton) on Mar 10, 2010 at 02:41 UTC
    1. I have not used Moose yet, but I would be very surprised if you could not return whatever you want. Why should the modifying code depend on the return statement? Have you simply tried to replace the return statement with, e.g., return 42;?
    2. It looks like needless boilerplate to me. Why not just return what you want to return?
    3. Rarely, I believe. Perhaps if you modify several attributes, and the caller most likely would not use them right away.
Re: Return $self, but what if I don't wanna?
by jasonk (Parson) on Mar 10, 2010 at 02:52 UTC

    calculate_foo calls _calculate_foo in a void context, so it doesn't matter what it returns, the return value is being ignored anyway.


    www.jasonkohles.com
    We're not surrounded, we're in a target-rich environment!
Re: Return $self, but what if I don't wanna?
by dsheroh (Monsignor) on Mar 10, 2010 at 10:48 UTC
    1) Yes.
    sub calculate_foo { my $self = shift; $self->foo($self->foo + 999); return $self->foo; }
    or even
    sub calculate_foo { my $self = shift; return $self->foo($self->foo + 999); }
    will work just fine.

    2) Question not relevant because answer to #1 was "yes".

    3) It makes sense when it makes sense.

    OK, less tautologically, it makes sense to return something other than the object when something other than the object is what will typically be most useful to the caller. If you're doing a calculation, return its result; if you're creating an aggregated object, return that one; etc.

Re: Return $self, but what if I don't wanna?
by chuckbutler (Monsignor) on Mar 10, 2010 at 03:19 UTC

    Return a value that is appropriate, logical, and will further the task that you wish to complete.

    If you are updating the data of the object, you should always be sure if there is an error, report if back to the caller of the method. This may involve a convention with the return value, ie: returning undef -or- zero and setting $! to something pithy and relevant, or terminating using croak with a descriptive message.

    Good luck, -c

Re: Return $self, but what if I don't wanna?
by tuor (Initiate) on Mar 10, 2010 at 14:37 UTC
    When I read your question, it occurred to me that you might have a misunderstanding of how objects work. Remember, the caller already has the object that gets assigned to $self; that's why he is able to call the method. When you update the object's attributes, that update is reflected in the object that the caller has, so returning that value is not strictly necessary.

    One common style of o-o programming is that you have some methods that mutate the state of the object, and others that access the state. The mutators typically do not return a value, but the accessors do return some aspect of the state of the object.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://827673]
Approved by toolic
Front-paged by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2024-03-28 08:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found