<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nicollet.Net &#187; Bugs</title>
	<atom:link href="http://www.nicollet.net/toroidal/bugs/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nicollet.net</link>
	<description>Everyone Loves Me</description>
	<lastBuildDate>Mon, 23 Jan 2012 16:55:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>On Escaping HTML</title>
		<link>http://www.nicollet.net/2011/10/on-escaping-html/</link>
		<comments>http://www.nicollet.net/2011/10/on-escaping-html/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 08:03:53 +0000</pubDate>
		<dc:creator>Victor Nicollet</dc:creator>
				<category><![CDATA[Dynamic]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.nicollet.net/?p=2572</guid>
		<description><![CDATA[A common issue with web software is cross-site scripting attacks — the ability for a third party to inject HTML elements into pages displayed to other users, using scripts contained in those elements to capture user cookies or perform operations on their behalf. The technical challenge in solving this is that whenever data is being [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-2573" title="dome" src="http://www.nicollet.net/wp-content/uploads/2011/10/dome.png" alt="" width="675" height="100" /></p>
<p>A common issue with web software is cross-site scripting attacks — the ability for a third party to inject HTML elements into pages displayed to other users, using scripts contained in those elements to capture user cookies or perform operations on their behalf.</p>
<p>The technical challenge in solving this is that whenever data is being output through a HTML page, it should be escaped — any special HTML characters should be turned into their non-special versions in order to be displayed verbatim. This is an ongoing effort: each new page and each new variable on a page involve the same amount of effort to be done.</p>
<p>Of course, the solution would be to decide that <strong>escaping string output should be a default behavior that must be explicitly overriden</strong>. This does create issues where HTML is escaped when it should not have been, but:</p>
<ul>
<li>These issues cannot be used to perform attacks.</li>
<li>They are usually easier to reproduce and consequently to solve.</li>
<li>HTML <em>usually </em>comes from template files, which can be handled with a different default.</li>
</ul>
<p>Indeed, I can guarantee that my software has zero vulnerabilities related to escaped HTML, because I have built into the type system the fact that HTML always comes from templates, and the method that injects variables into templates escapes them. If I try to use a string as if it were HTML, I get a compiler error.</p>
<p>Even without a type system, one can guarantee that the system would rather break at runtime than allow an injection, using the exact same design, with incompatible data structures for templates and strings that blow up when a string is used as a template:</p>
<pre style="color: #000020; padding-left: 30px;"><code><span style="color: #200080; font-weight: bold;">class</span><span style="color: #000000;"> FilledTemplate </span><span style="color: #406080;">{</span>
<span style="color: #000000;">  </span><span style="color: #200080; font-weight: bold;">function</span><span style="color: #000000;"> </span><span style="color: #400000;">__construct</span><span style="color: #308080;">(</span><span style="color: #007d45;">$html</span><span style="color: #308080;">)</span><span style="color: #000000;"> </span><span style="color: #406080;">{</span>
<span style="color: #000000;">    </span><span style="color: #007d45;">$</span><span style="color: #200080; font-weight: bold;">this</span><span style="color: #308080;">-&gt;</span><span style="color: #007d45;">_html</span><span style="color: #000000;"> </span><span style="color: #308080;">=</span><span style="color: #000000;"> </span><span style="color: #007d45;">$html</span><span style="color: #406080;">;</span>
<span style="color: #000000;">  </span><span style="color: #406080;">}</span>
<span style="color: #000000;">  </span><span style="color: #200080; font-weight: bold;">function</span><span style="color: #000000;"> html</span><span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #000000;"> </span><span style="color: #406080;">{</span>
<span style="color: #000000;">    </span><span style="color: #200080; font-weight: bold;">return</span><span style="color: #000000;"> </span><span style="color: #007d45;">$</span><span style="color: #200080; font-weight: bold;">this</span><span style="color: #308080;">-&gt;</span><span style="color: #007d45;">_html</span><span style="color: #406080;">;</span>
<span style="color: #000000;">  </span><span style="color: #406080;">}</span>
<span style="color: #406080;">}</span>

<span style="color: #200080; font-weight: bold;">class</span><span style="color: #000000;"> Template </span><span style="color: #406080;">{</span>
<span style="color: #000000;">  </span><span style="color: #200080; font-weight: bold;">function</span><span style="color: #000000;"> </span><span style="color: #400000;">__construct</span><span style="color: #308080;">(</span><span style="color: #007d45;">$file</span><span style="color: #308080;">)</span><span style="color: #000000;"> </span><span style="color: #406080;">{</span>
<span style="color: #000000;">    </span><span style="color: #007d45;">$</span><span style="color: #200080; font-weight: bold;">this</span><span style="color: #308080;">-&gt;</span><span style="color: #007d45;">_template</span><span style="color: #000000;"> </span><span style="color: #308080;">=</span><span style="color: #000000;"> </span><span style="color: #400000;">file_get_contents</span><span style="color: #308080;">(</span><span style="color: #007d45;">$file</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #000000;">  </span><span style="color: #406080;">}</span>
<span style="color: #000000;">  </span><span style="color: #200080; font-weight: bold;">function</span><span style="color: #000000;"> fill</span><span style="color: #308080;">(</span><span style="color: #007d45;">$values</span><span style="color: #308080;">)</span><span style="color: #000000;"> </span><span style="color: #406080;">{</span>
<span style="color: #000000;">    </span><span style="color: #007d45;">$replace</span><span style="color: #000000;"> </span><span style="color: #308080;">=</span><span style="color: #000000;"> </span><span style="color: #200080; font-weight: bold;">array</span><span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #000000;">    </span><span style="color: #007d45;">$with</span><span style="color: #000000;">    </span><span style="color: #308080;">=</span><span style="color: #000000;"> </span><span style="color: #200080; font-weight: bold;">array</span><span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #000000;">    </span><span style="color: #200080; font-weight: bold;">foreach</span><span style="color: #000000;"> </span><span style="color: #308080;">(</span><span style="color: #007d45;">$values</span><span style="color: #000000;"> </span><span style="color: #200080; font-weight: bold;">as</span><span style="color: #000000;"> </span><span style="color: #007d45;">$key</span><span style="color: #000000;"> </span><span style="color: #308080;">=</span><span style="color: #308080;">&gt;</span><span style="color: #000000;"> </span><span style="color: #007d45;">$value</span><span style="color: #308080;">)</span><span style="color: #000000;"> </span><span style="color: #406080;">{</span>
<span style="color: #000000;">      </span><span style="color: #007d45;">$replace</span><span style="color: #308080;">[</span><span style="color: #308080;">]</span><span style="color: #000000;"> </span><span style="color: #308080;">=</span><span style="color: #000000;"> </span><span style="color: #1060b6;">'{'</span><span style="color: #308080;">.</span><span style="color: #007d45;">$key</span><span style="color: #308080;">.</span><span style="color: #1060b6;">'}'</span><span style="color: #406080;">;</span>
<span style="color: #000000;">      </span><span style="color: #200080; font-weight: bold;">if</span><span style="color: #000000;"> </span><span style="color: #308080;">(</span><span style="color: #007d45;">$value</span><span style="color: #000000;"> </span><span style="color: #200080; font-weight: bold;">instanceof</span><span style="color: #000000;"> FilledTemplate</span><span style="color: #308080;">)</span><span style="color: #000000;"> </span>
<span style="color: #000000;">        </span><span style="color: #007d45;">$with</span><span style="color: #308080;">[</span><span style="color: #308080;">]</span><span style="color: #000000;"> </span><span style="color: #308080;">=</span><span style="color: #000000;"> </span><span style="color: #007d45;">$value</span><span style="color: #308080;">-</span><span style="color: #308080;">&gt;</span><span style="color: #000000;">html</span><span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #000000;">      </span><span style="color: #200080; font-weight: bold;">else</span><span style="color: #000000;"> </span>
<span style="color: #000000;">        </span><span style="color: #007d45;">$with</span><span style="color: #308080;">[</span><span style="color: #308080;">]</span><span style="color: #000000;"> </span><span style="color: #308080;">=</span><span style="color: #000000;"> </span><span style="color: #400000;">htmlspecialchars</span><span style="color: #308080;">(</span><span style="color: #007d45;">$value</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #000000;">    </span><span style="color: #406080;">}</span>
<span style="color: #000000;">    </span><span style="color: #200080; font-weight: bold;">return</span><span style="color: #000000;"> </span><span style="color: #200080; font-weight: bold;">new</span><span style="color: #000000;"> FilledTemplate</span><span style="color: #308080;">(</span>
<span style="color: #000000;">      </span><span style="color: #400000;">str_replace</span><span style="color: #308080;">(</span><span style="color: #007d45;">$replace</span><span style="color: #308080;">,</span><span style="color: #007d45;">$with</span><span style="color: #308080;">,</span><span style="color: #007d45;">$</span><span style="color: #200080; font-weight: bold;">this</span><span style="color: #308080;">-&gt;</span><span style="color: #007d45;">_template</span><span style="color: #308080;">)</span>
<span style="color: #000000;">    </span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #000000;">  </span><span style="color: #406080;">}</span><span style="color: #000000;"> </span>
<span style="color: #406080;">}</span></code></pre>
<p>Obviously, many languages and frameworks use non-escaped string output as the default behavior. This, in my opinion, is pure, broken insanity — I can certainly see that designing a safe way of constructing HTML is harder than just following the «HTML is strings, just use string functions» approach and telling the programmer to «always escape your variables, kid» but I still find it quite irresponsible for self-proclaimed Web Languages to rely on such a primitive and dangerous paradigm. The stupid kind of irresponsible. Yes, PHP, I&#8217;m looking at you.</p>
<p><small>Article Image © Freedom II Andres — <a href="http://www.flickr.com/photos/freedomiiphotography/6203083791/">Flickr</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.nicollet.net/2011/10/on-escaping-html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Toppling the Stacks</title>
		<link>http://www.nicollet.net/2011/10/toppling-the-stacks/</link>
		<comments>http://www.nicollet.net/2011/10/toppling-the-stacks/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 20:57:40 +0000</pubDate>
		<dc:creator>Victor Nicollet</dc:creator>
				<category><![CDATA[Strategy]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://www.nicollet.net/?p=2553</guid>
		<description><![CDATA[Everyone agrees that CSS is an overly verbose stream of boiling pain, but not everyone agrees on how it should be solved. Sass is one such solution — a language extension that supports standard CSS code natively, but provides several tricks that make the maintenance of stylesheets easier, not least of which being the ability [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-2554" title="buoy" src="http://www.nicollet.net/wp-content/uploads/2011/10/buoy.png" alt="" width="675" height="100" /></p>
<p>Everyone agrees that CSS is an overly verbose stream of boiling pain, but not everyone agrees on how it should be solved. <a href="http://sass-lang.com/" target="_blank">Sass</a> is one such solution — a language extension that supports standard CSS code natively, but provides several tricks that make the maintenance of stylesheets easier, not least of which being the ability to nest selectors:</p>
<pre style="padding-left: 30px;">.profile {
  color: black;
  .name { font-weight: bold; }
}</pre>
<p>A compiler turns the above into standard CSS:</p>
<pre style="padding-left: 30px;">.profile { color: black; }
.profile .name { font-weight: bold; }</pre>
<p>Typical usage of Sass is to write the former by hand, run the compiler, and move the resulting CSS file to wherever the browser can see it.</p>
<p>I successfully set up Sass on my development machine and uploaded the generated CSS to source control. This worked correctly for a few weeks.</p>
<p>Then came the time when I had to set up Sass on the deployment server, because not everyone on the team had the time or the operating system to set up Sass on their computer. It burst into flames almost immediately with an arcane stack trace:</p>
<pre style="padding-left: 30px;">.../rubygems/defaults.rb:40:in `exist?': Insecure operation - exist? (SecurityError)
    from .../rubygems/defaults.rb:40:in `default_path'
    from .../rubygems.rb:752:in `path'
    from .../rubygems/source_index.rb:59:in `installed_spec_directories'
    from .../rubygems.rb:1051:in `source_index'
    from .../rubygems.rb:243:in `activate_dep'
    from .../rubygems.rb:236:in `activate'
    from .../rubygems.rb:1307:in `gem'
    from /usr/local/bin/sass:18</pre>
<p>I posted an issue to the GitHub issues tracker for Sass. <a href="https://github.com/nex3/sass/issues/184">The answer was underwhelming</a> :</p>
<blockquote><p>This looks like a Rubygems issue, not a Sass issue.</p></blockquote>
<p>And the issue was closed.</p>
<p>Let me set things straight here: when a Sass user cannot use Sass, <strong>it is a Sass issue</strong>. Yes, the underlying <em>technical cause</em> of the issue is probably somewhere inside that «Rubygems» thing I sincerely know nothing about, or maybe it lies in the Debian package for it, or maybe I&#8217;m just setting up my environment variables badly and just need a clean diagnosis to fix that up, but <strong>Sass is not working</strong>. Even if you have absolutely no personal responsibility for the issue, pointers such as «ask about this on channel X or mailing list Y» are most welcome.</p>
<p>Now, I don&#8217;t expect <a href="https://github.com/nex3" target="_blank">nex3</a> to provide me with free support. This is an open source project, and there&#8217;s nothing unusual or wrong with having no technical support on open source projects. In fact, given the size of the technology stack sitting under Sass, this was probably the best thing to do in terms of project strategy — <em>only cater to users who can get the underlying stack working on their own</em>.</p>
<p>This is not a matter of fairness or ethics, but one of incentives. I have no need to keep debugging Sass &mdash; the path of least resistance is precisely to replace Sass with an equivalent working tool. Rewriting a handful of Sass rules over to <a href="http://lesscss.org/">Less CSS</a> is easier for me than tracking down bugs in the Debian packaging of «Rubygems». And the deployment server runs Less without a hitch.</p>
<p>I shudder to think what would have happened had I locked myself into more esoteric Sass language features.</p>
<p><small>Article image &copy; yimmy149 &mdash; <a href="http://www.flickr.com/photos/yimmy149/418164438/">Flickr</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.nicollet.net/2011/10/toppling-the-stacks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>jQuery Datepicker &#8211; the Instance Data bug</title>
		<link>http://www.nicollet.net/2011/09/jquery-datepicker-the-instance-data-bug/</link>
		<comments>http://www.nicollet.net/2011/09/jquery-datepicker-the-instance-data-bug/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 10:49:44 +0000</pubDate>
		<dc:creator>Victor Nicollet</dc:creator>
				<category><![CDATA[Dynamic]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.nicollet.net/?p=2538</guid>
		<description><![CDATA[The jQuery UI datepicker does strange things with the DOM, which causes undocumented brittleness. For instance, consider the following operations on a page that contains a single input element: $('input').datepicker().attr('id','the-input'); This will cause no error, and clicking on the input will correctly summon the date picking dialog, but clicking on a date in that dialog [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-2539" title="error" src="http://www.nicollet.net/wp-content/uploads/2011/09/error.png" alt="" width="675" height="100" />The jQuery UI datepicker does <em>strange</em> things with the DOM, which causes undocumented brittleness. For instance, consider the following operations on a page that contains a single input element:</p>
<pre style="padding-left: 30px;">$('input').datepicker().attr('id','the-input');</pre>
<p>This will cause no error, and clicking on the input will correctly summon the date picking dialog, but clicking on a date in that dialog will fail with the following error:</p>
<pre style="padding-left: 30px;">missing instance data for this datepicker</pre>
<p>The diagnosis is quite simple: the jQuery UI datepicker stores additional &#8220;instance data&#8221; based on the id attribute of the element, so changing the id attribute manually causes that instance data to be lost. This unexpected brittleness forced me to spend some time hacking my code so that the identifier is attributed <em>before</em> the datepicker is enabled, but at least this solved the problem.</p>
<p>Two related problems would be:</p>
<ul>
<li>If you have several input elements with the same identifier, and apply the datepicker on the second element, the search-by-id will return the first element and cause the same error as above.</li>
<li>If you apply the <code>hasDatepicker</code> CSS class on an element, and then apply the datepicker plugin, it will assume that the instance data has already been initialized, and will fail.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.nicollet.net/2011/09/jquery-datepicker-the-instance-data-bug/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Avoid Side Effects</title>
		<link>http://www.nicollet.net/2011/02/avoid-side-effects/</link>
		<comments>http://www.nicollet.net/2011/02/avoid-side-effects/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 09:16:01 +0000</pubDate>
		<dc:creator>Victor Nicollet</dc:creator>
				<category><![CDATA[Functional]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[Language Design]]></category>
		<category><![CDATA[Objective Caml]]></category>

		<guid isPermaLink="false">http://www.nicollet.net/?p=2273</guid>
		<description><![CDATA[Perhaps one of the single most useful aspects of functional programming is the absence of side-effects. In a pure functional language, there is no assignment — once created, you cannot change the members of an object or the value of a variable. All you can do is create new values based on old values. Advocates [...]]]></description>
			<content:encoded><![CDATA[<p>Perhaps one of the single most useful aspects of functional programming is the absence of side-effects. In a pure functional language, there is no assignment — once created, you cannot change the members of an object or the value of a variable. All you can do is create new values based on old values. Advocates of these so called <em>immutable values</em> argue that there are many benefits related to what you can do with them: you can keep around both the new version <em>and</em> the old version (implementing an &#8220;undo&#8221; feature of sorts), often at a reduced memory cost due to sharing of sub-elements between the two versions.</p>
<p>While I agree with these, I believe there&#8217;s something far more interesting about immutable values — what you <em>cannot</em> do with them, and the consequences this has on feeling <em>secure</em> about your code.</p>
<p>In my current project, I use a coding style that absolutely forbids any form of side-effects with the exception of 1° a clearly delimited set of create/update functions that affect the database, 2° any side-effects that affect local variables and 3° during initialization. These are of course <em>exceptions</em> — while allowed, they are avoided in the vast majority of the code.</p>
<h4>Reordering code</h4>
<p>One simple consequence: the order in which calls are made is only constrained by things that the compiler can detect — the function that uses <em>x</em> is called after the function that returns <em>x</em> — instead of subtle «open must be called before send» errors, simply because there&#8217;s no way for «open» to affect «send» unless the former returns a value used by the latter. So, I can rearrange lines freely because the compiler <em>will</em> warn me when I make a mistake.</p>
<h4>Protecting against invalid states</h4>
<p>A corrolary of the above is that it becomes possible to design your types so that only valid states can be represented. For instance, consider a list that must contain at least one element — in a mutable context, there is no way to represent this within the type system because I could always write this:</p>
<pre style="padding-left: 30px;">for (i = 0 ; i &lt; 10 ; i++)
  list.pop();</pre>
<p>There is no way here for the pop function to indicate that it might cause a problem, because it returns nothing — the only way out is an exception, and this happens outside the type system in most languages. On the other hand, if we keep the original list unmodified and return the new list, this opens the opportunity for indicating whether additional pops are available:</p>
<pre style="padding-left: 30px;">type 'a one_or_more =
  | One of 'a
  | More of 'a two_or_more

and 'a two_or_more = 'a * 'a one_or_more

let pop : 'a two_or_more -&gt; 'a one_or_more = function (_,rest) -&gt; rest</pre>
<p>By design, the pop function will never attempt to pop from a one-element list because it can only be called on a <em>two_or_more</em> value, and it returns a value which may or may not be a <em>two_or_more</em> — the code needs to check this, and the compiler will detect if you forget it:</p>
<pre style="padding-left: 30px;">let pop_n n list =
  if n = 0 then list else pop_n (n - 1) (pop list)</pre>
<p>Here, the type of the list variable is inferred to be <em>two_or_more</em> (because it&#8217;s passed as an argument to <em>pop</em>) which means that <em>pop list</em> (of type <em>one_or_more</em>) is not a valid argument to <em>pop_n</em>. An appropriate solution (popping up to <em>n</em>, if available) takes this into account:</p>
<pre style="padding-left: 30px;">let pop_n n = function
  | (One _) as keep -&gt; keep
  | more -&gt; if n = 0 then more else pop_n (n - 1) (pop more)</pre>
<p>Let&#8217;s summarize what happened here: I used a different representation for one-element lists and more-than-one-element lists, which let me selectively define a pop operation only for more-than-one-element lists, and this allowed the compiler to detect when the «must contain at least one element» constraint might be violated. Have fun achieving this in your non-functional language of choice! Using a different representation in this way was made possible by the fact that pop returns a new list instead of altering its argument — so the new list can be of a different type than the old one.</p>
<p>This is a fundamental principle in compiled functional languages: <strong>if a given state is not valid, design your types so that it may not be represented</strong>. When this is done correctly, not only does it become harder to write code that tries to create an invalid state, but when that code is written, the compiler rejects it.</p>
<h4>Memoization</h4>
<p>If you are certain that a given function is pure but involves computations that you would rather not repeat too often (such as database reads), you can resort to memoization: wrap the function in a piece of code that memorizes the result of every call. In my current project, this is as simple as:</p>
<pre style="padding-left: 30px;">let get_pic_url = Util.memoize Picture.get_url</pre>
<p>From then on, asking ten times for the URL of a given picture will result in a single database request. Had the function involved a side-effect, memoization would have changed the program behavior: knowledge that the function is pure lets me apply memoization without any risk of creating a bug.</p>
<h4>Retry until successful</h4>
<p>Yet another situation is when dealing with CouchDB transactions, which involve the following process:</p>
<ol>
<li>Fetch current version of the document from the database</li>
<li>Modify the document</li>
<li>Write the document back to the database</li>
<li>If a collision happened, repeat from 1.</li>
</ol>
<p>In short, the application must repeat steps 1-2-3 until a write succeeds. Correctness of these algorithms is difficult to test because development servers seldom have enough active users to actually cause conflicts (and when conflicts do happen, they are hard to trace). By deciding that steps 1-2-3 are handled by pure functional code, I have the guarantee that the loop can be executed any number of times and yield the expected result. Right now, a transaction looks like this:</p>
<pre style="padding-left: 30px;">let accept id = DB.transaction id
  begin function
  | None -&gt; (* No object in database *) DB.Keep
  | Some post -&gt;
    if post # accepted then
      (* Post is already accepted *) DB.Keep
    else
      (* Accept post *)
      DB.Put (object
        method accepted = true
        method author   = post # author
        method text     = post # text
      end)
  end</pre>
<p>By applying a &#8220;never use side-effects&#8221; convention, I know without even looking at the function contents that there are no side-effects inside.</p>
<p>These four examples are original in that they don&#8217;t try to showcase the <em>power</em> of immutable values and how they can be <em>used</em>. Instead, they simply illustrate how a program <em>without mutable values</em> has interesting properties that make refactoring easier, help the compiler detect many more errors, and allows the application of patterns that can only be safely applied in the absence of side-effects. Like the monks of old, I write my software without the mundane facilities of mutable values, but I derive significant benefits out of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nicollet.net/2011/02/avoid-side-effects/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sorry About That</title>
		<link>http://www.nicollet.net/2010/11/sorry-about-that/</link>
		<comments>http://www.nicollet.net/2010/11/sorry-about-that/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 23:04:49 +0000</pubDate>
		<dc:creator>Victor Nicollet</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[The Blog]]></category>
		<category><![CDATA[Useless]]></category>

		<guid isPermaLink="false">http://www.nicollet.net/?p=2123</guid>
		<description><![CDATA[Welcome to a geek&#8217;s worst nightmare: the server just went down. There&#8217;s no more blog, no more web site, no more safe online backup of your family pictures, and your victor@nicollet.net e-mail is deader than a wooden piece of&#8230; wood. Turns out, my hosting company had a little accident where hard drives suddenly couldn&#8217;t be [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome to a geek&#8217;s worst nightmare: the server just went down. There&#8217;s no more blog, no more web site, no more safe online backup of your family pictures, and your victor@nicollet.net e-mail is deader than a wooden piece of&#8230; wood. Turns out, my hosting company had a little accident where hard drives suddenly couldn&#8217;t be written to anymore.</p>
<p><img class="aligncenter size-full wp-image-2125" title="fail" src="http://www.nicollet.net/wp-content/uploads/2010/11/fail1.png" alt="" width="617" height="293" />Now, of course, <em>nicollet.net</em> is not what I would call a production server. On a real-life production server where the disk cannot be written to, sirens would start wailing, system administrators would be paged in the middle of the night (on a week-end), monitoring software would send cryptic apocalypse prophecies in their summary e-mails, and statues would cry blood. For my blog, everything continued to work in read-only mode for what appears to be half a day, until I decided to log in to the server and found out I couldn&#8217;t.</p>
<p>So, I rebooted it (from my hosting company&#8217;s online administration tool) and waited for it to come back up so I could investigate.</p>
<p>It didn&#8217;t. For half an hour. I kept refreshing <a href="http://travaux.ovh.net/vms/index_rbx.html" target="_blank">the web page that shows the server status</a> in my hosting company&#8217;s server rooms (mine is in 08H06) until I found out the page refreshed itself automatically.</p>
<p>And when it came back online, I stumbled upon the geek&#8217;s second worst nightmare: the private key of my server had been changed. In non-geek terms, this means that the server had been replaced by another server, possibly as a consequence of a hostile take-over by a random hacker (I&#8217;ve had this happen, and it&#8217;s very annoying) or an unexpected hard drive re-format.</p>
<p>After a few minutes of frantic searching, it appeared that my server had been replaced by a special rescue server that I was allowed to use to salvage whatever I could from the smoldering heap of its former self. That server, of course, had a special password that was sent to me on my e-mail address. All of you who guessed victor@nicollet.net, you get a cookie. All my attempts to have that password sent to another address failed miserably, until I finally gave up (because I have, you know, a <a href="http://www.nicollet.net/2010/10/runorg-aka-muahahaha/" target="_blank">Start-Up</a> to start up).</p>
<p>It took about 12 hours for my hosting company to find out what happened, revert the changes and reboot my server. No data was lost (except for that e-mail that Steve Jobs sent me about our secret project together, which I guess I&#8217;ll never get), and everything works like a charm.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nicollet.net/2010/11/sorry-about-that/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL (Un)Maintenance Trick</title>
		<link>http://www.nicollet.net/2010/04/mysql-unmaintenance-trick/</link>
		<comments>http://www.nicollet.net/2010/04/mysql-unmaintenance-trick/#comments</comments>
		<pubDate>Sat, 24 Apr 2010 21:49:58 +0000</pubDate>
		<dc:creator>Victor Nicollet</dc:creator>
				<category><![CDATA[Dynamic]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Surprises]]></category>

		<guid isPermaLink="false">http://www.nicollet.net/?p=1347</guid>
		<description><![CDATA[Not so long ago, I discussed the puzzling fact that in JavaScript, if(x) is not equivalent to if(x&#160;==&#160;true). Today, I stumbled upon a similar occurence in MySQL. The Problem Consider the following table, containing arbitrary text with an «alive» boolean flag: CREATE TABLE tested ( txt CHAR(32) NOT NULL, alive BOOLEAN NOT NULL, PRIMARY KEY(txt), [...]]]></description>
			<content:encoded><![CDATA[<p>Not so long ago, I discussed the <a href="http://www.nicollet.net/2010/02/javascript-unmaintenance-trick/">puzzling fact</a> that in JavaScript, <code>if(x)</code> is not equivalent to <code>if(x&nbsp;==&nbsp;true)</code>. Today, I stumbled upon a similar occurence in MySQL.</p>
<h4>The Problem</h4>
<p>Consider the following table, containing arbitrary text with an «alive» boolean flag:</p>
<pre style="padding-left: 30px;"><strong>CREATE TABLE</strong> tested (
  txt <strong>CHAR</strong>(32) <strong>NOT NULL</strong>,
  alive <strong>BOOLEAN NOT NULL</strong>,
  <strong>PRIMARY KEY</strong>(txt),
  <strong>KEY</strong>(alive)
);

<strong>INSERT INTO</strong> tested (txt,alive) <strong>VALUES</strong>
( <strong>MD5</strong>(1), <strong>FALSE</strong> ),
( <strong>MD5</strong>(2), <strong>FALSE</strong> ),
( <strong>MD5</strong>(3), <strong>FALSE</strong> ),
( <strong>MD5</strong>(4), <strong>TRUE</strong> ),
( <strong>MD5</strong>(5), <strong>TRUE</strong> );</pre>
<p>I want to display all the lines that are marked as alive, sorted by their text field. What is the difference between these two requests?</p>
<pre style="padding-left: 30px;"><strong>SELECT</strong> txt <strong>FROM</strong> tested <strong>WHERE</strong> alive <strong>ORDER BY</strong> txt;</pre>
<pre style="padding-left: 30px;"><strong>SELECT</strong> txt <strong>FROM</strong> tested <strong>WHERE</strong> alive = <strong>TRUE ORDER BY</strong> txt;</pre>
<p>And the answer is&#8230; <strong>both queries will return the same result set</strong>! But let&#8217;s <a href="http://dev.mysql.com/doc/refman/5.1/en/explain.html"><code>EXPLAIN</code></a> them, just in case.</p>
<table style="margin:auto" border="0" cellspacing="3">
<thead>
<tr style="text-align: center;">
<td></td>
<td>type</td>
<td>possible keys</td>
<td style="text-align: center;">key</td>
<td>rows</td>
</tr>
</thead>
<tbody>
<tr>
<td><code>WHERE alive</code></td>
<td style="text-align: center;">ALL</td>
<td></td>
<td></td>
<td style="text-align: center;">5</td>
</tr>
<tr>
<td><code>WHERE alive = TRUE</code></td>
<td style="text-align: center;">ref</td>
<td style="text-align: center;"><code>alive</code></td>
<td><code>alive</code></td>
<td style="text-align: center;">2</td>
</tr>
</tbody>
</table>
<p>The first query will scan through the entire table, whereas the second query will use the index to only run through lines that are still alive. If your table consists of 99% dead elements, the first query will be a hundred times slower than the second one!</p>
<h4>The Reason</h4>
<p>The fundamental reason for this behavior can be found in the <a href="http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html" target="_blank">MySQL documentation</a>:</p>
<blockquote><p>These types are synonyms for <code>TINYINT(1)</code>.             A value of zero is considered false. Nonzero values are             considered true:</p>
<p>However, the values <code>TRUE</code> and             <code>FALSE</code> are merely aliases for             <code>1</code> and <code>0</code>, respectively,             as shown here:</p></blockquote>
<p>In short, that boolean column is not actually a boolean value, but actually an integer. This means it can contain values that are neither <code>TRUE</code> nor <code>FALSE</code>, such as 2. Such a value would be returned by the first query, but not the second, so the query optimizer is not allowed to turn the first one into the second one. And  «this column evaluates to true in a boolean context» is not easily expressed as a key constraint, whereas «this column equals one» is the textbook definition of a key constraint. This explains why the second query is faster.</p>
<p>It also means that the second query might start behaving incorrectly if a non-<code>TRUE</code>, non-<code>FALSE</code> value finds its way into that column.</p>
<h4>The Solution</h4>
<p>The good news is that <code>NOT foo</code> is mathematically equivalent to <code>foo = FALSE</code>, so that the constraint can be easily rewritten by turning the «alive» property into a «dead» property. Both queries become equivalent, so the second query is a faster yet functionally identical alternative:</p>
<pre style="padding-left: 30px;"><strong>CREATE TABLE</strong> tested (
  txt <strong>CHAR</strong>(32)<strong> NOT NULL</strong>,
  dead <strong>BOOLEAN NOT NULL</strong>,
  <strong>PRIMARY KEY</strong>(txt),
  <strong>KEY</strong>(dead)
);

<strong>INSERT INTO</strong> tested (txt,dead) <strong>VALUES</strong>
( <strong>MD5</strong>(1), <strong>TRUE</strong> ),
( <strong>MD5</strong>(2), <strong>TRUE</strong> ),
( <strong>MD5</strong>(3), <strong>TRUE</strong> ),
( <strong>MD5</strong>(4), <strong>FALSE</strong> ),
( <strong>MD5</strong>(5), <strong>FALSE</strong> );

<strong>SELECT</strong> txt <strong>FROM</strong> tested <strong>WHERE</strong> dead = <strong>FALSE ORDER BY</strong> txt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.nicollet.net/2010/04/mysql-unmaintenance-trick/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lorem Ipsum</title>
		<link>http://www.nicollet.net/2010/03/lorem-ipsum/</link>
		<comments>http://www.nicollet.net/2010/03/lorem-ipsum/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 21:06:56 +0000</pubDate>
		<dc:creator>Victor Nicollet</dc:creator>
				<category><![CDATA[Imperative]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[Lorem Ipsum]]></category>
		<category><![CDATA[Useless]]></category>

		<guid isPermaLink="false">http://www.nicollet.net/?p=1280</guid>
		<description><![CDATA[Lorem Ipsum is a sample phrase used as a filler in typesetting, to illustrate how some text would look. Here&#8217;s a sample paragraph: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip [...]]]></description>
			<content:encoded><![CDATA[<p>Lorem Ipsum is a sample phrase used as a filler in typesetting, to illustrate how some text would look. Here&#8217;s a sample paragraph:</p>
<blockquote><p><em>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</em></p></blockquote>
<p>This approach to filler text is superior in many ways to most alternatives:</p>
<ul>
<li>It&#8217;s long, certainly longer than &#8220;Test&#8221; or &#8220;AAA&#8221;, so it can fill several lines (and test whether there is an unexpected length limit when saving the data).</li>
<li>Unlike random strings of characters copy-pasted several times, it is split into words of uneven length, spaces between words do not align horizontally or vertically.</li>
<li>It is readily recognizable as random text by any typesetter (or developer) worth its salt.</li>
</ul>
<p>A typical testing strategy, when filling forms by hand, is to copy-paste one or two Lorem Ipsum paragraph to test such things as how the text area reacts, whether it is saved correctly, and so on.</p>
<p>Lorem Ipsum does have some limitations:</p>
<ul>
<li>It&#8217;s written in latin, so it fits nicely in the ASCII range of characters. As such, it does not test for Unicode support.</li>
<li>It contains no quotes of any kind, so no testing of database escaping processing either.</li>
<li>It contains no HTML-specific characters like &lt; or &amp;, so HTML character escaping is not tested either.</li>
<li>For that matter, it does not contain exceedingly long words that would overflow a single line, so you cannot test for this kind of overflow either.</li>
<li>Sometimes, you want to auto-linkify links and URLs.</li>
<li>Sometimes, Skype turns numbers into &#8230; clickable numbers.</li>
</ul>
<p>I need to test these things on my web applications, so I&#8217;ve developed my own version of a &#8220;<strong>Modern Lorem Ipsum</strong>&#8220;:</p>
<blockquote><p><em>Lorem &lt;a href=&#8221;javascript:document.write(&#8221;)&#8221;&gt;ipsum&lt;/a&gt; dòlor sit àmet, consectetur adipisicing élit, sèd do eiusmod tempor incididunt ut labore &amp; dolore magna aliqua. &lt;hr/&gt;Ut enim@minim.com veniam, quis nostrud exercitation `&#8221;ullamco laboris nisi &amp; aliquip ex æ commodo consequat. Duis aute irure dolor 01 23 45 67 89 in reprehenderit in voluptate velit esse cillum dolore `eu fugiat https://nulla.biz/pariatur. aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa </em></p>
<p><em>Excepteur [u]sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit &#8216;anim id est laborum.[u] </em><em>Lorem&#8221; ipsum dòlor sit àmet, consectetur adipisicing élit, sèd do eiusmod tempor http://incididunt.ut.com/labore &amp; dolore magna aliqua. &lt;b&gt;Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex æ commodo consequat.&lt;/b&gt; &#8220;Duis aute irure dolor in &#8216;reprehenderit in voluptate velit &#8212; esse cillum dolore eu fugiat nulla pariatur.</em></p></blockquote>
<p>Feel free to copy-paste it away. WordPress certainly does seem to have a hard time with these long lines in post bodies—I wonder if it happens in comments as well <img src='http://www.nicollet.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.nicollet.net/2010/03/lorem-ipsum/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>That DOM removal thing, again</title>
		<link>http://www.nicollet.net/2010/01/that-dom-removal-thing-again/</link>
		<comments>http://www.nicollet.net/2010/01/that-dom-removal-thing-again/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 06:56:26 +0000</pubDate>
		<dc:creator>Victor Nicollet</dc:creator>
				<category><![CDATA[Dynamic]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.nicollet.net/?p=1255</guid>
		<description><![CDATA[Earlier this month, I pondered what looked like a bug in JavaScript/DOM/jQuery: removing an element from the DOM with jQuery (either manually with remove() or by setting the html() of its parent to something else) kept most of the data bound to the element around, but removed all event handlers from it. You could then [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this month, I pondered what looked like <a href="http://www.nicollet.net/2010/01/dom-removal-and-events/" target="_blank">a bug in JavaScript/DOM/jQuery</a>: removing an element from the DOM with jQuery (either manually with remove() or by setting the html() of its parent to something else) kept most of the data bound to the element around, but removed all event handlers from it. You could then re-insert the element, but its event handlers would be lost.</p>
<p>I then gathered from several sources, such as <a href="http://stackoverflow.com/questions/2027706/why-do-registered-events-disappear-when-an-element-is-removed-from-dom">Stack Overflow</a>, that this is a jQuery issue (or rather, feature) and not a JavaScript one.</p>
<p>The <a href="http://javascript.crockford.com/memory/leak.html">underlying cause</a> is explained by Douglas Crockford:</p>
<blockquote><p>When a DOM object contains a reference to a    JavaScript object (such an    event handling function), and when that JavaScript object contains a reference    to that DOM object, then a cyclic structure is formed. This is not in itself    a problem. At such time as there are no other references to the DOM object and    the event handler, then the garbage collector (an automatic memory resource    manager) will reclaim them both, allowing their space to be reallocated. The    JavaScript garbage collector understands about cycles and is not confused by    them. Unfortunately, IE&#8217;s DOM is not managed by JScript. It has its own memory    manager that does not understand about cycles and so gets very confused. As    a result, when cycles occur, memory reclamation does not occur.</p></blockquote>
<p>A common solution to this problem is to remove the cycles when the element is removed from the DOM. Since a major source of cycles in your average jQuery program is the presence of event handlers, then removing the event handlers when an element is removed from the DOM solves the problem most of the time.</p>
<p>With the release of jQuery 1.4, the new documentation for <a href="http://api.jquery.com/remove/" target="_blank"><code>.remove()</code></a> makes mention of this fact:</p>
<blockquote><p>In addition to the elements themselves, all bound events and jQuery data  associated with the elements are removed.</p></blockquote>
<p>The documentation for <a href="http://api.jquery.com/html/" target="_blank"><code>.html()</code></a> still makes no mention of this. If you want to remove an element and keep all the goodies you bound to it, jQuery 1.4 provides you with <a href="http://api.jquery.com/detach/" target="_blank"><code>.detach()</code></a>:</p>
<blockquote><p>The <code>.detach()</code> method is the same as <code>.remove()</code>, except that <code>.detach()</code> keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.nicollet.net/2010/01/that-dom-removal-thing-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shouldn&#8217;t Happen&#8230;</title>
		<link>http://www.nicollet.net/2010/01/shouldnt-happen/</link>
		<comments>http://www.nicollet.net/2010/01/shouldnt-happen/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 20:29:26 +0000</pubDate>
		<dc:creator>Victor Nicollet</dc:creator>
				<category><![CDATA[Imperative]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[Psychology]]></category>

		<guid isPermaLink="false">http://www.nicollet.net/?p=1252</guid>
		<description><![CDATA[Design and development is turning the great unknown chaos into tiny bits of controlled functionality with promises about what the result will be, and expectations about what the input should be. There is an interesting duality between two categories of expectations, depending on whether they are the responsibility of the user, or of the programmer. [...]]]></description>
			<content:encoded><![CDATA[<p>Design and development is turning the great unknown chaos into tiny bits of controlled functionality with promises about what the result will be, and expectations about what the input should be.</p>
<p>There is an interesting duality between two categories of expectations, depending on whether they are the responsibility of the user, or of the programmer.</p>
<p>User errors are classic mistakes involving incorrect input, such as attempting to load a file that does not have the right format, or visiting a web site that does not exist, or entering an incorrect email address. A program is expected to, at the very least, gracefully handle these situations (because nobody likes errors) and the best programs are actively designed to reduce the possibility of error though appropriate user interface choices.</p>
<p>Programmer errors are the most frequent ones, but most of there are luckily caught by a compiler (or, in the case of the less lucky interpreted languages, the parser). The basic idea is that if you expect a function parameter to be an integer, and you tell your compiler, then static analysis will determine that you will receive a string argument, and the <span style="text-decoration: line-through;">universe will collapse</span> build will fail.</p>
<h3>Static Analysis</h3>
<p>Static analysis can be very smart. It can prove beyond any doubts <a href="http://www.astree.ens.fr/" target="_blank">complex properties</a> about complex software written in obscenely low-level code (such as C with inline assembly). The problem if that working with a static analysis tool can add unusual constraints on the developers themselves: the halting problem dictates that no tool can safely predict the behavior of a program, so any given tool will either have false negatives (undetected bugs) or false positives (safe code reported as dangerous) and the general trend for static analysis tools is to avoid any false negatives at the cost of false positives.</p>
<p>The quality of a static analysis tool is determined by how hard it is to write code without false positives (usually done by manually coding around the blind spots of the tool).</p>
<p>Static analysis tools have two problems. One, they&#8217;re not available for every single language and platform out there. Some of use are still using languages with <code>eval()</code>, throwing Java exception-safety out the window because we find it too constraining, doing without those pesky type systems and generally making a childish fuss about those &#8220;warning&#8221; thingies. Two, static analysis tools can only check constraints that are described by the developer in some form, such as assertions, preconditions, postconditions, type annotations or some other kind of attribute added to the code.</p>
<p>So, if you forget to &#8220;assert&#8221; it, nobody is going to check it for you. For instance, no tool is going to warn you that you unwittingly leak a credit card number to a third party.</p>
<h3>The Elephant Statue</h3>
<p>In a sense, predicting user errors is the mirror activity of gathering specifications. Both force you to think about all possible situations your software will face, and decide what should happen: maybe you have to display an error, maybe you will have to tread the input in a clever but predictable way, or maybe you will have to rework your process to prevent that situation from happening.</p>
<p>This is akin to creating an elephant statue by starting with a block of stone and carving out everything but the elephant. Deciding what your users can do implicitly defines what your users cannot do. Depending on the situation, you may guide your design with either approach.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nicollet.net/2010/01/shouldnt-happen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DOM removal and events</title>
		<link>http://www.nicollet.net/2010/01/dom-removal-and-events/</link>
		<comments>http://www.nicollet.net/2010/01/dom-removal-and-events/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 21:12:25 +0000</pubDate>
		<dc:creator>Victor Nicollet</dc:creator>
				<category><![CDATA[Functional]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.nicollet.net/?p=1248</guid>
		<description><![CDATA[Let&#8217;s try something&#8230; go to a page with jQuery enabled (such as this one), and run the following code in your Javascript debugger console (such as Firebug): var button = $('&#60;button&#62;Click me&#60;/button&#62;') .click(function(){alert('Clicked!')}) .appendTo('body') In case you were wondering, this creates a brand new button, causes it to display a &#8220;Clicked!&#8221; message box when it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s try something&#8230; go to a page with jQuery enabled (<a href="http://nicollet.net/files/articles/jstut/" target="_blank">such as this one</a>), and run the following code in your Javascript debugger console (such as Firebug):</p>
<pre style="padding-left: 30px;"><span>var button =
  $('&lt;button&gt;Click me&lt;/button&gt;')
  .click(function(){alert('Clicked!')})
  .appendTo('body')</span></pre>
<p>In case you were wondering, this creates a brand new button, causes it to display a &#8220;Clicked!&#8221; message box when it&#8217;s clicked, and appends it to the document you are viewing.</p>
<p>Click on the button that just appeared : the message box appears. Not very surprising.</p>
<p>Now, run the following code on the same page :</p>
<pre style="padding-left: 30px;"><span>$('body').html('');
button.appendTo('body')</span></pre>
<p>As expected, everything on the page, including the button, disappears. However, the button is still referenced by the <code>button</code> variable, so it sticks around and we can append it back to the document. And indeed, it does appear on the page.</p>
<p>Click on the button again. This time, no message box appears.</p>
<p>I honestly have no idea <strong>why</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nicollet.net/2010/01/dom-removal-and-events/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

