Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've always been a fan because if a property turns from a simple value to a more complex interaction that might involve DB operations or other side effects then if a getter is in place you can modify the logic without needing to update widespread code.


If you are replacing a performant property with a slow network call, you are being negligent if you aren't reviewing all the callers to make sure that is okay.


In a typical ORM when you do say $Model->DateTime = 1732046457; the __set is actually checking the value and seeing oh it's an integer. Treat this as a unix timestamp. But when you run save() the query is actually converting that to a Y-m-d H:i:s (for MySQL/MariaDB). This doesn't actually happen until you run save() when it makes the query and runs the network call. Most of that time it's actually storing everything in memory.

But you might want to support string date times and the PHP object DateTime as well. So a typical well designed ORM converts multiple PHP types into a SQL string for saving. That's what the historical __set and __get are all about. This is called "mapping" by most ORMs and a very well designed modern one like Doctrine will actually have mappings for different SQL storage engines available.

Obviously it also has to handle the reverse.


That is a fine argument for setters, but I still don't see the connection between that, and the desire to disguise properties as setter methods.


Some light weight ORMs do not require you to define all the properties ahead of time. They pull the field names from the table and generate the model record on the fly for you. This generally lets you prototype really fast. Laravel's Eloquent is known to do this. It's also useful for derived SQL fields when you use custom queries or join from other tables. Also kinda fun to do it for properties backed by a method. As in $record->isDirty will run isDirty() under the hood for you. All these things can be documented with PHPDoc and static analyzers handle it just fine.


Is it possible to dynamically define methods in PHP?


Yes.


A method is supposed to be an action and a property is supposed to be data. So I don't see the desire to disguise setting data as a "setting method" rather than using the syntax of assignment.


> A method is supposed to be an action and a property is supposed to be data.

I agree! That's why it's wild to allow a setter to do literally anything.

You aren't just setting a property, there is a conversion happening under the hood.

And the reason I hate it is that code that appears to be infallible, isn't. It can have arbitrary side effects, raise exceptions, have unbounded runtime, etc.


There are many ways to make code misleading. You can write a method called plus and have it do multiplication. You can write a method that sounds safe but looks dangerous. Every language relies on programmers exercising judgement when writing the program.

In a lot of contexts you have something that requires a bit of code but really does behave like a property access, where it's more misleading to make it look like a method call than to make it look like a data access. E.g. using an ORM hooked up to SQLite embedded in the program. Or accessing properties of objects that you're using an EAV system or array-of-structs layout to store efficiently in memory. Or a wrapped datastructure from a C library that you're binding.

Of course if you make something look like a property that doesn't behave like a property then that's confusing. Programmers have to exercise judgement and only make things look like properties when they behave like properties. But that's not really any different from needing to name methods/objects/operators in ways that reflect what they do.


It's abstraction. Your not supposed to care that the setter is doing anything. The class is providing you an interface -- what it does with that interface is not your concern. I hate to quote Alan Kay but all objects should just respond to messages. Whether that message corresponds to a method or a property is pure semantics.

I sometimes use getters and setters to provide backwards compatibility. What was just maybe a simple data field a decade ago doesn't even exist anymore because some major system has changed and we aren't rewriting every single application when we can provide the values that they need easily enough.

If you know that setters exist then you already know that the code can do more. It's not a huge mental leap from property setting to method calls. You should never assume anything is infallible. I don't think classes should even expose raw fields.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: