In the current implementation DateTime is not a value object, but its
internal state can be modified at any given time. This can lead to very
obscure bugs when references to DateTime objects are shared or objects are
passed through a chain of methods/functions that modify it. Using DateTime
is not side-effect free.
I propose to allow to work with DateTime objects that are marked as
immutable optionally. This means that all methods add, sub, modify,
setDate, setTime, setISODate, setTimestamp and setTimezone will return a
NEW instance of Datetime instead of reusing the old one.
I also talked to Derick about this and he agrees that immutable DateTime
objects would be desirable. I have talked to many other people who agreed
that the current behavior is weird.
My proposed syntax would be:
$immutableDateTime = date_create("2010-12-05", null, true);
$immutableDateTime = new DateTime("2010-12-05", null, true);
$immutableDateTime = DateTime::createFromFormat("%Y-%m-%d", "2010-12-05",
null, true);
Where the third and fourth variable respectivly are boolean flags
$immutable yes or no. Also the DatePeriod iterator would be modified. If an
immutable start date is passed the date iterator would also create
immutable dates.
I have attached a patch that implements this functionality and a little
test-script that shows how it would work. This is the first complex bit of
C-code that I did so please bear with any mistakes I made ;-) Also i havent
followed the coding standards.
Any feedback is greatly appreciated. My C-Skills arent that good so i am
not finished with an additional solution allowing to call a method
"setImmutable()" on any datetime instance, marking it as immutable.
Obviously this would only mark the instance as immutable, allowing to
accept a flag to reset it to be mutable would be counter-productive.
The only drawback I see to this patch is the additional int variable on
the _php_date_obj and _php_date_period structs. I am not sure if they
affect memory in such a way that this solution isn't viable.
If this topic needs more discussion or pro/cons I am willing to open up an
RFC for a more detailed discussion.
I'd love to have a Value Object version of DateTime, as its current behavior
is quite annoying.
However, making it a toggle on the existing class does not make sense to me.
A function or method that gets called with a DateTime object then doesn't know
if it is safe to modify or not, and if the return value from a method will be
a new object or not. That means I need to also pass around a flag saying
which it is, or else have a method to ask DateTime which mode it's in and then
fork my own code to account for both cases. That's ugly. :-)
I think it would be better to have a new DateTimeValue class that subclasses
off DateTime (or even better, introduce a new interface that they both
implement) that is essentially identical but is immutable. That would make it
much easier to code against.
--Larry Garfield
In the current implementation DateTime is not a value object, but its
internal state can be modified at any given time. This can lead to very
obscure bugs when references to DateTime objects are shared or objects are
passed through a chain of methods/functions that modify it. Using DateTime
is not side-effect free.I propose to allow to work with DateTime objects that are marked as
immutable optionally. This means that all methods add, sub, modify,
setDate, setTime, setISODate, setTimestamp and setTimezone will return a
NEW instance of Datetime instead of reusing the old one.I also talked to Derick about this and he agrees that immutable DateTime
objects would be desirable. I have talked to many other people who agreed
that the current behavior is weird.My proposed syntax would be:
$immutableDateTime = date_create("2010-12-05", null, true);
$immutableDateTime = new DateTime("2010-12-05", null, true);
$immutableDateTime = DateTime::createFromFormat("%Y-%m-%d", "2010-12-05",
null, true);Where the third and fourth variable respectivly are boolean flags
$immutable yes or no. Also the DatePeriod iterator would be modified. If an
immutable start date is passed the date iterator would also create
immutable dates.I have attached a patch that implements this functionality and a little
test-script that shows how it would work. This is the first complex bit of
C-code that I did so please bear with any mistakes I made ;-) Also i havent
followed the coding standards.Any feedback is greatly appreciated. My C-Skills arent that good so i am
not finished with an additional solution allowing to call a method
"setImmutable()" on any datetime instance, marking it as immutable.
Obviously this would only mark the instance as immutable, allowing to
accept a flag to reset it to be mutable would be counter-productive.The only drawback I see to this patch is the additional int variable on
the _php_date_obj and _php_date_period structs. I am not sure if they
affect memory in such a way that this solution isn't viable.If this topic needs more discussion or pro/cons I am willing to open up an
RFC for a more detailed discussion.
Hey Larry,
You don't need to know if the instance is immutable or not, since the current DateTime instances also return themselves for method chaining. So any code that looks like:
$d = $d->modify("+1 hour");
would work no matter mutable/immutable. This is still a bit strange though. But still any DateTimeValue would extend DateTime. So when you typehint
for a "DateTime", you still don't know if you get the one or the other and you would have to resort to the previous code example anyways.
What would be possible though to detect if the return value of all the modify methods is used. If it is not and the DateTime is immutable we could trigger a notice or throw an exception.
greetings,
Benjamin
On Sun, 5 Dec 2010 02:55:53 -0600
Larry Garfield larry@garfieldtech.com wrote:
I'd love to have a Value Object version of DateTime, as its current behavior
is quite annoying.However, making it a toggle on the existing class does not make sense to me.
A function or method that gets called with a DateTime object then doesn't know
if it is safe to modify or not, and if the return value from a method will be
a new object or not. That means I need to also pass around a flag saying
which it is, or else have a method to ask DateTime which mode it's in and then
fork my own code to account for both cases. That's ugly. :-)I think it would be better to have a new DateTimeValue class that subclasses
off DateTime (or even better, introduce a new interface that they both
implement) that is essentially identical but is immutable. That would make it
much easier to code against.--Larry Garfield
In the current implementation DateTime is not a value object, but its
internal state can be modified at any given time. This can lead to very
obscure bugs when references to DateTime objects are shared or objects are
passed through a chain of methods/functions that modify it. Using DateTime
is not side-effect free.I propose to allow to work with DateTime objects that are marked as
immutable optionally. This means that all methods add, sub, modify,
setDate, setTime, setISODate, setTimestamp and setTimezone will return a
NEW instance of Datetime instead of reusing the old one.I also talked to Derick about this and he agrees that immutable DateTime
objects would be desirable. I have talked to many other people who agreed
that the current behavior is weird.My proposed syntax would be:
$immutableDateTime = date_create("2010-12-05", null, true);
$immutableDateTime = new DateTime("2010-12-05", null, true);
$immutableDateTime = DateTime::createFromFormat("%Y-%m-%d", "2010-12-05",
null, true);Where the third and fourth variable respectivly are boolean flags
$immutable yes or no. Also the DatePeriod iterator would be modified. If an
immutable start date is passed the date iterator would also create
immutable dates.I have attached a patch that implements this functionality and a little
test-script that shows how it would work. This is the first complex bit of
C-code that I did so please bear with any mistakes I made ;-) Also i havent
followed the coding standards.Any feedback is greatly appreciated. My C-Skills arent that good so i am
not finished with an additional solution allowing to call a method
"setImmutable()" on any datetime instance, marking it as immutable.
Obviously this would only mark the instance as immutable, allowing to
accept a flag to reset it to be mutable would be counter-productive.The only drawback I see to this patch is the additional int variable on
the _php_date_obj and _php_date_period structs. I am not sure if they
affect memory in such a way that this solution isn't viable.If this topic needs more discussion or pro/cons I am willing to open up an
RFC for a more detailed discussion.
You don't need to know if the instance is immutable or not, since the current DateTime instances also return themselves for method chaining. So any code that looks like:
$d = $d->modify("+1 hour");
would work no matter mutable/immutable. This is still a bit strange though. But still any DateTimeValue would extend DateTime. So when you typehint
for a "DateTime", you still don't know if you get the one or the other and you would have to resort to the previous code example anyways.
I do need to know if the instance is immutable. I have plenty of
class methods that modify the DateTime instance and some don't return
the DateTime instance back. If you want to make sure the object is
immutable, you typehint for a DateTimeValue object. From an OO
perspective, it makes much more sense to extend the class and add this
functionality than to change the inner workings of the existing class.
--
Herman Radtke
hermanradtke@gmail.com | http://hermanradtke.com
On Sun, 5 Dec 2010 08:18:46 -0800
Herman Radtke hermanradtke@gmail.com wrote:
You don't need to know if the instance is immutable or not, since the current DateTime instances also return themselves for method chaining. So any code that looks like:
$d = $d->modify("+1 hour");
would work no matter mutable/immutable. This is still a bit strange though. But still any DateTimeValue would extend DateTime. So when you typehint
for a "DateTime", you still don't know if you get the one or the other and you would have to resort to the previous code example anyways.I do need to know if the instance is immutable. I have plenty of
class methods that modify the DateTime instance and some don't return
the DateTime instance back. If you want to make sure the object is
immutable, you typehint for a DateTimeValue object. From an OO
perspective, it makes much more sense to extend the class and add this
functionality than to change the inner workings of the existing class.--
Herman Radtke
hermanradtke@gmail.com | http://hermanradtke.com--
Hmm yeah you and Larry maybe right on this.
I want to take some discussion over from #pecl-dev also i had with Pierre and others. I am not certain if i carry their argument over correctly, but Immutable Objects are a pain for the garbage collector (many instances) and it would be much more efficient if PHP had a concept of static or read-only classes that don't change after the constructor has been called. This way they could be handled much better by PHPs internal garbage collection mechanisms.
So currently preferred over my patch are two solutions:
- Just create a DateTimeValue object that is immutable, not optimizing PHP to handle it with efficient garbage collection.
- One step further, add a "static class DateTimeValue" like syntax that creates an immutable class.
Any ideas?
Benjamin
So currently preferred over my patch are two solutions:
- Just create a DateTimeValue object that is immutable, not optimizing PHP to handle it with efficient garbage collection.
- One step further, add a "static class DateTimeValue" like syntax that creates an immutable class.
Any ideas?
I'd prefer BC breakage. DateTimeValue just doesn't have a good ring to
it. Besides, having two both a mutable and an immutable version at the
same time is bound to cause confusion.
--
troels
So currently preferred over my patch are two solutions:
- Just create a DateTimeValue object that is immutable, not optimizing PHP to handle it with efficient garbage collection.
- One step further, add a "static class DateTimeValue" like syntax that creates an immutable class.
Any ideas?
I'd prefer BC breakage. DateTimeValue just doesn't have a good ring to
it. Besides, having two both a mutable and an immutable version at the
same time is bound to cause confusion.
It is not only about date but about create value type. There are
plenty of good usages for such thing.
Cheers,
Pierre
@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
- Just create a DateTimeValue object that is immutable, not
optimizing PHP to handle it with efficient garbage collection.- One step further, add a "static class DateTimeValue" like syntax
that creates an immutable class.Any ideas?
Some ideas here:
http://www.javalobby.org/articles/immutable/index.jsp
A pattern I've been using is ~
interface Immutable {}
class DateTime_Immutable extends DateTime implements Immutable {
// throw exceptions if attempt to modify...
}
// Get immutable objects...
Objects::getImmutable('Datetime', '2009-01-09'); // returns
(Immutable) new DateTime_Immutable('2009-01-09')
Objects::getImmutable('Datetime', $param1, $param2, ...); // returns
(Immutable) new DateTime_Immutable($param1, $param2, ...)
Hi!
I propose to allow to work with DateTime objects that are marked as
immutable optionally. This means that all methods add, sub, modify,
I think it's a bad idea, which would instantly break all the code that
assumes different semantics. Yes, I noticed the word optional, however,
the code accepting DateTime assumes some semantics, and had no means to
reject object with different semantics, and combining two semantics in
one class is a bad idea.
On the other hand, you can create DateTimeValue object, which can do
what you want. I'd imagine it'd be quite easy to do in user space too.
If enough people feel they need it then it can be brought into the
extension too.
I also talked to Derick about this and he agrees that immutable DateTime
objects would be desirable. I have talked to many other people who agreed
that the current behavior is weird.
I've talked to many people who agree it isn't ;)
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Sun, 05 Dec 2010 10:29:29 -0800
Stas Malyshev smalyshev@sugarcrm.com wrote:
Hi!
I propose to allow to work with DateTime objects that are marked as
immutable optionally. This means that all methods add, sub, modify,I think it's a bad idea, which would instantly break all the code that
assumes different semantics. Yes, I noticed the word optional, however,
the code accepting DateTime assumes some semantics, and had no means to
reject object with different semantics, and combining two semantics in
one class is a bad idea.On the other hand, you can create DateTimeValue object, which can do
what you want. I'd imagine it'd be quite easy to do in user space too.
If enough people feel they need it then it can be brought into the
extension too.
Hey Stas,
i actually implemented this in userland, but its rather ugly:
http://whitewashing.de/blog/124
I'd like to see it in the extension, the patch was just the only thing i could do with my limited C skills ;-) It is better to start the discussion with something visible rather than just speaking about hypothetical changes :-)
I also talked to Derick about this and he agrees that immutable DateTime
objects would be desirable. I have talked to many other people who agreed
that the current behavior is weird.I've talked to many people who agree it isn't ;)
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi!
i actually implemented this in userland, but its rather ugly:
It is ugly because you try to have one class with two semantics. It is a
mistake. If you remove this ambiguity it actually would be quite small.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227