{"id":371,"date":"2007-07-13T10:09:46","date_gmt":"2007-07-13T17:09:46","guid":{"rendered":"http:\/\/www.red-sweater.com\/blog\/371\/suicidal-code"},"modified":"2007-07-15T14:00:19","modified_gmt":"2007-07-15T21:00:19","slug":"suicidal-code","status":"publish","type":"post","link":"https:\/\/redsweater.com\/blog\/371\/suicidal-code","title":{"rendered":"Suicidal Code"},"content":{"rendered":"<p>Some code is not meant to live forever. In particular, during development phases of projects, it can be very reassuring to know that a particular release of an application will have a short life-cycle, because you&#8217;ll be (relatively) assured that users aren&#8217;t accidentally running crufty old (development!) versions of the app.<\/p>\n<p>\nThe basic means of accomplishing this is to put a date check in your code that determines if a certain time has come and, if it has, refuses to run any longer. Anecdotally, I can tell you that <em>lots<\/em> of developers do something like this. But I can also tell you that lots of developers do it the error-prone, labor-intensive way. I did too, until I picked up a great tip from <a href=\"http:\/\/roobasoft.com\/blog\/\">Brian Cooke<\/a> a while back, that completely automates the process.\n<\/p>\n<p>\nThe laborious and error-prone method involves manually typing into your code a particular date in the future, and using that date as the test for whether or not to keep running. Brian&#8217;s brilliant observation was that the future date is almost always some number of days from &#8220;now,&#8221; where &#8220;now&#8221; is the date the code is being compiled. Using a gcc <a href=\"http:\/\/developer.apple.com\/documentation\/DeveloperTools\/gcc-3.3\/cpp\/Standard-Predefined-Macros.html\">predefined macro<\/a>, __DATE__, the code can know for itself when it was compiled, and build in an expiration date based on that value.\n<\/p>\n<p><pre style=\"font-size:1.1em;\">\n\/\/ Two-week expiration\n&#35;define EXPIREAFTERDAYS 14\n\n&#35;if EXPIREAFTERDAYS\n   \/\/ Idea from Brian Cooke.\n   NSString* nowString = \n      [NSString stringWithUTF8String:__DATE__];\n   NSCalendarDate* nowDate = \n      [NSCalendarDate dateWithNaturalLanguageString:nowString];\n   NSCalendarDate* expireDate =\n      [nowDate addTimeInterval:(60*60*24* EXPIREAFTERDAYS)];\n\n   if ([expireDate earlierDate:[NSDate date]] == expireDate)\n   {\n      \/\/ Run an alert or whatever\n\n      \/\/ Quit!\n      [NSApp terminate:self];\n   }\n&#35;endif\n<\/pre>\n<\/p>\n<p>\nBy putting code like this in all of your projects, you have at your disposal a simple, error-proof way of releasing a build that will stop working N days from now. When you&#8217;re ready to release a non-suicidal version, just change the EXPIREAFTERDAYS preprocessor macro to 0. Nifty, eh?\n<\/p>\n<p>\nPS: Thanks to <a href=\"http:\/\/outerlevel.com\/blog\/\">Jon Trainer<\/a> for inspiring this entry by thinking the idea was cool when I told him about it.  <\/p>\n<p>\n<strong>Update:<\/strong> <a href=\"http:\/\/www.unsanity.org\/\">Rosyna<\/a> points out that dateWithNaturalLanguageString might be a dangerous method to use here, because it will implicitly use a different locale to parse the string, depending on the user&#8217;s language settings. Furthermore, the documentation for that method strongly discourages its use. Ironically though, the reason its use is discouraged, because it&#8217;s got a limited vocabulary and favors English, is probably just about right for parsing the date from GCC.\n<\/p>\n<p>The GCC documentation describes the contents of __DATE__ as &#8220;eleven characters and looks like &#8216;Feb 12 1996&#8217;.&#8221; I&#8217;m not really sure how many locales this will or will not work correctly for, so I&#8217;m thinking the safe bet is to use a more explicit string -> date conversion format. I&#8217;m busy with something else right now but if anybody has a good capsule solution for this, please share it in the comments! Rosyna suggests offline that perhaps some POSIX date string formatter will do the trick.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some code is not meant to live forever. In particular, during development phases of projects, it can be very reassuring to know that a particular release of an application will have a short life-cycle, because you&#8217;ll be (relatively) assured that users aren&#8217;t accidentally running crufty old (development!) versions of the app. The basic means of [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,15],"tags":[],"class_list":["post-371","post","type-post","status-publish","format-standard","hentry","category-cocoa","category-programming"],"_links":{"self":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/371","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/comments?post=371"}],"version-history":[{"count":0,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/371\/revisions"}],"wp:attachment":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/media?parent=371"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/categories?post=371"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/tags?post=371"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}