Just a quick thought here after looking at someone’s code I just stumbled on. This person had a “isReadOnly()” method inside of a generic “set” method which would allow them to determine if a property should be allowed to be modified or not.
It got me to thinking again how the traditional notion of “visibility” in OO is, imo, broken. Perhaps that’s going a bit far. It doesn’t address the day to day needs most developers have. I’d say more developers need some sort of a way of making properties “read only” than they do dealing with “public, protected, private” PPP notions which we get in traditional OO implementations. What PPP gives is all-or-nothing – you get full access to this property (or method) or you don’t get any at all.
Short port (I gotta run) – why do we not have some sort of default “read only” property modifier in OO implementations? The Groovy approach would be to create a setXXX() method that was empty, effectively overriding the default setXXX() method to not perform any manipulation at all. It’s not *bad*, and is pretty clear, but some modifier like, oh, I dunno:
readonly String name
would be useful, no?
I couldn’t agree more.
The Ruby solution is that no attributes are visible from outside of an object and they’re only made accessible through methods. The language then provides some shortcuts for creation of accessors which can be read, write or read/write.
I’m skeptical of the application most programmers use readOnly, even more so with public/private/protected.
99% of the time these features are used to protect programmers from themselves using over-engineered API’s for setting properties. If something shouldn’t be touched I make the variable start with “_”, if someone wants to mess with it they are doing so at their own risk.
If you’re writing an incredibly public API then you need to bounds check all the input anyway and having a structured internal API doesn’t actually help that.
Of course there are times where sandboxing is needed and these features can be used to great benefit but this is certainly a less than 1% case.
Objective-C and C# have readonly
I absolutely agree with this. When writing PHP code, I often end up making class member variables private/protected and giving them get() methods only. It would be a lot nicer/faster/clearer if I could just slap “readonly” in front of the variable name. Also, I never understood the point of having simple get/set methods – if you’re going to do that, why not just make the variable public?
This will teach me to post and the run off immediately afterwards. My JUG tonight schooled me with cries of “final static”!
In general I like the idea of volatility being expressed in some way as part of the language itself, without having to resort to hacks like the one you encountered. Java does provide a lot of control over this, which is one of the things I like about Java.
Huh? We already have read-only properties for ages.
type
TWhatever = class
private
FReadMe: string;
published
property ReadMe: string read FReadMe;
end;
What do you base this on:
I’d say more developers need some sort of a way of making properties “read only” than they do dealing with “public, protected, private” PPP notions which we get in traditional OO implementations
I think I don’t agree to that. If you find that you have more properties that should be readonly, than members that need to be ppp’d, then you should ask yourself if a property is the right solution for what you are trying to accomplish.
But let’s forget that for a minute and look at solutions. In traditional OO, encapsulation is the way to handle this. By making properties private and then encapsulating them in getters and setters, you are in full control of what happens to the property. If you want it to be readonly, you just don’t provide a setter.
That being said, if you still want to have a property that is publicly accessible, but not writable, and you don’t want to encapsulate it (which in most languages is the arguably best solution), then you have a number of options. Const members are available in most languages to make something readonly, but then it will be readonly to your own class as well. In PHP, you could make a virtual property using __get and __set and then implement __set such that certain properties are not changed.
i totally agree with ivo. we can already do this in php. a readonly property is only
syntactic sugar.
i’d rather consider a “readonly” feature dangerous like “private” or “final”.
it’s easy to overuse them and break the open/close principle.
The correct way to implement this is not to have a setter for the property. However in languages like php that dont support constructor overloading people are lazy and end up with constructors that dont create “valid” objects (in the business sense) and these object are then constructed by the caller using set methods.
As I wrote before, I sent this off then just went offgrid for a number of hours, and had some other thoughts on this which I’d have liked to have gotten down or modified.
“final static”, at least in Java, is an approach. Writing an empty setter is another approach.
I would say to those who think something like “readonly” is just “syntactic sugar” that public/protected/private is “syntactic sugar” as well. Based on the definition, I’d say there’s not one thing you can do functionally in code that is affected by public/protected/private. Well, I guess if you want to call throwing access exceptions “functionality”, then yes, you get a bit more functionality with PPP, but it’s not the kind most people care about. PPP is something there primarily for the developer during dev time and compilers during compile time.
I can write programs which are easier for developers to understand (derive intent, etc) using PPP, but there’s no additional functionality. When I moved from PHP4 to PHP5, my programs didn’t get any more functional because of this syntactic sugar. Yet huge numbers of people thought of this as the best thing since sliced bread, because it made it apparently easier for them to write code. Fair enough. Something like a ‘read only’ type property wouldn’t add any extra functionality, but would make reading and writing code easier for some people.
I think Ivo is right. The “PHP Way” to do this is using the Magic Methods. Hold an array with the fields you want to be readonly and then disable overwriting them in __set.
@Martin Holzhauer
@Ivo
That would be nice, but magic __set __get only work for unset attributes in PHP. So, you cannot do this unless you are willing to sacrifice automatically generated documentation and IDE code completion.
Do we really need more excuses not to document code?
Also, I wouldn’t consider magic get/set to be a *way* of doing anything. It’s a simple hack to avoid warnings… i don’t understand how, or if, it could work with serialization, introspection, or anything beyond the simplest case of $x->foo.
Specifically speaking for PHP, I’d love to see the Groovy approach adopted. I just got access to the RFC area, and am planning to draft this up.
class foo {
public $name;
public $email;
public $ssn;
public function getName() {
// override access to the $name property
}
public function setEmail() {
// override access to setting the $email property
}
}
If a property is accessed (defined or not – don’t use the current __magic approach) – PHP would look for a corresponding getXXX or setXXX method. If it’s there, use it. If not, fallback to whatever the default behaviour would be (setting or getting the value).
This would be backwards compatible with all existing code, but would allow for easy refactoring of code by allowing any modifications that need to be done when getting/setting values without having to refactor your entire codebase to use get/set methods. For code that already has get/set methods defined for properties, nothing would change.
Concerns about get/set method lookups being expensive – code caches would take care of most of that, but it could be a quick compilation step when a class is created. Or, if a method is found to exist at runtime, that info is cached just for the life of the script (many properties are accessed multiple times, so this would still be useful, even without a bytecode cache).
The backwards-compatibility problems of what you’ve just suggested are too horrible to contemplate
The problem with __get() et al is the performance overhead, plus the documentation issues already mentioned.
Why not simply introduce a ‘readonly’ keyword when declaring attributes? This won’t break existing code.
class foo
{
public readonly $var;
}
Best regards,
Stu
What backwards compatibility problems would arise? I’ve thought about this for awhile (on and off for months) and I’m not seeing any. Doesn’t mean they don’t exist, but what do you see as a BC issue?
The reason to use a getter method or __get() instead of a read-only property is to separate the implementation from the interface. This is important for library code and good practice elsewhere else.
PHP does not support C#-style properties which allow the property syntax while still allowing separating the implementation from the interface. Until such a feature is added to PHP, the only ways to do it are getter or __get() methods.
Actually in Groovy the final modifier will give you just that
class Person {
final int id
Person( int id ) { this.id = id }
}
The Groovy compiler will generate getId() but not setId()
If something is read-only why is set being called on it? Generic set methods can be useful for implementations when you’re repeating yourself but that method should never be called for something you consider read-only. This is a design flaw in the code not the language.
I like to take a more interface centric approach. If an interface has setXXX methods then you can change XXX, if it doesn’t then you can’t.
The backwards-compatibility problem is simple. You are assuming that any get/set methods in existing code are there as wrappers around the associated object attribute, and you’re assuming that making PHP automagically call these get/set methods won’t cause unintentional problems.
Assumptions are the source of most fsck-ups
Python has a nice solution for this:
You can also specify setter & deleter methods for a property, if desired.
Of course, it should be noted that “private” for instance variables in python is really only a convention (kinda like PHP4) — and while this bothered me at first, in practical terms I think it works very well. In general I have observed that Python is an enabler language; it would seem to me that preventing access to object properties would really contradict the spirit of the Python object model (which is far richer than any OO model I’ve encountered in languages like Java, C#, and certainly PHP). Providing convenience solutions (like @property) for making code readable and intuitive, though, is certainly something Python does well.
-Hans
I also see little real benefit from PPP. I close to never use “private” and most often when I still use “private”, I end up changing it to “protected” eventually.
As for readonly. I presume you mean readonly for “outside” code? If you mean just define once, there are of course constants, which do have their severe limitations. So much so that Georg Richter pushed towards being able to return db results as readonly variables. This would also have the nice benefit that their memory footprint could be much more efficient.
Yeah, perhaps I didn’t clarify enough. The idea would be that anyone could read the property (well, within the bounds of the PPP visibility restrictions) but they’d only be writeable within the class itself. So, technically, it’s not really “readonly”, but “readonly_from_outside”
I think the way C# implements readonly properties is the easiest syntax and simplest way to do it. Primarily because C# uses the concept of accessors. Example:
public class Loan
{
private string _ssn = “123456789″;
public SSN
{
get { _ssn };
}
}
In this example there is no way to “set” the SSN, only read the value. Other logic could be added within the get accessor to substring the last 4 chars or even add security checks to make sure the person requesting the property has access to view that property.
The way we’d right that same example knowing we wouldn’t need any get logic today would be:
public class Loan
{
public string SSN { get; private set; }
}
There is a lot of CIL magic happening behind the scenes but we use this all the time in C#.
The big thing about java and other languages that always bothered me was having methods in a class that set and get information. It is too cumbersome and doesn’t work well when binding data and reflecting over objects.
My $.02.
-Keith
Interesting to see C#’s evolution here, because the original C# didn’t have accessors AFAIR. They were introduced in 2.0, no? Definitely useful.
I see the Groovy approach (and what I’d recommended for PHP) as a middle ground approach. The traditional getXXX() and setXXX() methods are still there under the hood, and still the way of defining behavior, but code accessing the properties does not need to use the explicit get/set method names.
Most of the C# accessor examples I’ve seen are pretty basic. If there’s a lot of accessor logic, do people tend to put those in separate methods and call those from the get/set definitions?
Curious as to what problems you see with “reflecting over objects” and the traditional get/set method approach. Does it just get too cluttered or is there something else?