<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Posts about Gotcha</title>
    <link>http://wiki.futuretoby.com/tag/gotcha</link>
    <language>en-us</language>
    <item>
      <title>ActiveRecord Gotcha</title>
      <description>I came across this interesting gotcha while debugging through someone else's rails code. When you set a model's one-to-many attribute(an perhaps other association types as well), let's say:&lt;pre&gt;user.friends = new_friend_list&lt;/pre&gt;&lt;div&gt;It doesn't always set it. As far as I can figure from my blackbox testing, it does an equal check first between the old value and the new value, and then sets only if they are different.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Now, in Ruby's == is easily overridable, you can easily make it do anything you want. It happens that Array#== returns true iff both arrays have the same number of elements and each element in one array is == to the element of the other array in the same position. It also happens that ActiveRecord's base class' == returns true as long as the objects are of the same class and the primary keys equal.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Which brings us to the gotcha of the day. The code in question built an array, say &lt;span class="Apple-style-span" style="font-style: italic;"&gt;new_&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;friend_list&lt;/span&gt;&#160;independently, starting with an id list passed in from a from, finding each &lt;span class="Apple-style-span" style="font-style: italic;"&gt;friend&lt;/span&gt;&#160;in the database and adding them to the array, but, in the meantime, modifying a field in each of the friends, say...&lt;span class="Apple-style-span" style="font-style: italic;"&gt;friend.charma++&lt;/span&gt;. It then goes on to set the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;friends&lt;/span&gt;&#160;attribute in the manner you'd already seen above, and saves &lt;span class="Apple-style-span" style="font-style: italic;"&gt;user&lt;/span&gt;. Well, the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;charma&lt;/span&gt;&#160;field&#160;that was modified in each of the friends retrieved did not get saved, because the set did not happen: the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;new_friend_list &lt;/span&gt;pointed to the same list of friends &lt;span class="Apple-style-span" style="font-style: italic;"&gt;user&lt;/span&gt;&#160;was already associated to.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Hmm..., yeah. Watch out for this one. Debugging this one was not fun. It definitely didn't fit with the principle of least surprise.&lt;/div&gt;</description>
      <pubDate>Fri, 01 May 2009 23:18:36 -0500</pubDate>
      <guid>http://wiki.futuretoby.com/ActiveRecord_Gotcha</guid>
      <author>toby ho</author>
      <link>http://wiki.futuretoby.com/ActiveRecord_Gotcha</link>
    </item>
    <item>
      <title>Ruby Gotcha of the Day</title>
      <description>Okay, so in ruby:&lt;br&gt;&lt;pre&gt;&gt;&gt;&#160;nil&#160;or&#160;'value'&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;=&gt;&#160;"value"&lt;br&gt;&lt;/pre&gt;because nil acts as false when used with boolean operators and any other object acts as true. Now let's assign the result to a temp variable a:&lt;br&gt;&lt;pre&gt;&gt;&gt; a = nil or 'value'&lt;br&gt;&lt;/pre&gt;&lt;font face="courier new,courier"&gt;&lt;pre&gt;=&gt; "value"&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&gt;&gt; a&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;=&gt; nil&lt;br&gt;&lt;/pre&gt;&lt;/font&gt;Whoa?? Can you guess? In ruby the assignment operator is not special. It acts just like any other operator and does not have a lower precedence than the &lt;i&gt;or&lt;/i&gt; operator. Therefore the expression&lt;br&gt;&lt;pre&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;a = nil&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;executes first, which evaluates to &lt;i&gt;nil&lt;/i&gt;, and assigns the value &lt;i&gt;nil&lt;/i&gt; to &lt;i&gt;a&lt;/i&gt;, and then the result &lt;i&gt;nil&lt;/i&gt; is used in the expression &lt;i&gt;nil or 'value'&lt;/i&gt;. Therefore to do what we intended we need to do:&lt;br&gt;&lt;pre&gt;&gt;&gt; a = (nil or 'value')&lt;br&gt;&lt;/pre&gt;&lt;font face="courier new,courier"&gt;&lt;pre&gt;=&gt; "value"&lt;br&gt;&lt;/pre&gt;&lt;/font&gt;Wow! That is messed up. &lt;br&gt;</description>
      <pubDate>Fri, 26 Dec 2008 19:03:23 -0600</pubDate>
      <guid>http://wiki.futuretoby.com/Ruby_Gotcha_of_the_Day</guid>
      <author>toby ho</author>
      <link>http://wiki.futuretoby.com/Ruby_Gotcha_of_the_Day</link>
    </item>
    <item>
      <title>Python Optional Arguments Gotcha</title>
      <description>When you use Python optional arguments you should know that the default value you set is static, it is set at the time the function is defined, and does not change after that. If you a mutable type as the default value, you need to be careful. &lt;br&gt;Ex:&lt;br&gt;&lt;font face="courier new,courier"&gt;&lt;br&gt;&lt;/font&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; def enlist(n, lst=[]):&lt;/pre&gt;&lt;pre&gt;...&amp;nbsp;&amp;nbsp; lst.append(n)&lt;/pre&gt;&lt;pre&gt;...&amp;nbsp;&amp;nbsp; return lst&lt;/pre&gt;&lt;pre&gt;...&lt;/pre&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; enlist(3)&lt;/pre&gt;&lt;pre&gt;[3]&lt;/pre&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; enlist(4)&lt;/pre&gt;&lt;pre&gt;[3, 4]&lt;/pre&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; enlist(5)&lt;/pre&gt;&lt;pre&gt;[3, 4, 5]&lt;/pre&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; enlist(6)&lt;/pre&gt;&lt;pre&gt;[3, 4, 5, 6]&lt;/pre&gt;&lt;pre&gt;&lt;br&gt;&lt;/pre&gt;Everytime you call the &lt;font face="courier new,courier"&gt;enlist&lt;/font&gt; function, the list gets bigger, because &lt;font face="courier new,courier"&gt;lst&lt;/font&gt; is never reset to the empty list. It is set to the empty list only once, when &lt;font face="courier new,courier"&gt;enlist&lt;/font&gt; was defined. After that it references the same instance everytime you don't supply a &lt;font face="courier new,courier"&gt;lst&lt;/font&gt; argument.&lt;br&gt;</description>
      <pubDate>Wed, 15 Oct 2008 14:54:33 -0500</pubDate>
      <guid>http://wiki.futuretoby.com/Python_Optional_Arguments_Gotcha</guid>
      <author>toby ho</author>
      <link>http://wiki.futuretoby.com/Python_Optional_Arguments_Gotcha</link>
    </item>
    <item>
      <title>Javascript Gotcha</title>
      <description>&lt;font size="3"&gt;&lt;strong&gt;offsetTop&lt;/strong&gt;&lt;/font&gt;&lt;br&gt;element.offsetTop does different things in gecko than IE, best bet is to use the function listed here: &lt;a href="http://www.quirksmode.org/js/findpos.html"&gt;http://www.quirksmode.org/js/findpos.html&lt;/a&gt;, the code: &lt;br&gt;&lt;font face="courier new,courier"&gt;&lt;br&gt;&lt;pre&gt;function findPos(obj) {&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp;var curleft = curtop = 0;&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp;if (obj.offsetParent) {&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;curleft = obj.offsetLeft&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;curtop = obj.offsetTop&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;while (obj = obj.offsetParent) {&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;curleft += obj.offsetLeft&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;curtop += obj.offsetTop&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp;return [curleft,curtop];&lt;br&gt;&lt;/pre&gt;&lt;pre&gt;}&lt;br&gt;&lt;/pre&gt;&lt;/font&gt;</description>
      <pubDate>Mon, 03 Sep 2007 23:42:36 -0500</pubDate>
      <guid>http://wiki.futuretoby.com/Javascript_Gotcha</guid>
      <author>toby ho</author>
      <link>http://wiki.futuretoby.com/Javascript_Gotcha</link>
    </item>
  </channel>
</rss>

