<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>wuputah ~ Jonathan Dance</title>
  <id>http://wuputah.com</id>
  <updated>2009-08-29</updated>
  <author>
    <name>Jonathan Dance</name>
  </author>
  <entry>
    <title>Stop punching the duck</title>
    <link rel="alternate" href="http://wuputah.com/2010/10/27/stop-punching-the-duck/"/>
    <id>http://wuputah.com/2010/10/27/stop-punching-the-duck/</id>
    <published>2010-10-27</published>
    <updated>2010-10-27</updated>
    <author>
      <name>Jonathan Dance</name>
    </author>
    <summary type="html">&lt;p&gt;So there you were, minding your own business, doing some behavior
driven development, thinking everything is great. You test your
controllers, you spec your models, and now the final, dreadful step:&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;So there you were, minding your own business, doing some behavior
driven development, thinking everything is great. You test your
controllers, you spec your models, and now the final, dreadful step:
actually firing up the browser. Expecting to see some terrible CSS
disasters, you get a nice error screen. &amp;ldquo;That&amp;rsquo;s weird,&amp;rdquo; you say, &amp;ldquo;my
cucumber tests say this should work!&amp;rdquo;&lt;/p&gt;

&lt;p&gt;Alas, enter the duck punch. In your testing environment, rspec and
cucumber are loaded. And that means so is &lt;a href="http://github.com/dchelimsky/rspec-rails/blob/master/lib/spec/rails/extensions/active_record/base.rb#L28"&gt;this little duck punch&lt;/a&gt;.
Seems like you used &lt;code&gt;errors_on&lt;/code&gt; instead of using &lt;code&gt;errors.on&lt;/code&gt;. This
worked just fine in your tests but now that rspec is not loaded, the
feature explodes.&lt;/p&gt;

&lt;p&gt;And there&amp;rsquo;s no test you can write to check for this.&lt;/p&gt;

&lt;p&gt;Your philosophical view of the world broken, you give up programming and
&lt;a href="http://en.wikipedia.org/wiki/Jainism"&gt;move to a cave&lt;/a&gt;, never to be seen by civilization again.&lt;/p&gt;

&lt;p&gt;So please, before you punch a duck, think of the caves. There&amp;rsquo;s only so
many left.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Early bird dilemma</title>
    <link rel="alternate" href="http://wuputah.com/2010/10/19/early-bird-dilemma/"/>
    <id>http://wuputah.com/2010/10/19/early-bird-dilemma/</id>
    <published>2010-10-19</published>
    <updated>2010-10-19</updated>
    <author>
      <name>Jonathan Dance</name>
    </author>
    <summary type="html">&lt;p&gt;One of the (many) problems I have with society today is that the early
bird is rewarded, while the &amp;ldquo;late bird&amp;rdquo; is frowned upon. Meanwhile,
[$300 million][1] is lost because of this &lt;em&gt;every weekday.&lt;/em&gt;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;One of the (many) problems I have with society today is that the early
bird is rewarded, while the &amp;ldquo;late bird&amp;rdquo; is frowned upon. Meanwhile,
&lt;a href="http://www.msnbc.msn.com/id/20829879/"&gt;$300 million&lt;/a&gt; is lost because of this &lt;em&gt;every weekday.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A quick example is commuting. Traffic here in Boston starts to back up
as early as 6 AM, and actually flows more regularly at 8:30 or 9am. As
each person tries to get up earlier and earlier to beat traffic and get
into work early, the problem has cascaded to the point where it makes
more sense to go in later, not earlier.&lt;/p&gt;

&lt;p&gt;However, people who try to take advantage of this are looked upon as
lazy, as showing up to work &amp;ldquo;late&amp;rdquo; is frowned upon. 8am, 9am, or 10am
meetings cause problems with this approach. If we assume the &amp;ldquo;normal&amp;rdquo;
time for starting work is 9am (although more commonly, due to this
phenomenon, most people arrive around 8am). It&amp;rsquo;s fine to show up to work
3 hours early (6am)&amp;mdash;in fact, this is usually considered a sign of being
hard working or responsible&amp;mdash;but show up an hour late (10am) and you are
likely to be looked down upon. You must have been &amp;ldquo;up late partying.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;Instead of encouraging everyone to show up at the same time, spreading
out the work day should be encouraged. It reduces congestion, reducing
traffic on the roads and mass transit systems. It encourages flexibility,
allowing people to fit work into their lives how they see fit. Some
people are morning people; some are not. Some people have commitments,
and need to be home at a certain hour.&lt;/p&gt;

&lt;p&gt;Even among my programmer cohorts, who are among those who have realized
the folly of this system and often enjoy the flexibility of working on
their schedule, some believe that this is detrimental to the work
environment, productivity, team dynamics, or even personal health. Even
if your organization allows a dynamic schedule, you will probably be
partially judged by superiors by the time of your arrival. Debunking
these myths is near impossible, as we have been risen in a society where
&amp;ldquo;the early bird catches the worm.&amp;rdquo; Showing up for work on time is
frequently more important than results, even if you would get better
results from being well rested.&lt;/p&gt;

&lt;p&gt;In short, the workplace should be a meritocracy. Nothing else should
matter. This is never the case.&lt;/p&gt;

&lt;p&gt;As I mentioned, this is one of many examples. Yet another early bird
dilemma is the queue, which naturally favors the one who arrived first,
and therefore waited the longest. Now in many cases, I have no problem
with this; certainly waiting in line at the grocery store makes sense.
However, when it comes to things like product releases or ticket sales,
this system is fundamentally flawed. Encouraging people to wait in a
queue for hours, sometimes days or even weeks, is not healthy nor
productive.  Certainly a lottery would be a better approach to this
system.&lt;/p&gt;

&lt;p&gt;As someone who both frequently rises early (I wrote this entry &lt;em&gt;before&lt;/em&gt;
leaving for work) and stays up all night, I fear I&amp;rsquo;ll be fighting the
early bird dilemma for my entire life.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>A Note to Recruiters</title>
    <link rel="alternate" href="http://wuputah.com/2010/08/07/a-note-to-recruiters/"/>
    <id>http://wuputah.com/2010/08/07/a-note-to-recruiters/</id>
    <published>2010-08-07</published>
    <updated>2010-08-07</updated>
    <author>
      <name>Jonathan Dance</name>
    </author>
    <summary type="html">&lt;p&gt;If you&amp;rsquo;re a recruiter (that is, anyone looking to hire me), please read this
before contacting me, or you risk losing a potential lead forever&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;If you&amp;rsquo;re a recruiter (that is, anyone looking to hire me), please read this
before contacting me, or you risk losing a potential lead forever.&lt;/p&gt;

&lt;p&gt;As you are probably aware, software engineers are in fairly high demand.
Those with experience in Ruby on Rails are even more so. Demand is easily
outstripping supply, and that means I get contacted a lot, even though I am not
actively looking for a new position.&lt;/p&gt;


&lt;p&gt;So, before sending me an email or thinking about dialing those enticing 10
digits on my home page, please note the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I am gainfully and happily employed. This means that your position needs to
be very enticing just to consider the position. In order to do this, you
must be able to provide me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The name of the company I would be working for.&lt;/li&gt;
&lt;li&gt;What I would specifically be working on.&lt;/li&gt;
&lt;li&gt;What it&amp;rsquo;s like to work at the company, in terms of work expectations,
office environment, and the corporate culture.&lt;/li&gt;
&lt;li&gt;What I might expect for compensation and benefits.&lt;/li&gt;
&lt;li&gt;All the standard information you would include in a job posting. Ryan
Bigg &lt;a href="http://ryanbigg.com/job-postings/"&gt;has a longer list&lt;/a&gt; on what should be in a job posting.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;If you&amp;rsquo;re unable to provide this information &lt;strong&gt;by email&lt;/strong&gt;, whether
it&amp;rsquo;s due to contractual obligations, because your business model depends
on withholding information (or you don&amp;rsquo;t trust me), or because you
haven&amp;rsquo;t done your homework and don&amp;rsquo;t know, then you should not bother
contacting me. You may think that phone calls are a &amp;ldquo;better way&amp;rdquo; to
share information, but I can&amp;rsquo;t have phone calls every other day with
recruiters when I&amp;rsquo;m not even looking for a job.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do not contact me by email and then &amp;ldquo;follow up&amp;rdquo; with a phone call unless I
have specifically requested to speak with you. Unsolicited email followed by
a unsolicited phone call is likely to get you blocked. I will respond to
your email if you have provided the above information and if I&amp;rsquo;m interested.
If you&amp;rsquo;re thorough and polite, I will usually respond either way within a
few days.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don&amp;rsquo;t make me do your work for you. You need to sell me on the job. &lt;a href="http://ryanbigg.com/2010/05/recruiters-know-thine-recruitees/"&gt;Know
your recruit.&lt;/a&gt; If you want to know more about my professional
experience, check out my &lt;a href="http://linkedin.com/in/wuputah"&gt;LinkedIn profile&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;All that being said, I don&amp;rsquo;t want this to be taken the wrong way. I&amp;rsquo;m
happy to be contacted, but you&amp;rsquo;re not doing me&amp;mdash;or yourself&amp;mdash;any favors
if you can&amp;rsquo;t tell me what the job is about.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Bluepill, chef, and resque</title>
    <link rel="alternate" href="http://wuputah.com/2010/07/02/bluepill-chef-and-resque/"/>
    <id>http://wuputah.com/2010/07/02/bluepill-chef-and-resque/</id>
    <published>2010-07-02</published>
    <updated>2010-07-02</updated>
    <author>
      <name>Jonathan Dance</name>
    </author>
    <summary type="html">&lt;p&gt;&lt;a href="http://github.com/arya/bluepill"&gt;Bluepill&lt;/a&gt; is an alternative for process monitoring, competing in the same space as heavyweight &lt;a href="http://mmonit.com/monit/"&gt;monit&lt;/a&gt; and hubristic &lt;a href="http://god.rubyforge.org/"&gt;god&lt;/a&gt;. Like &lt;code&gt;god&lt;/code&gt;, bluepill itself and its recipes are written in pure Ruby. &lt;a href="http://asemanfar.com/Why-We-Wrote-Bluepill"&gt;Bluepill&amp;rsquo;s goal&lt;/a&gt; is to be very lightweight, and while it weighs in at greater than 1400 LOC, it&amp;rsquo;s much smaller than both &lt;code&gt;monit&lt;/code&gt; and &lt;code&gt;god&lt;/code&gt;, and easily wins over &lt;code&gt;god&lt;/code&gt; on memory usage:&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;&lt;a href="http://github.com/arya/bluepill"&gt;Bluepill&lt;/a&gt; is an alternative for process monitoring, competing in the same space as heavyweight &lt;a href="http://mmonit.com/monit/"&gt;monit&lt;/a&gt; and hubristic &lt;a href="http://god.rubyforge.org/"&gt;god&lt;/a&gt;. Like &lt;code&gt;god&lt;/code&gt;, bluepill itself and its recipes are written in pure Ruby. &lt;a href="http://asemanfar.com/Why-We-Wrote-Bluepill"&gt;Bluepill&amp;rsquo;s goal&lt;/a&gt; is to be very lightweight, and while it weighs in at greater than 1400 LOC, it&amp;rsquo;s much smaller than both &lt;code&gt;monit&lt;/code&gt; and &lt;code&gt;god&lt;/code&gt;, and easily wins over &lt;code&gt;god&lt;/code&gt; on memory usage:&lt;/p&gt;

&lt;p class="img"&gt;&lt;img src="http://asemanfar.com/system/bluepill_memory_usage.png" alt="Bluepill vs God memory usage" /&gt;&lt;/p&gt;


&lt;p&gt;At WegoWise, we began to investigate using bluepill on recommendation from EngineYard as bluepill would be an independent system apart from EY&amp;rsquo;s own use of monit. We were previously using monit to monitor and control our &lt;a href="http://github.com/defunkt/resque"&gt;resque&lt;/a&gt; processes; bluepill would replace this role.&lt;/p&gt;

&lt;h3&gt;The Good&lt;/h3&gt;

&lt;p&gt;There are some very nice things about bluepill. Bluepill removes the need to create &lt;code&gt;init.d&lt;/code&gt;-style scripts to control your processes. Bluepill will handle creating PID files, daemonizing, and sending a standard &lt;code&gt;TERM&lt;/code&gt; signal to end the process (as well as number of other handy things). For our resque processes, the only truly necessary configuration is a start command.&lt;/p&gt;

&lt;p&gt;If that&amp;rsquo;s the case, then why is our resulting chef recipe and bluepill template (&lt;a href="http://github.com/wegowise/chef-recipes/tree/master/resque"&gt;which we&amp;rsquo;ve released to the public&lt;/a&gt;) so complicated? Well, most of the complication is queue logic, but there&amp;rsquo;s some other tricks in there that are worth explaining.&lt;/p&gt;

&lt;h3&gt;The Bad&lt;/h3&gt;

&lt;p&gt;Overall, our experience with bluepill has been very positive, but it is not without a few drawbacks. Bluepill doesn&amp;rsquo;t do graceful shutdowns, nor will it ever issue a &lt;code&gt;KILL&lt;/code&gt; signal if the process becomes unresponsive to &lt;code&gt;TERM&lt;/code&gt;. To solve this, we included a &lt;a href="http://github.com/wegowise/chef-recipes/blob/b00c047f2597316eb3a4420bf09ae5ad0df2e4c9/resque/templates/default/resque.pill.erb#L32-45"&gt;&lt;code&gt;QUIT&lt;/code&gt;&amp;rarr;&lt;code&gt;TERM&lt;/code&gt;&amp;rarr;&lt;code&gt;KILL&lt;/code&gt; signal chain in our bluepill configuration&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another problem is there&amp;rsquo;s no way to set up alerts should something go terribly wrong (we&amp;rsquo;ve yet to solve this problem). For instance, bluepill allows you to monitor flapping (rapid restarting), but bluepill will simply unmonitor the process when this occurs, and you will be none the wiser. This also occurs is if the process doesn&amp;rsquo;t start, stop, or restart within the allotted grace time. Therefore, a shutdown script like the one we used is a real necessity.&lt;/p&gt;

&lt;p&gt;For now, we&amp;rsquo;ve solved our most critical issue directly in our pill (each bluepill configuration file is called a &lt;em&gt;pill&lt;/em&gt;), but we might look into adding signal chains and alerts to bluepill itself. Fortunately, resque is quite stable and so alerts&amp;mdash;even using a &lt;code&gt;TERM&lt;/code&gt; signal&amp;mdash;has yet to be necessary, and bluepill has been rock solid as well.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Moving attachment_fu from filesystem to S3 storage</title>
    <link rel="alternate" href="http://wuputah.com/2010/06/27/moving-attachmentfu-from-filesystem-to-s3-storage/"/>
    <id>http://wuputah.com/2010/06/27/moving-attachmentfu-from-filesystem-to-s3-storage/</id>
    <published>2010-06-27</published>
    <updated>2010-06-27</updated>
    <author>
      <name>Jonathan Dance</name>
    </author>
    <summary type="html">&lt;p&gt;Most of this transition is fairly easy, but many users will find a small hiccup when it comes time to upload your files to S3.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;config/amazon_s3.yml&lt;/code&gt; file with your credentials&amp;hellip;&lt;/li&gt;
&lt;/ol&gt;

</summary>
    <content type="html">&lt;p&gt;Most of this transition is fairly easy, but many users will find a small hiccup when it comes time to upload your files to S3.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;config/amazon_s3.yml&lt;/code&gt; file with your credentials.&lt;/li&gt;
&lt;li&gt;Setup your S3 bucket, upload the files (I use &lt;a href="http://www.s3fox.net/"&gt;S3Fox&lt;/a&gt;). Make sure to set the access to world-read for your uploaded files.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;aws-s3&lt;/code&gt; gem to your environment as well as your hosting platform or server.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Ah, but there is a small problem. How do you get from &lt;code&gt;attachment_fu&lt;/code&gt;&amp;rsquo;s default of &lt;code&gt;0010/5198/filename.png&lt;/code&gt; to &lt;code&gt;105198/filename.png&lt;/code&gt;? The solution is a small Bash script. This is designed to be run from within the top-level folder for each of your &lt;code&gt;attachment_fu&lt;/code&gt; directories, like &lt;code&gt;public/pictures&lt;/code&gt;, &lt;code&gt;public/avatars&lt;/code&gt;, etc.&lt;/p&gt;

&lt;script src="http://gist.github.com/455215.js?file=rename-files-for-s3.sh"&gt;&lt;/script&gt;


&lt;p&gt;I&amp;rsquo;d recommend running this on a copy of your files, just in case I messed up, but the most important line is &lt;code&gt;let "d=$d1$d2"&lt;/code&gt;. This wonderful line combines the &lt;code&gt;0010&lt;/code&gt; and &lt;code&gt;5198&lt;/code&gt; and treats them as a number, for a result of &lt;code&gt;105198&lt;/code&gt;. I don&amp;rsquo;t know much about &lt;code&gt;let&lt;/code&gt;, but it seems to work wonderfully when you need to treat strings as integers.&lt;/p&gt;

&lt;p&gt;PS. Don&amp;rsquo;t forget step 3.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Stardates in Toto</title>
    <link rel="alternate" href="http://wuputah.com/2010/06/06/stardates-in-toto/"/>
    <id>http://wuputah.com/2010/06/06/stardates-in-toto/</id>
    <published>2010-06-06</published>
    <updated>2010-06-06</updated>
    <author>
      <name>Jonathan Dance</name>
    </author>
    <summary type="html">&lt;p&gt;I was messing around with the date and instead of going with &lt;em&gt;the 6th day of the 6th month of the year 2010; a glorious Sunday!&lt;/em&gt;, I decided to implement stardates. Don&amp;rsquo;t worry, you can still mouseover the stardate to get the Gregorian date, but I figured, who pays attention to the date anyway? Well, it might catch your attention now&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;I was messing around with the date and instead of going with &lt;em&gt;the 6th day of the 6th month of the year 2010; a glorious Sunday!&lt;/em&gt;, I decided to implement stardates. Don&amp;rsquo;t worry, you can still mouseover the stardate to get the Gregorian date, but I figured, who pays attention to the date anyway? Well, it might catch your attention now.&lt;/p&gt;

&lt;script src="http://gist.github.com/427294.js?file=stardates-in-toto.rb"&gt;&lt;/script&gt;


&lt;p&gt;For the first two digits, I use a somewhat unique approach amongst trekkies: instead of using years since 1900, I drop the leading digit just like we do with our centuries. Thus, instead of today being 110430.1, it&amp;rsquo;s simply 10430.1; this fits with the 5-digit years used in the series. Of course, my stardates won&amp;rsquo;t align with those in the show.&lt;/p&gt;

&lt;p&gt;The rest is the standard fractional year: there are 1000 stardates a year, so take the current day and divide it by the total number of days and multiply by 1000. Round to the nearest tenth. There&amp;rsquo;s 8.76 hours per star-day, and 52 minutes per 0.1 star-day. (Granted, toto doesn&amp;rsquo;t use time, just the date, so I&amp;rsquo;m using too many significant digits.)&lt;/p&gt;

&lt;p&gt;As an aside, you might be interested to know this tidbit about the Gregorian calendar:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;[The Gregorian calendar] was introduced by Pope Gregory XIII, after whom the calendar was named, by a decree signed on 24 February 1582. The need for the Gregorian reform stemmed from the fact that the Julian calendar system assumes time between vernal equinoxes is 365.25 days, when in fact it is about 11 minutes less. The accumulated error between these values was about 10 days when the reform was made, resulting in the equinox occurring on March 11 and moving steadily earlier in the calendar. Since the equinox was tied to the celebration of Easter, the reform in the calendar was undertaken by the Roman Catholic Church.&lt;sup&gt;&lt;a href="http://en.wikipedia.org/wiki/Gregorian_calendar"&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This was certainly an improvement, but now that we have standardized time, we also need &lt;a href="http://en.wikipedia.org/wiki/Leap_second"&gt;leap seconds&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>How to pronounce "wuputah"</title>
    <link rel="alternate" href="http://wuputah.com/2010/06/06/how-to-pronounce-wuputah/"/>
    <id>http://wuputah.com/2010/06/06/how-to-pronounce-wuputah/</id>
    <published>2010-06-06</published>
    <updated>2010-06-06</updated>
    <author>
      <name>Jonathan Dance</name>
    </author>
    <summary type="html">&lt;p&gt;Here&amp;rsquo;s the problem with posting this in text: ˈwoŏpətä. You all know &lt;a href="http://en.wikipedia.org/wiki/International_Phonetic_Alphabet"&gt;IPA&lt;/a&gt;, right? Me neither&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Here&amp;rsquo;s the problem with posting this in text: ˈwoŏpətä. You all know &lt;a href="http://en.wikipedia.org/wiki/International_Phonetic_Alphabet"&gt;IPA&lt;/a&gt;, right? Me neither.
Let me try to break it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first syllable, woŏp, is like &lt;em&gt;whoops&lt;/em&gt;, but it shouldn&amp;rsquo;t rhyme with &lt;em&gt;hoops&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The second syllable, ə, is a very common vowel sound in English, and is pronounced like &lt;em&gt;uhh&lt;/em&gt; as in &lt;em&gt;cup&lt;/em&gt;. I also sometime pronounce this syllable as ɛ, which is closer to &lt;em&gt;ehh&lt;/em&gt;, as in &lt;em&gt;bed&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The third syllable, tä, is pronounced as in the first syllable in &lt;em&gt;ta-ta!&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Emphasis is on the first syllable, so it&amp;rsquo;s &lt;em&gt;WHOOP-uh-ta&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You&amp;rsquo;re doing it wrong if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You pronounce &lt;em&gt;utah&lt;/em&gt;, as in the state.&lt;/li&gt;
&lt;li&gt;The first syllable doesn&amp;rsquo;t include the &lt;em&gt;p&lt;/em&gt;, and hence sounds like &lt;em&gt;woo-poo-tah&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  <entry>
    <title>count, size, and length: associations vs named scopes</title>
    <link rel="alternate" href="http://wuputah.com/2010/05/24/count-size-and-length-associations-vs-named-scopes/"/>
    <id>http://wuputah.com/2010/05/24/count-size-and-length-associations-vs-named-scopes/</id>
    <published>2010-05-24</published>
    <updated>2010-05-24</updated>
    <author>
      <name>Jonathan Dance</name>
    </author>
    <summary type="html">&lt;p&gt;I was looking into this today and it was a bit different&amp;mdash;and much more complex&amp;mdash;than what I expected, so I figured I&amp;rsquo;d pass on the results&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;I was looking into this today and it was a bit different&amp;mdash;and much more complex&amp;mdash;than what I expected, so I figured I&amp;rsquo;d pass on the results.
On an association:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;length&lt;/code&gt; forces the association to be loaded if it is not already, then checks the size of the array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;count&lt;/code&gt; always invokes a &lt;code&gt;COUNT()&lt;/code&gt; query, regardless of the state of the association (loaded or not). It does not take unsaved records into account, and does not respect active scopes (which is why named scope does not use this). The count is never cached by Rails, but would be cached by the Rails query cache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;size&lt;/code&gt;&amp;rsquo;s main difference is that it includes unsaved records in its result, but it can only do so if knows about them. Associations only know about records that are queued for saving when the parent object is saved, and it can only do so if called with &lt;code&gt;association.&amp;lt;&amp;lt;&lt;/code&gt; or &lt;code&gt;association.build&lt;/code&gt;. (These are the same cases as when a &lt;code&gt;counter_cache&lt;/code&gt; column is automatically updated; &lt;em&gt;caveat emptor&lt;/em&gt;.) &lt;code&gt;size&lt;/code&gt; can be more efficient than &lt;code&gt;length&lt;/code&gt; in some cases &amp;ndash; for &lt;code&gt;has_many&lt;/code&gt; and &lt;code&gt;has_many/has_one through&lt;/code&gt; associations, it takes advantage of &lt;code&gt;counter_cache&lt;/code&gt; columns or invokes a &lt;code&gt;COUNT()&lt;/code&gt; query. There is no optimization for HABTM associations.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This gets a bit trickier when you add named scopes into the mix: the results change because named scope has taken over some of the methods. To understand this, you must remember that calling a named scope creates a new &lt;code&gt;Scope&lt;/code&gt; object which wraps the upstream object. In addition to implementing the required querying magic, it provides a separate layer of caching entirely separate from the upstream object.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;length&lt;/code&gt; is not implemented by named scope, and so falls back to either the association&amp;rsquo;s implementation, which will work because the eventual &lt;code&gt;find(:all)&lt;/code&gt; will be scoped, or &lt;code&gt;Array#length&lt;/code&gt; if there is no association defined.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;count&lt;/code&gt; is not implemented by named scope, but does not send this method to the association&amp;rsquo;s implementation, as the result would be incorrect. It always invokes an SQL count by using &lt;code&gt;with_scope()&lt;/code&gt; and invoking the original count method on the class (defined by &lt;code&gt;ActiveRecord::Calculations&lt;/code&gt;) with the appropriate parameters. This is probably the most confusing of the 6 cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;size&lt;/code&gt; is implemented by named scopes, and either returns the length of the loaded array, or invokes an SQL count if it hasn&amp;rsquo;t been loaded in all cases. The association behavior of handling unsaved records is gone as well as any association-specific optimizations (or lack thereof).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Keep in mind that both object associations and named scopes can only cache objects internally if they&amp;rsquo;re the same instance (i.e. saved to a variable), so two otherwise identical named scopes/association calls will only be cached at the query cache level (whether by Rails or the database). &lt;code&gt;self&lt;/code&gt; often serves as this instance for an association when writing model code, but once you use a named scope, these are much more rarely cached, so &lt;code&gt;count&lt;/code&gt; is often the best choice if a named scope is involved. Otherwise, &lt;code&gt;size&lt;/code&gt; or &lt;code&gt;length&lt;/code&gt; may be faster, depending on the scenario, but it still requires a full association load before it can cache the size. However, if you&amp;rsquo;re using &lt;code&gt;counter_cache&lt;/code&gt;, you must use &lt;code&gt;size&lt;/code&gt; to take advantage of them (unless you read the counter attribute directly).&lt;/p&gt;

&lt;p&gt;Lastly, while &lt;code&gt;count&lt;/code&gt; is a good choice, you shouldn&amp;rsquo;t get in a habit of using it on everything. &lt;code&gt;Array#count&lt;/code&gt; was added in ruby 1.8.7 (and later). &lt;code&gt;String#count&lt;/code&gt; exists, but it takes a parameter and returns the count of the number of occurrences of characters (&lt;code&gt;'confused yet?'.count('ce')&lt;/code&gt; returns &lt;code&gt;3&lt;/code&gt;).&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Announcing a DNS tool without the bullshit</title>
    <link rel="alternate" href="http://wuputah.com/2010/02/20/announcing-a-dns-tool-without-the-bullshit/"/>
    <id>http://wuputah.com/2010/02/20/announcing-a-dns-tool-without-the-bullshit/</id>
    <published>2010-02-20</published>
    <updated>2010-02-20</updated>
    <author>
      <name>Jonathan Dance</name>
    </author>
    <summary type="html">&lt;p&gt;I&amp;rsquo;ve created a &lt;a href="http://dns.heroku.com/"&gt;simple DNS tool&lt;/a&gt; that allows you to easily link DNS results to share with others. Using a third-party tool is a great way to show that the DNS settings are not being affected by your local network, but most third-party tools are riddled with advertising and unclear tool names, with some even charging a membership to access some of their tools. My tool uses (and displays in the result) the command line used to generate the results instead. While not everyone will be familiar with these different commands, users can still experiment to learn and discover more about these valuable tools&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;I&amp;rsquo;ve created a &lt;a href="http://dns.heroku.com/"&gt;simple DNS tool&lt;/a&gt; that allows you to easily link DNS results to share with others. Using a third-party tool is a great way to show that the DNS settings are not being affected by your local network, but most third-party tools are riddled with advertising and unclear tool names, with some even charging a membership to access some of their tools. My tool uses (and displays in the result) the command line used to generate the results instead. While not everyone will be familiar with these different commands, users can still experiment to learn and discover more about these valuable tools.&lt;/p&gt;

&lt;p&gt;The tool is available at &lt;a href="http://dns.heroku.com/"&gt;dns.heroku.com&lt;/a&gt;. The site is written using the Sinatra framework and the &lt;a href="http://github.com/jdance/dns-tools"&gt;code is open source&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>ERD diagrams from Sequel Pro</title>
    <link rel="alternate" href="http://wuputah.com/2010/01/07/erd-diagrams-from-sequel-pro/"/>
    <id>http://wuputah.com/2010/01/07/erd-diagrams-from-sequel-pro/</id>
    <published>2010-01-07</published>
    <updated>2010-01-07</updated>
    <author>
      <name>Jonathan Dance</name>
    </author>
    <summary type="html">&lt;p&gt;If you need a diagram of your MySQL database and you&amp;rsquo;re on a Mac, generating an ERD diagram is quite easy &amp;ndash; and completely free. Sequel Pro can export Graphviz dot files, and then all you need is a few tools to create the diagram&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;If you need a diagram of your MySQL database and you&amp;rsquo;re on a Mac, generating an ERD diagram is quite easy &amp;ndash; and completely free. Sequel Pro can export Graphviz dot files, and then all you need is a few tools to create the diagram.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install graphviz from MacPorts via your Terminal:&lt;br /&gt;&lt;code&gt;sudo port install graphviz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Install &lt;a href="http://www.sequelpro.com/"&gt;Sequel Pro&lt;/a&gt;, run the app, connect to your MySQL server and open the database you&amp;rsquo;d like to diagram.&lt;/li&gt;
&lt;li&gt;Go to File &gt; Export &gt; Graphviz Dot file, and save the file somewhere convenient.&lt;/li&gt;
&lt;li&gt;Generate an SVG file of your diagram:&lt;br /&gt;&lt;code&gt;dot -Tsvg your_database.dot &amp;gt; your_database.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;You can open SVG files with Opera, Safari, Illustrator, etc, but you can generate a PNG file in a number of ways. You can try installing ImageMagick or libsrvg from MacPorts, or use Illustrator or Inkscape to open and convert the file.
&lt;strong&gt; ImageMagick: &lt;code&gt;convert your_database.svg your_database.png&lt;/code&gt;
&lt;/strong&gt; libsrvg: &lt;code&gt;cat your_database.svg | rsvg-convert -o your_database.png&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The result is a basic table-based ERD, but it&amp;rsquo;s not bad for a few minutes of your time.&lt;/p&gt;

&lt;p&gt;Thanks to the &lt;a href="http://github.com/finalist/geert"&gt;geert&lt;/a&gt; README for the introduction to this process.&lt;/p&gt;
</content>
  </entry>
</feed>

