Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Getter and Setter Function Names

by Wally Hartshorn (Friar)
on Apr 09, 2003 at 21:18 UTC ( #249433=perlquestion: print w/ replies, xml ) Need Help??
Wally Hartshorn has asked for the wisdom of the Perl Monks concerning the following question:

I'm posting this under SoPW because there isn't a category called "Pointless Debates". :-) What are people's preferences for how to name "getter" functions? One style guide I've read recommends naming functions after the thing that is returned -- e.g. "salary()". Another style guide recommends naming such a function "get_salary()".

Is there any predominant style in the Perl community? Does the answer depend on whether the function is simply returning the salary or is actually computing it first? Does the answer depend on whether the function is part of a package or is actually a method in an object?

On a related topic, do you prefer to see a separate "set_salary()" function, or do you prefer to see the same function performing both... uh... functions?

Like I said, "Pointless Debates". :-) Still, I'm curious as to whether there is a clear preference.

Wally Hartshorn

(Plug: Visit JavaJunkies, PerlMonks for Java)

Comment on Getter and Setter Function Names
Re: Getter and Setter Function Names
by Ovid (Cardinal) on Apr 09, 2003 at 21:36 UTC

    I don't like overloaded functions that allow you to both get and set a property. For example:

    my $thing = Thing->new($id); print $thing->name; $thing->name($new_name); print $thing->id; $thing->id($new_id);

    If that's an object that represents a row in the database, there's a good chance that you can't set the id to a new value. However, the interface doesn't make that clear. If you have multiple "read only" methods, overloading the methods names leads to overloading the brain. Bad Stuff.

    Another reason for not overloading the methods lies in bugs: if you overload the methods, you have to explicitly write code -- potentially buggy -- to prevent someone from changing read-only values. If you keep accessors and mutators separate, you simply omit mutators for read only attributes.

    After a much experimentation, I find that I prefer the following:

    print $thing->name; $thing->set_name($new_name);

    Aside from the fact that it's less typing, I use Template Toolkit quite heavily and it's easier for our designers to see what's going on.

    [% FOREACH customer = customers; customer.last_name; ", "; customer.first_name, "\n"; END; %]

    To me, that just seems much cleaner.

    Cheers,
    Ovid

    New address of my CGI Course.
    Silence is Evil (feel free to copy and distribute widely - note copyright text)

Re: Getter and Setter Function Names
by Mr. Muskrat (Abbot) on Apr 09, 2003 at 21:40 UTC

    A subroutine name of salary is too vague for me. Sure it's got to do with salary but what does it do? GetSalary (or getsalary or get_salary) sounds like one that gets the salary. SetSalary and CalcSalary would of course set and calculate a salary. Unless of course you are dealing with objects and then I'd probably do it different, like $salary->get($user);.

    /me shrugs.

Re: Getter and Setter Function Names
by BrowserUk (Pope) on Apr 09, 2003 at 22:29 UTC

    My preference is definately for the

    $employee->salary($employee->salary()*1.1);

    form. Partly, this is laziness, but mostly because I haven't seen a clear argument as to the benefits of the get/put form.

    Ideally, where the attribute is a numeric one, I'd like to be able to do

    $employee->salary() *= 1.1;

    This can be acheived with use overload (I think), but it would require a fair amount of effort to overload all the appropriate operators.

    Easier than this is to make the accessor methods, lvalue subs. This removes the need for overload.pm in many cases and greatly simplifies the code. The unfortunate downside of this is that there is no way to apply restrictions or validations to the values set into the object. This works well enough for some types of modules, such as those used only as glorified aggregate datastructures, or where it is acceptable to place the onus of only supplying 'good' values on the users of the module. So called 'unenforced contract interface design', which is quite perlish in its philosophy of recommending you stay out of the barn, but not backing it up with a shotgun:)

    #! perl -slw use strict; package Test; my %numbers; sub new{ my $self = bless \rand, shift; $numbers{$self} = 0; return $self; } sub number :lvalue { $numbers{+shift}; } package main; my $number = Test->new; $number = 3; print $number; $number *= 1.5; print $number; __END__ 3 4.5

    Of course, there will be many situations where the lack of enforcement will not be acceptable to the project design, but that is often a judgement call rather an a pre-requisite. A more serious limitation is that if the representation of the attribute changes in a way that means that using lvalue accessors is no longer feasible, then it becomes extremely difficult, if not impossible, to modify the class in such a way as makes the modification transparent to calling code.

    I've had various attempts at finding a workaround for this limitation of lvalue methods, but haven't found anything satisfactory. I also held out hope that Perl6 might provide a solution, but my reading of Apocolypse 6 recently scuppered those. LW seemed to fairly clearly dismiss the idea--with impecably argued reasoning--but I still find myself hankering for a way of having lvalue subs that could validate their assigned value either before or after assignment.


    Examine what is said, not who speaks.
    1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
    2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
    3) Any sufficiently advanced technology is indistinguishable from magic.
    Arthur C. Clarke.
Re: Getter and Setter Function Names
by DrManhattan (Chaplain) on Apr 09, 2003 at 22:39 UTC
    Assuming you're referring to object methods, I take a different stance than Ovid. I like using overloaded methods that match my variable/column names. For instance, if my object represents a database row with a "salary" column,
    $object->salary() # returns the value of salary $object->salary(1234) # sets salary to 1234

    In the end what really matters, though, is that you establish a standard practice and follow it. The exact nature of the practice is less important than your consistancy in adhering to it.

    -Matt

Re: Getter and Setter Function Names
by vek (Prior) on Apr 09, 2003 at 23:24 UTC
    Personally I'm with Mr. Muskrat on this one. I think it's far nicer to have self documenting code i.e $foo->get_salary as there can be no question as to what it's actually doing.

    Remember, someone has to maintain the code, and it might not always be you :-)

    /me speaking from experience - trying to figure out code written by a former coworker :-)

    -- vek --
Re: Getter and Setter Function Names - content warning:contains references to Java
by Elgon (Curate) on Apr 10, 2003 at 00:51 UTC

    Hi Wally,

    Having just done courses on Java and Enterprise Java recently (I just became an evil management/IT consultant) I rather like the traditional getSalary() and setSalary() and toString() accessor, mutator and accessor/casting (they teach us cool and inscrutable words too) method standard. They act as good visual cues as to what is going on in the program, whereas the overloading route is less obvious and may make maintaining the code harder.

    In general though, I like the idea of standardised method names as it makes life so much easier: I'm doing a smidgeon of J++ coding at the moment and I was taught in (real) Java, which uses the standard ways of doing things, whereas the bastardised version we are currently using has subtly different implementations of the same libraries. This also includes some of the method names as far as I can tell (I could be wrong, the learning curve is still steep.)

    I guess I'd say this as a final quip- it doesn't actually really matter, provided that they are carefully documented.

    Elgon

    "What this book tells me is that goose-stepping morons, such as yourself, should read books instead of burning them."
           - Dr. Jones Snr, Indiana Jones and the Last Crusade

Re: Getter and Setter Function Names
by Biker (Priest) on Apr 10, 2003 at 14:14 UTC

    I dislike "getters" but like "setters".

    A method called salary() indicates a "thing", a noun. Well, what is this "thing", you may ask. The logical (in my humble opinion) answer is that the salary() method tells you what the "salary thing" is. Implementation: salary() returns the salary. No need for a "get_salary()".

    It all becomes different when we want to apply a verb to your "thing". This is when I start working with the method name. Like increase_salary(), set_salary() or (sob) decrease_salary().

    As a result, I end up with one method that represents the thing and zero or more methods that affects the thing.


    Everything went worng, just as foreseen.

Re: Getter and Setter Function Names
by zby (Vicar) on Apr 10, 2003 at 15:04 UTC
    When you can do both get and set on a property, then I personally like to have direct access to the variable. For me this is the clearest way:
    $obj->{property} = 'something'; # for setting $somevar = $obj->{property}; # to get the value
    I just don't see the any advantage in using a specialized functions for it. Getting and setting values of variables is something so basic for programming that I find it the most intuitive way for the task.

      Until the maintainer of the class decides to add something to the "getter" or the "setter" method. Like data checking, or persistance or some such. You'll be left out.


      Everything went worng, just as foreseen.

        Of course it is always a matter of tradeoff. You can't program against all possible future changes. You just need to forsee the most probable.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://249433]
Approved by Ovid
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2014-08-31 05:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (294 votes), past polls