Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:50845 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 27705 invoked from network); 5 Dec 2010 08:55:10 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 5 Dec 2010 08:55:10 -0000 Authentication-Results: pb1.pair.com smtp.mail=larry@garfieldtech.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=larry@garfieldtech.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain garfieldtech.com from 76.96.30.56 cause and error) X-PHP-List-Original-Sender: larry@garfieldtech.com X-Host-Fingerprint: 76.96.30.56 qmta06.emeryville.ca.mail.comcast.net Received: from [76.96.30.56] ([76.96.30.56:48435] helo=qmta06.emeryville.ca.mail.comcast.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 59/80-19822-C635BFC4 for ; Sun, 05 Dec 2010 03:55:09 -0500 Received: from omta09.emeryville.ca.mail.comcast.net ([76.96.30.20]) by qmta06.emeryville.ca.mail.comcast.net with comcast id fLtt1f0020S2fkCA6Lv6fP; Sun, 05 Dec 2010 08:55:06 +0000 Received: from earth.ufp ([98.220.236.211]) by omta09.emeryville.ca.mail.comcast.net with comcast id fLv31f00H4aLjBW8VLv4BY; Sun, 05 Dec 2010 08:55:04 +0000 Received: from localhost (localhost [127.0.0.1]) by earth.ufp (Postfix) with ESMTP id 6675FD7A51 for ; Sun, 5 Dec 2010 02:55:03 -0600 (CST) Received: from earth.ufp ([127.0.0.1]) by localhost (earth.ufp [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6-o1N+4nHzDm for ; Sun, 5 Dec 2010 02:55:03 -0600 (CST) Received: from linux-nkec.site (unknown [192.168.42.1]) by earth.ufp (Postfix) with ESMTPSA id 4D969D7A50 for ; Sun, 5 Dec 2010 02:55:03 -0600 (CST) To: internals@lists.php.net Date: Sun, 5 Dec 2010 02:55:53 -0600 User-Agent: KMail/1.13.5 (Linux/2.6.34.7-0.5-desktop; KDE/4.4.4; x86_64; ; ) References: In-Reply-To: MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-15" Content-Transfer-Encoding: 7bit Message-ID: <201012050255.54059.larry@garfieldtech.com> Subject: Re: [PHP-DEV] Patch: Marking DateTime Instances Immutable From: larry@garfieldtech.com (Larry Garfield) 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 On Saturday, December 04, 2010 6:11:37 pm Benjamin Eberlei wrote: > 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.