Getting "this" to work similar to "self" in Python

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Jul 22 19:39:06 PDT 2015


On Wednesday, July 22, 2015 23:19:35 nurfz via Digitalmars-d-learn wrote:
> Hmm, is there a specific reason aside from the encapsulation
> violation?  It seems needlessly complicated.  If you have
> someone/something that has direct access to your source code,
> isn't a getter/setter the least of your concerns?

It has nothing to do with people having access to your source code. It's
leaking how your class is implemented when you provide access to its member
variables, which makes it so that code that uses it is more likely to depend
on how it's currently implemented, and it makes it harder to change your
code later. Users of your class should not depend on the internal
implementantion of that class, since it creates unnecessary dependencies.
Search on "high cohesion" and "low coupling," and you'll find stuff talking
about how your code is more maintainable and of better quality when
internals are kept internal, and dependencies across types are kept to a
minimum.

And remember that just because a getter/setter or property function happens
to currently wrap a member variable, doesn't mean that it will later. For
instance, you may need to change your code later so that the value in
question is actually calculated rather than stored directly in the class.
If the member variable is public, then making that change will break all
code that uses that member variable, whereas if it's accessed via getters
and setters (or property functions), then all of the code that uses that
class will continue to work as it did before, which could save you a fair
bit of time and effort, and if your code is part of an API that's publicly
available, then you avoid breaking a lot of other people's code.

And even if your getter/setter/property function will always wrap a member
variable, it could be that you'll need to add code to the function(s) later
that does extra checks, or sets another variable, or calls another function
in addition to getting the current value of the member variable or setting
it to a new value. It may not always simply access the variable. If you've
made the member variable public, you'll be forced to break existing code
when you need to wrap it in a function later. It's just good practice to
make all of your member variable private and not provide direct access to
any of them.  It'll save you from pain later when you have to change how
your class works, even if it's as simple as adding log messages.

Even worse in D, invariants get called before and after a public member
function is called. They don't get called when you access a public member
variable. So, if you have a public member variable in a class with an
invariant, you're just shooting yourself in the foot, because you can't
guarantee the invariant anymore. It's not getting called when the member
variable is accessed, and the code accessing it can do whatever it wants to
it, including violate the invariant, and you won't catch it until a public
member function gets called later, which could be in completely unrelated
code.

If you start searching for encapsulation and programming, or encapsulation
and OOP, or data encaplusation, or anything like unto it, you will very
quickly find a lot of stuff telling you to never make your member variables
public. It's commonly considered bad practice in languages like C++, Java,
C#, D, etc. because it's a mantainance problem when you do, and it really
doesn't play well with OOP, since very few languages that support OOP have
polymorphic variables (since to do that, you need wrap their access in
function calls internally anyway).

> Does the @property decorator incur a large runtime cost?

@property is only applicable to functions and has no effect on the runtime
cost, though if a function is not inlined, then it will cost more than
accessing a variable directly. So, if your question is whether wrapping
member variable access in a getter/setter or a property function costs more,
then that depends on whether the call gets inlined. If the call is inlined,
then the cost is the same, and if they're not virtual one line functions are
going to be inlined if you compile with -inline (which you would normally
use in a release build). And if you're comparing with python, D would win
regardless, because the only way that python can have polymorphic variables
is by looking them up rather than simply accessing them directly as occurs
in a language like D, C++, Java, etc. So, python is essentially always
wrapping your variable accesses in getters and setters.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list