www.digitalmars.com         C & C++   DMDScript  

D - Getters and Setters

reply "Sheldon Simms" <sheldon semanticedge.com> writes:
From the Documentation:





is a set'er, and an rvalue is a get'er: class Abc { int myprop; void property(int newproperty) { myprop = newproperty; } // set'er int property() { return myprop; } // get'er } which is used as: Abc a; a.property = 3; // equivalent to a.property(3) int x = a.property; // equivalent to int x = a.property() Thus, in D you can treat a property like it was a simple field name. A property can start out actually being a simple field name, but if later if becomes necessary to make getting and setting it function calls, no code needs to be modified other than the class definition. <<<< I've been wishing Java had this for a long time. The given examples, though, seem kind of funny. Why shouldn't the getter and setter names be exactly the same as the property name? That way, you don't even have to define the getter and setter methods to get the default functionality: class ABC { public: int property; // getter and setter automatically defined ... } ABC a; a.property = 3; // equivalent to a.property(3) int x = a.property; // equivalent to int x = a.property() Now if there is some reason to change the semantics of getters or setters, you can do so by defining the method explicitly: class Doubler { public: ABC property; void property (ABC foo) { // don't just reference it (default), make a copy property = foo.deep_copy(); } } Doubler d; d.property = a; assert(a != d.property); // succeeds, assuming != compares object identity As far as access control goes, this would act as if the attribute value itself was always private, and the getters and setters were whatever is specificied in the class definition. Assuming class members are private by default, you could make an attribute read- only like this: class DEF { void property(int); // the property-setter is private public: int property; // but the property is in general public } Or like this: class GHI { int property; // the property is in general private public: int property(); // but the property-getter is public } I'm using this "declaration-like" syntax above to keep from having to redefine the method, when all I'm interested is access-control. -- Sheldon Simms / sheldon semanticedge.com
Aug 16 2001
next sibling parent Chris Friesen <cfriesen nortelnetworks.com> writes:
Sheldon Simms wrote:

 I've been wishing Java had this for a long time. The given examples,
 though, seem kind of funny. Why shouldn't the getter and setter
 names be exactly the same as the property name? That way, you
 don't even have to define the getter and setter methods to get
 the default functionality:
 
 class ABC
 {
 public:
    int property;
    // getter and setter automatically defined
    ...
 }
 
 ABC a;
 a.property = 3; // equivalent to a.property(3)
 int x = a.property; // equivalent to int x = a.property()
 
 Now if there is some reason to change the semantics of getters
 or setters, you can do so by defining the method explicitly:

This is a great idea. I'm all for it. -- Chris Friesen | MailStop: 043/33/F10 Nortel Networks | work: (613) 765-0557 3500 Carling Avenue | fax: (613) 765-2986 Nepean, ON K2H 8E9 Canada | email: cfriesen nortelnetworks.com
Aug 16 2001
prev sibling parent reply "Tim Sweeney" <tim epicgames.com> writes:
 In D, get'ers and set'ers take advantage of the idea that an lvalue
 is a set'er, and an rvalue is a get'er:

 class Abc
 {
     int myprop;
     void property(int newproperty) { myprop = newproperty; } // set'er
     int property() { return myprop; } // get'er
 }

 which is used as:

 Abc a;
 a.property = 3; // equivalent to a.property(3)
 int x = a.property; // equivalent to int x = a.property()

Why??!? :-) In current reasonable languages "a.x" is a variable access and "a.f(x)" is a function call. Why complicate this so that "a.x" could either be a function call or a variable access, depending on its (possibly very complicated) context? Also, this seems to create ambiguity (or context-specific special-casing of sematics) with function pointers. Given a reference to a function p taking a parameter, p=a could either mean calling it with a parameter of a, or initializing it to a. I know Bertrand Meyer advocated this approach in Eiffel, but this has been shown to be one of several areas (along with, i.e. covariant typing on function parameters) where Eiffel's type system is unsafe and problematic.
 Thus, in D you can treat a property like it was a simple field name.
 A property can start out actually being a simple field name, but if
 later if becomes necessary to make getting and setting it function
 calls, no code needs to be modified other than the class definition.

That breaks with open-world modules. For example, given a module declaring a class like: class c { int a; }; How can you subclass it later on in another module like: class d: public c { int a() {...} }; The similar question comes up with binary-compatible evolution of modules (i.e. Java's list of rules, "You can do the following things to evolve a class without breaking existing precompiled modules that depend on it". That's an essential thing that's vital to writing real-world programs, such as applications supporting plug-ins. The only sound solution to this is that every variable access in a program has to translate to a virtual function call, which obviously isn't reasonable. -Tim
Aug 17 2001
next sibling parent reply Charles Hixson <charleshixsn earthlink.net> writes:
Tim Sweeney wrote:
...
 Why??!? :-) In current reasonable languages "a.x" is a variable access and
 "a.f(x)" is a function call.
 
 ...
 I know Bertrand Meyer advocated this approach in Eiffel, but this has been
 shown to be one of several areas (along with, i.e. covariant typing on
 function parameters) where Eiffel's type system is unsafe and problematic.
 
 ...
 -Tim

I've never seen that shown. I know that Eiffel tends to be a bit inflexible, but this is one (of several) areas that I feel it got right. Especially if one is going to be having overridden-via-inheritance classes. It's quite reasonable that some classes would implement, e.g., a counter by a function and others by a variable. And a reference via inheritance shouldn't be required to know ahead of time which kind of reference the exact class is making. I think that information hiding is in favor of this, also, but the main thrust comes from simple utility and code re-use.
Aug 20 2001
parent reply "Walter" <walter digitalmars.com> writes:
I have mixed feelings about the getters and setters. They are turning out to
be a problem in the compiler, and may wind up getting dumped.

Charles Hixson wrote in message <3B8163BE.6080402 earthlink.net>...
Tim Sweeney wrote:
...
 Why??!? :-) In current reasonable languages "a.x" is a variable access


 "a.f(x)" is a function call.

 ...
 I know Bertrand Meyer advocated this approach in Eiffel, but this has


 shown to be one of several areas (along with, i.e. covariant typing on
 function parameters) where Eiffel's type system is unsafe and


 ...
 -Tim

I've never seen that shown. I know that Eiffel tends to be a bit inflexible, but this is one (of several) areas that I feel it got right. Especially if one is going to be having overridden-via-inheritance classes. It's quite reasonable that some classes would implement, e.g., a counter by a function and others by a variable. And a reference via inheritance shouldn't be required to know ahead of time which kind of reference the exact class is making. I think that information hiding is in favor of this, also, but the main thrust comes from simple utility and code re-use.

Aug 22 2001
parent reply Dan Hursh <hursh infonet.isl.net> writes:
	That's a shame.  I get it would be to ask for an enhancement to it
then, right?  I'll do it anyhow.  It looks like a setter/getter pair
cannot have the same name as a data member.  (reasonable enough.)  Would
it be possible for a sub-class to hide an inherited data member behind a
setter/getter pair and then allow the sub-class to access the parent
data via super?  This would only allow you to access you parent's data
and not your grandparent's, but that may not be all bad.
	Of course, if it doesn't make it in then this is moot.  On a related
note (at least in my mind), is it expected to be possible to have lvalue
function calls?

Dan

Walter wrote:
 
 I have mixed feelings about the getters and setters. They are turning out to
 be a problem in the compiler, and may wind up getting dumped.
 
 Charles Hixson wrote in message <3B8163BE.6080402 earthlink.net>...
Tim Sweeney wrote:
...
 Why??!? :-) In current reasonable languages "a.x" is a variable access


 "a.f(x)" is a function call.

 ...
 I know Bertrand Meyer advocated this approach in Eiffel, but this has


 shown to be one of several areas (along with, i.e. covariant typing on
 function parameters) where Eiffel's type system is unsafe and


 ...
 -Tim

I've never seen that shown. I know that Eiffel tends to be a bit inflexible, but this is one (of several) areas that I feel it got right. Especially if one is going to be having overridden-via-inheritance classes. It's quite reasonable that some classes would implement, e.g., a counter by a function and others by a variable. And a reference via inheritance shouldn't be required to know ahead of time which kind of reference the exact class is making. I think that information hiding is in favor of this, also, but the main thrust comes from simple utility and code re-use.


Aug 23 2001
parent "Walter" <walter digitalmars.com> writes:
Dan Hursh wrote in message <3B85D1A1.9EF78A97 infonet.isl.net>...
 That's a shame.  I get it would be to ask for an enhancement to it
then, right?  I'll do it anyhow.  It looks like a setter/getter pair
cannot have the same name as a data member.  (reasonable enough.)  Would
it be possible for a sub-class to hide an inherited data member behind a
setter/getter pair and then allow the sub-class to access the parent
data via super?  This would only allow you to access you parent's data
and not your grandparent's, but that may not be all bad.

Yes.
 Of course, if it doesn't make it in then this is moot.  On a related
note (at least in my mind), is it expected to be possible to have lvalue
function calls?

No, no lvalue function calls unless the function returns a reference. -Walter
Aug 24 2001
prev sibling parent "Anthony Steele" <asteele nospam.iafrica.com> writes:
"Tim Sweeney" <tim epicgames.com> wrote in message
news:9lkhq6$2p61$1 digitaldaemon.com...'

 Why??!? :-) In current reasonable languages "a.x" is a variable access and
 "a.f(x)" is a function call.

Delphi, which I think is current and reasonable, if y := a.x(); is a function call with no params, then the brackets may be and usually are omitted, giving y := a.x; If you are using an object, and want to read a value off it, you care about the meaning of that value, not if it it returned by public data, public function or public property (in Delphi it could be any of the three). In java, you have x = myArray.length; y = myString.length(); What is the semantic difference? none. So why the syntactic difference? Even better - public data can can be turned into private data acessed through a gettor and a settor that checks it's args *without the client code knowing or caring* about the implementation of the public contract. That to me is a win. A public fn can be replaced by the gettors and settors of a property, as the system grows. I've found this feature to be usefull.
 Also, this seems to create ambiguity (or context-specific special-casing

True, this is a drawback. You don't get something for nothing.
 That breaks with open-world modules.
 How can you subclass it

I don't really see why not allowing non-private methods and data with the same name is a major loss.
Sep 04 2001