[Request] 'Properties' - getter/setter shortcuts
See original GitHub issueThe Problem
Let’s say you’re making a Vector2
class that indicates a position or direction in 2D coordinate space:
class Vector2{
float x,y;
}
Now, the X and Y instance variables may be accessed very often, and in moderately complex ways. For example:
v1.x *= (v2.x * v3.y);
v1.y *= v2.y;
The issue here, however, is that making x
and y
public is dangerous. What if you happen to make a class that holds immutable vector constants, such as (0,0)
or (1,0)
or (0, 1)
, and one of the constants gets modified? Or, what if you want to make sure that the components never get set to NaN
or some other illegal value? You would be forced to make both fields private, and add getters/setters to prevent modifications in subclasses. However, this would severely impact usability. The code above would become:
v1.setX(v1.getX() * (v2.getX() * v3.getY()));
v1.setY(v1.getY() * v2.getY));
This may not be a massive difference, but when you’re dealing with many vector operations, typing getX()
every time you want to access a component gets very tedious.
The only alternative to getters and setters here would be to keep the fields public, and hope that nobody messes things up accidentally. Immutability is not an option either, as it can cause garbage collection and stuttering. There is no good solution here.
(By the way, this is not a made-up issue - libGDX has this exact problem with mutable colors and vectors)
The Solution
Similarly to other languages like C#, generate “extension fields” (properties) that would internally call getter and setter methods. When this option is enabled, methods of the form getAbc
and setAbc
can be invoked by accessing or modifying the field abc
. Accessing the field inside its class works like it normally does - no methods will be called.
Groovy already does something similar when interfacing with getters and settters in Java, I believe.
Note that the field would not have to actually exist in order for this syntax to work. It would only examine the presence and getters/setters with a specific name.
Thus:
class Vector2{
private float x,y;
public float getX(), setX(), getY(), setY()... //standard getter/setter implementations here
public float getLength(){
//implementation
}
public String toString(){
//fields are used directly, *not* the accessor methods
return x + ", " + y;
}
}
//somewhere else...
Vector2 v = ...
v.x = 1.0; //uses setter method
v.y *= 99.0; //uses getter + setter methods
System.out.println(v.length); //uses getter method - note that this field doesn't actually exist!
v.length = 0; //compilation error - no setter defined
This system would also have several added benefits to it:
- Accessing object hierarchies with many levels of composition would become much simpler. As an example: Instead of calling
getApplication().getContext().getSecurityHandler().getName()
, one could simply doapplication.context.securityHandler.name
. - Encapsulating previously-public fields would become easier. When replacing something with a getter and/or setter, no users of that API would have to change their code.
Potential Issues
- May be very complex to implement. I don’t know exactly how Manifold generates fields and methods, but since it already supports faking field visibility/access through the
@Jailbreak
annotation, I would assume that this feature is at least possible. - May lead to significant style changes, since
get/set
become unnecessary. - May be confusing to read for those who don’t know that methods are being used internally. However, Manifold already does similar “hidden methods” with operator overloading and extension methods, so I don’t think this should much of a problem.
- May need some tweaking to figure out how to generate names for getters with strange names - should the field for
getX()
beX
orx
? How about forgetURL()
?
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:6 (4 by maintainers)
Top GitHub Comments
Thank you very much! It doesn’t look like this issue is needed anymore, so I’ll close it.
Note this issue is considered a duplicate of https://github.com/manifold-systems/manifold/issues/242, which is now under development. Properties are coming soon 😃