Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

OOP's setter/getter method - is there a way to avoid them?

by tiny_monk (Sexton)
on Oct 27, 2015 at 08:15 UTC ( #1146074=perlquestion: print w/replies, xml ) Need Help??
tiny_monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello, beloved Perl monks. My learning journey has taken me to a far and exciting land called Object-Oriented Programming (OOP). I find OOP interesting as it entails a different way of thinking and approach in programming. I am currently studying a book, Perl Objects, References & Modules (1993) by Randal L. Schwartz, and was introduced to the concepts of getters and setters. Personally, I do not feel comfortable with the idea of using setter and getter functions. I understood clearly the disadvantages of accessing class objects directly. If down the road I would need to design a class object, I would try to stay away, as possible, from using accessors. However, I am a bit frustrated because the book only illustrated how setters/getters could break the encapsulation of a class object. I made up my own example to illustrate how encapsulation could be broken into despite the success of changing the color attribute from 'red' to ‘green’.

use strict; use warnings; { package Fruit; sub new { my $class = shift; my $fruit = shift; my $self = { name => $fruit, color => 'red' }; bless $self, $class; }; sub set_color { my $self = shift; $self->{'color'} = shift; }; sub get_color { my $self = shift; $self->{'color'}; }; } my $obj = Fruit->new('apple'); $obj->set_color('green'); $obj->get_color; use Data::Dumper; print Dumper($obj);

I used Data::Dumper and the result is shown below:

$VAR1 = bless( { + + 'color' => 'green', + + 'name' => 'apple' + + }, 'Fruit' ); + +

The chapter I read, chapter 9, did not offer definitive and non-invasive solutions on updating an object’s attribute. On the other hand, It’s also possible that I have failed to understand some key points in the chapter. My question is, are setters and getters still used these days in Perl programming? Is there a non-invasive way to update an object’s attribute? Is OOP considered a universal subject that it could be discussed without any reference to a particular programming language? Are there books that you could recommend on the subject? Thank you. :)

Replies are listed 'Best First'.
Re: OOP's setter/getter method - is there a way to avoid them?
by Discipulus (Monsignor) on Oct 27, 2015 at 08:44 UTC
    Hello, you receive for sure good replies, but even if i'm not a ObjectOrientedMonk (read Damian Conway's ten rules for when to use OO), i recall that some framework for OOPerl gives theese method for free if you want: Moose and Moo.

    In a very lazy and minimalist perspective i recall also a good trick to have the setter and getter method for free without extra packages using the AUTOLOAD (a Perl mechanism that intercepts all possible undefined method calls) trick:
    package Person; use strict; use Carp; use vars qw($AUTOLOAD %ok_field); # Authorize four attribute fields for my $attr ( qw(name age peers parent) ) { $ok_field{$attr}++; } sub AUTOLOAD { my $self = shift; my $attr = $AUTOLOAD; $attr =~ s/.*:://; return unless $attr =~ /[^A-Z]/; # skip DESTROY and all-cap metho +ds croak "invalid attribute method: -> $attr()" unless $ok_field{$attr}; $self->{uc $attr} = shift if @_; return $self->{uc $attr}; } sub new { my $proto = shift; my $class = ref($proto) || $proto; my $parent = ref($proto) && $proto; my $self = {}; bless($self, $class); $self->parent($parent); return $self; } 1;
    If i remember this code is from the old but still worth reading book Perl CookBook. In this book an entire chapter is dedicated to Object but starting from the very primitive concepts (the book is aged).

    Even in the recent and very good book Modern Perl ther is tha chapter object oriented Perl that is very interesting.

    About your other general questions... is a matter of aptitude i think. Remember also that an OO Perl program is generally slower than a normal one. Anyway setter and getter methods are needed if you want do something with that fat Object. And yes OO is a general way of thinking to data and behaviours and relationships.
    Here at Perlmonks is a subject discussed many times: see super search: ?node_id=3989;HIT=object;re=N;BR;MR;M (notabely The Power of Objects Object-Oriented Perl - Introduction in The Perl Review Object Oriented Perl - very basic guide When to Use Object Oriented approach in Perl? (RFC))

    HtH
    L*
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      Thank you, Discipulus. I'll look into all the sources that you have suggested. Damian Conway's rules were particulary useful. And, yes, thank you for confirming that OOP is slower - I think by 30%. If I remember it correctly, the author Randal Schwartz had mentioned this piece of information in his book. However, it was in 2003 that he made this statement. I'm unsure how OOP behaves on present day computers assuming that the trend for computer performance is to improve each year. I have heard of Moose and Moo lately but I do not have any idea what they could actually do. I'll look into it as well. If you have the time, I'd appreciate it if you could share with me the author of Perl Cookbook. :)

        Well, it's likely to be consistent in that it'll always be _slower_. But that's never been the point of OO. The point is to segregate and isolate chunks of code such that you always know where you're looking for problems and tracing bugs. And 10 years of Moore's law means that speed is increasingly not a concern - and when it is, it's time to whip out a profiler, and decide on a risk managed way, if you can afford to rewrite

        I'd appreciate it if you could share with me the author of Perl Cookbook. :)

        Perl Cookbook is written by Tom Christiansen and Nathan Torkington. Tom also co-wrote Programming Perl (among other highly-regarded endeavours).

Re: OOP's setter/getter method - is there a way to avoid them?
by Laurent_R (Canon) on Oct 27, 2015 at 09:36 UTC
    Personally, I do not feel comfortable with the idea of using setter and getter functions.
    Why? Using accessors is pretty much a standard way of accessing object attributes (in many OO languages, to the point that, for example, either Moose or Perl 6 will just write the accessors for you if you kindly ask) and obeying the rules of data encapsulation. Although I do own a copy of Randal's book, I don't have it at hand right away, but I can't remember having read about "inherent" dangers of using accessors. Well, at least, using accessors is much better than fiddling directly with the objects' internal data structure.

      Hello, Laurent_R. You are right. The author of the book did not explicitly write about the inherent dangers of using accessors. Nor did I claim that he did. I was merely speaking from my viewpoint that ensued after reading chapter 9. It was merely my own abstraction. It was more personal than universal. I apologize for not being able to communicate clearly. I am new to OOP. The moment I saw $self->{'attribute'} = shift; being used in the setter and $self->{'attribute'} in the getter functions, it gave me the notion that the encapsulation was being broken. But I may be wrong. My understanding is that the object's innards should stay inside the object. That's my understanding of what Randal wrote in his book. Then again I may be wrong. I was hoping to find clarity as to whether it is perfectly legal to access the object's data directly inside the setter/getter function. While I understand that it is not advised that an API caller use $object->{'attribute'} to access or update the object's attribute outside a class, I don't understand why it seems perfectly alright for the setter and getter methods to use $self->{'attribute'} for changing and accessing attributes internally? Why? This is what Randal did not explain in this particular chapter. Does the concept of encapsulation apply to the code found in the setter and getter functions? If it is so, isn't $self->{'attribute'} = shift; a violation of the encapsulation? Or is this a privilege that setter and getter functions have over API callers?

        Hello tiny_monk,

        The moment I saw $self->{'key'} = shift; being used in the setter and $self->{'key'} in the getter functions, it gave me the notion that the encapsulation was being broken. But I may be wrong. My understanding is that the object's innards should stay inside the object.

        You are absolutely right, an object’s implementation (“innards”) should stay private to the object, to maintain encapsulation. But getter and setter methods are internal to the object — or, rather, they are internal to the class from which the object is instantiated. So it is quite appropriate for them to access the object’s innards. Encapsulation is broken only when an object’s implementation details are exposed or accessed outside the object.

        While I understand that it is not advised that an API caller use $self->{'key} to access or update the object's attribute outside a class, ...

        In this context, an object’s “API” is equivalent to its “interface”, that is, the totality of its public methods. And since the object itself is a blessed reference, it is often possible for code with access to the object to access its innards directly. But that breaks encapsulation, so external code should access an object only through its public methods.

        In your original example, the methods set_color and get_color do not break encapsulation, because they are defined within package Fruit. But suppose we add the following lines:

        $obj->{color} = 'blue'; print Dumper($obj);

        The output is now:

        22:39 >perl 1424_SoPW.pl $VAR1 = bless( { 'name' => 'apple', 'color' => 'green' }, 'Fruit' ); $VAR1 = bless( { 'name' => 'apple', 'color' => 'blue' }, 'Fruit' ); 22:40 >

        which shows that we have again altered the apple’s colour. But this time we have done so by accessing the object’s internals directly, which does break encapsulation.

        Unlike other OO languages, Perl allows this to happen, but that doesn’t make it a good idea! Here’s a famous quote from Larry Wall:

        Perl doesn’t have an infatuation with enforced privacy. It would prefer that you stayed out of its living room because you weren’t invited, not because it has a shotgun.

        But there are also techniques for enforcing privacy. See the section “Using Closures for Private Objects” in Chapter 12 of the Camel Book (4th Edition, 2012, pp. 446–9), and CPAN modules such as MooX::ProtectedAttributes for use with Perl object systems such as Moose and Moo.

        Hope that helps,

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        Further to Athanasius's comments above:

        My understanding is that the object's innards should stay inside the object.

        But they can't stay inside forever. After all, an object's innards are data, and data must be accessed and sometimes even (gasp) changed in order to be useful. Consider the  'name' attribute in the example code of the OP. It has no getter/setter method. Except by direct reading or writing via the object reference, which we all agree is a Really Bad Idea and which no one will ever do, this data cannot be accessed in any way. What good is it? Of course, you can imagine you might write another method that would access it, say along the lines of

        sub string_of { my $self = shift; return "$self->{color} $self->{name}"; } sub print { my $self = shift; printf "I am a %s \n", $self->string_of; }
        Both these methods "expose" object attributes to application code without any risk that they may be changed, and why not? It's up to the library (or class) programmer to decide to offer such methods or not.


        Give a man a fish:  <%-{-{-{-<

        Well, to sort of mitigate what I said previously, if I were to design a class in which all object attributes were to have simple getters and setters, and in which there was no other way to use or modify these attributes than these getters and setters (and the initial constructor), then, my class might still work fine for its intended purpose, but it would likely be poor OOP design. Or it would at best be a use of an OO interface / functionalities to do something else than real OO programming, perhaps, for instance, to simply benefit from data encapsulation and relative persistence from one call to another. And this might be perfectly OK if I don't fool myself into believing that I have created a real OOP design.

        So, yes, accessors might sometimes be harmful if I use them lavishly in order to, in fact, avoid creating a real OO design, but the problem here is not so much my excessive use of accessors, but rather perhaps my own lack of experience in OO programming or my lazy reluctance to actually design a real OO application.

        I have seen at work many Java programs that are not OOP at all: they were just purely procedural programs written in Java (or maybe I should say written in C with a Java syntax) rather than in actual C, presumably just because it is easier not to have to deal with the pitfalls of memory allocation, memory leaks, dangling pointers, segmentation faults and other traps of the C language. Well, why not if it make things easier? But, if you do that, just be aware that it is not true OO programming. My own son (who is preparing a PhD in IT) is frequently using C++ just as if it were pure C, just using some of the facilities offered by the C++ (non-OO) syntax. Again, why not? But this is no OO design.

        Conversely, I am using relatively regularly closures and related FP features to implement data encapsulation and persistence, and creating my own getters and setters, a kind of very light-weight object methodology in a way, but this is also not OO programming.

        So, in brief, I don't think there is anything wrong or even dangerous about accessors in OO programming per se, except that, if I am not careful about what I do, I might simply not be doing true OO programming, but just (cleverly or lazily, it is your draw) using some of the useful tools provided by the OO framework and functionalities in Perl or whichever language in which I happen to be developing.

Re: OOP's setter/getter method - is there a way to avoid them?
by jeffa (Bishop) on Oct 27, 2015 at 16:27 UTC

    "My question is, are setters and getters still used these days in Perl programming?"

    • Yes they very much are. This is why packages like Moose easily make them available for you.

    "Is there a non-invasive way to update an object’s attribute?"

    • From inside the object? Sure, as long as those methods are neither the getter nor the setter? :) You see ... something has to get the attribute on behalf of the client, and something has to set the attribute on behalf of the client.

    'Is OOP considered a universal subject that it could be discussed without any reference to a particular programming language? Are there books that you could recommend on the subject?"

    • Yes, very much so, although you'll see many examples in C++ and Java. My favorite book on the subject is "Design Patterns: Elements of Reusable Object-Oriented Software" by Gamma, Helm, Johnson and Vlissides.

    "However, I am a bit frustrated because the book only illustrated how setters/getters could break the encapsulation of a class object."

    • Just remember that getters and setters are use to enforce encapsulation, not break it. In Perl, an object is most often implemented as a hash, and it is blessed to a package so that the interpreter can find its methods. If you don't care about those methods, then just use a hash. A hash is a key/value store of attributes, which can in turn be treated as a light weight object. No getters/setters needed ... and since you don't need to worry about internal representation of bytes 9 times out of 10 in Perl, you don't even need to worry about such encapsulation, although you may still benefit from its organization. Encapsulation is essentially used for 2 reasons: to hide away internal representations of bytes (double vs long etc.) and to keep your code organized. Along the lines of organization are working with large teams where you don't want some team relying on the internals of your code if you will making changes to it -- if they can reliably use an unchanging interface, this can prevent a breakdown of communication among large teams.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    

      Jeffa, thank you for sharing your insight on the subject. I appreciate it. :)

Re: OOP's setter/getter method - is there a way to avoid them? ( what should be an object and what should it do)
by Anonymous Monk on Oct 27, 2015 at 09:30 UTC

      Thank you for generously suggesting different resources. And, yes, you have valid points and questions. They are all worth considering. I'm still learning that it takes a special way of looking at things when using an object-oriented style of programming. I'm afraid that my concept of class object has not fully evolved yet. It's hard to transition from the mundane concept of an object as a mere instance of a class to the concept that objects (even supposedly inanimate objects such as apple) could actually behave like living objects that bring forth methods or actions (i.e. saying "I am a red apple"). :)

Re: OOP's setter/getter method - is there a way to avoid them?
by stevieb (Abbot) on Oct 27, 2015 at 13:49 UTC

    That is a great book. I read it several times, and foundation of the knowledge I have of references to this day is owed to that book.

    Personally, unless absolutely necessary, I try to stay away from having to set attributes individually. I prefer to try to set these within larger public methods that set/reset the attribute then do something functional with it, like this:

    sub write_graffiti { my $self = shift; my %params = @_; $self->{colour} = $params{colour} if defined $params{colour}; # spray paint wall with the colour, # whether new or existing }

    When I do need to expose a direct setter/getter for an individual attribute, I do both in one fell swoop, in a more generic sub:

    sub colour { my $self = shift; my $colour = shift if @_; $self->{colour} = $colour if defined $colour; return $self->{colour}; }
Re: OOP's setter/getter method - is there a way to avoid them?
by shmem (Chancellor) on Oct 27, 2015 at 22:51 UTC

    For real encapsulation of an objects data, which provides black box inheritance, is thread safe and has little impact on performance, check Alter, which has received too little attention by the Perl Community up to now.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
      The author of Alter also wrote Hash::Util::FieldHash which is a core module and has a similar goal to Alter.

        oh. I wasn't aware that Alter had indeed been added to the perl core, under another name. And it's in there since 5.10! Yay! Thanks for the hint, Arunbear!

        (hint to $self: take the time to read perldeltas!)

        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: OOP's setter/getter method - is there a way to avoid them?
by BrowserUk (Pope) on Oct 28, 2015 at 08:57 UTC
    My question is, are setters and getters still used these days in Perl programming?

    I've followed the responses to this thread with interest. The sum total of them seems to be: getters and setters are okay because they are internal to the class.

    I say, for the most part, that is phooey.

    Well written classes for most objects should never need setters and getters for their internal attributes.

    An example: A BankAccount class.

    One way to write that it to have a getter and a setter for the balance attribute. The code charged with processing transactions receives a transaction for a particular account number; creates an instance (proxy) for that account; calls the $act->get_balance() method to retrieve the current balance; adds or subtracts the transaction amount depending if it is a deposit or withdrawal; then calls the $act->set_balance() method to store the revised amount. This is WRONG!

    The transaction processing code should: instantiate the account, and the pass the transaction object to $act->transact( $trans ) method. That method then performs all the required checks and balances before finally -- assuming all is well -- modifying the balance attribute to reflect the transaction.

    Well designed classes should (almost) never need to expose their internal attributes to the outside world via setters & getters. Calling code should not query current values, modify them and then set them back; it should pass the information detailing the change to an appropriate method that will perform that task.

    That's why I'll never be a Mo(o)(u)(se) user. Pretty much the only thing those modules do for you is automate the construction of setters and getters along with validating the values passed to them. But as (almost) no class should ever require getters & setters that is all redundant.

    As for validation: If all values entering the class come in via 'do something useful' methods, by the time the objects attributes get around to being modified, the logic of those methods has already ensured that the values being set into attributes are valid; so further indirection and validation is both redundant and noxious.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.

      What you're saying, in short, is to take responsibility for implementing the actions taken on your object rather than foisting that responsibility onto code outside the object?

        What you're saying, in short, is to take responsibility for implementing the actions taken on your object rather than foisting that responsibility onto code outside the object?

        Yes, but also more than that.

        The use of accessors & mutators does not necessarily imply that. For example, my BankAccount example might be implemented something like this:

        sub new { my %account; ... return bless \%account; } sub getBalance { my $self = shift; return $self->{balance}; } sub setBalance { my( $self, $newBalance ) = @_; $self->{balance} = $newBalance; return; } sub transact { my( $self, $amount ) = @_; my $newBalance = $self->getBalance() + $amount; if( $amount < 0 ) { ## withdrawal if( $newBalance > 0 ) ) { $self->setBalance( $newBalance ); } elsif( $newbalance > $self->overdraftFacility() ) { $self->setBalance( $newBalance ); } else { die 'Overdraw attempt'; ## raise exception; allow caller t +o deal with the problem } } else { ## deposit $self->setBalance( $newBalance ) } return $newBalance. }

        But the point to note here is that getBalance() & setBalance() serve no purpose. There is no purpose in performing any further validity testing within those methods as they should never be called from outside; and whenever they are called from inside, all validity checking required or possible should have already taken place.

        So every use of those methods can be directly and correctly substituted with inlined, direct access to the object attributes; thus they are pure overhead for no benefit; and with the very great downside of breaking encapsulation by exposing the internal attributes to the outside world via the very accessors that are apparently intended to ensure it!

        The same applies to pretty much all other accessors and mutators, with the very rare exception of when it makes sense to have classes of objects that are nothing more that bags of associated variables. And I do mean, very rare.

        There are only two arguments that even vaguely make sense for the provision of accessors:

        • The use of accessors -- internal to the class -- simplifies the (potential future) process of changing the underlying storage of the class. Eg. Moving from a hash-based to array-based (or vice versa) class implementation.

          Sounds cool; but in nearly 30 years of writing and using OO classes; I've never seen an occasion where this was necessary without it also requiring so much other redesign that the savings attributed to the use of accessors would simply be lost in the noise of the overall re-work effort.

          In the greater scheme of things, imposing a recurring, unnecessary, and avoidable fixed overhead on every use of a class in every application that uses or reuses it, in the forlorn hope that you might gain some insignificant benefit from it at some point in the future that in 99% of cases will never arrive is the absolute height of the programmer arrogance that their time is more valuable than that of their 10s, or 100s, or millions of users.

          The arrogance that it is worth the recurring imposition of overhead upon every run; affecting every program that uses the code; and every user that uses those programs; just in case it might save them (the programmer) a few minutes at some unspecified point in the future.

        • That they simplify the process of extending (subclassing) the class.

          I've seen this argument put forward, but never seen any evidence that it is so. It seems to me to be just as easy to subclass a class that doesn't use accessors as it is one that does. And further more, the absence of the additional overhead of accessors in the parent class mean that subclasses also benefit.

        To date, and I've been arguing this point for most of my career, the provision of externally accessible accessors and mutators is a direct contravention of the design goals and aspirations of OO design. And the use of internal use only accessors and mutators -- where the language allows this -- is pure avoidable overhead with only a theoretical potential benefit that in 30 years I've never seen realised.

        In compiled languages with decent optimising compilers; that overhead is minimal as the accessors and mutators get in-lined at compile time; but in a interpreted languages without that benefit and without a mechanism to prevent those accessors being used externally to the class; they are not just overhead, but severe code-smell.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: OOP's setter/getter method - is there a way to avoid them?
by karlgoethebier (Prior) on Oct 27, 2015 at 19:50 UTC
    "...is there a way to avoid them?"

    This might be of interest, less or more.

    I don't know the latest encyclical ;-[

    IMHO it seems to change from time to time.

    Regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

      This (Stop creating mutable objects.)

      Imagine:

      1. If your bank account number changed every time you deposited or withdrew money.
      2. You had to buy a new fridge or freezer (or construct a new larder) every time you brought home new food; or consumed some.
      3. If you had to buy a new car every time you need to top up the tank.

        (How would that work when you are driving and using fuel?)

      Too real-world for OO programmers to consider relevant?

      Then think on this:

      Every time the balance in an account object changes; something has to 'mutate': either the current balance changes; or you create a new account object, duplicating all the attributes as the existing one except the balance. And then discard (garbage collect) the old one.

      "Spooky action at a distance" is a great quote from a great man about a truly spooky phenomena; and utterly bogus when applied to changing the bit-pattern held at a location in DRAM.

      Read only objects are akin to, and equally nonsensical, as read-only variables: the triumph of theoretical dogma over pragmatic practice.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice.
        "...the triumph of theoretical dogma over pragmatic practice."

        I didn't endorse these practices.

        And i must admit that i don't understand why some folks make such a bohei about.

        "Don't shoot the messenger." (British author?)

        Thanks and best regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

Re: OOP's setter/getter method - is there a way to avoid them?
by sundialsvc4 (Abbot) on Oct 27, 2015 at 13:22 UTC

    It might be time to stop reading books, so to speak, and get into the water.   There’s a little bit of room for theory in this business (which is really not “computer science” at all ...), but it is mostly practicum.   And OOP – which, by the way, is not “30% slower” – is mostly a practical way of looking at things so that you can write more-maintainable source code.

    Always remember that production applications may consist of a million or more lines of source-code, most of which you did not write and have never looked at, and never will.   By placing strictures upon the language, and thus upon ourselves, we enable the computer to do the one thing a piece of silicon does best.   The computer never “overlooks” anything.   It does process all those lines of code, and, if we reduce what we are looking for (namely, our own mistakes) into something that a yes-or-no machine can detect, that’s a huge win for us.   “Getters and setters” are in the OOP implementation by design.   Methods are the buttons.   Properties are the dials and knobs.   Everything that is concerned with this chunk of data has been moved into the class definition, and can be nowhere else.

    So, the definition of a class (and of its clearly-identified ancestors and “friends”) is known to encompass all of the source-code that can directly manipulate a particular piece of data.   And, unless we are specifically concerned with that class’s definition, we can safely ignore the details, knowing that we do not have to concern ourselves with them in order to correctly write code that does the right thing.   Furthermore, we know that if we do make certain very-common types of misakes ... ;-) ... the computer itself will catch it and refuse to compile our code.   If we need to change something, we need to change it in only one place and we also know that there cannot be any other place where “a corresponding change must be made at exactly the same time, or else.”

    Perl’s OOP-design, which was mostly grafted-onto an existing language, is very much shaped by the fact that it is a dynamic interpreter, not a static compiler.   Therefore, it is not “pure.”   But, no practical language really is.

      It might be time to stop reading books, so to speak, and get into the water.

      Take your own advice or stop giving it out

Re: OOP's setter/getter method - is there a way to avoid them?
by sundialsvc4 (Abbot) on Oct 27, 2015 at 15:34 UTC

    Certainly, in the case of Perl, getters and setters are a matter of practical necessity in the Perl language, if you wish to ensure that no other piece of code in your grand application is manipulating a property directly.   OOP was grafted-onto this language, which does not have the “strong sense of compile-time” that you have in a language like C++.   OOP is optional.   You can get around it.   You can decide not to use it.   You can decide to use it and then also not-use it, and the language has only a very limited ability to catch you.   If you want to centralize where a property can potentially be manipulated, you must use getters/setters, and you must use them “in the right way.”   These factors very-simply draw from the design and architecture of this particular language in which we work.   (By saying these things, I am making no negative statement or criticism whatsoever.)

    Other languages allow us to, for example, declare a private variable, then expose that directly as a property for reading and/or for writing.   Or, if we choose, to declare a getter and/or a setter, doing so only when we must.   The design of the language is such that the language compiler can enforce these self-imposed restrictions while safely generating optimizable code.   This option is not available unconditionally in Perl, due to the nature of the language, which draws from its provenance and history.   However, I do think that the various people who did address this issue (including the unprecedented system, Moose, the likes of which I have never seen in any other language) did an excellent job.   Possibly the most astonishing thing about Moose, IMHO, is the ability to say, no Moose; over certain specific sections of your source-code, and then later on to say use Moose; again.   And it actually works, giving you the best of both worlds at the price of having to know exactly what you are doing, which Perl generally assumes you do.   You might assume that something as “radically different” as Moose et al would carry with it a hefty performance price ... but it doesn’t.

      My eyes get blurry at this point. Without deeper qualifications almost everything you said is false. Picking two easy ones.

      including the unprecedented system, Moose

      I alluded to this before when you went on a Perl6 bashing rant while singing the praises of Moose—from the Moose docs: Moose is based in large part on the Perl 6 object system, as well as drawing on the best ideas from CLOS, Smalltalk, and many other languages.

      You might assume that something as “radically different” as Moose et al would carry with it a hefty performance price ... but it doesn’t.

      Of course it does. Moose is about 1,000% slower than straight hashrefs, 750% slower than plain objects, and there are sweetened syntax/utility options like Object::Tiny::XS and Mouse::XS that are still much faster than Moose. But again, without qualification for what use, what place, etc, all such speed statements are noise.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1146074]
Approved by Perlbotics
Front-paged by Corion
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2018-01-16 15:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How did you see in the new year?










    Results (182 votes). Check out past polls.

    Notices?