<?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>John Myles White &#187; Ruby</title>
	<atom:link href="http://www.johnmyleswhite.com/notebook/category/programming/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.johnmyleswhite.com</link>
	<description>&#34;He who refuses to do arithmetic is doomed to talk nonsense.&#34;</description>
	<lastBuildDate>Wed, 26 Oct 2011 11:36:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Cleaning Up an iTunes Library with MacRuby</title>
		<link>http://www.johnmyleswhite.com/notebook/2009/11/20/cleaning-up-an-itunes-library-with-macruby/</link>
		<comments>http://www.johnmyleswhite.com/notebook/2009/11/20/cleaning-up-an-itunes-library-with-macruby/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 22:42:37 +0000</pubDate>
		<dc:creator>John Myles White</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.johnmyleswhite.com/?p=3625</guid>
		<description><![CDATA[For a little more than a year now, I&#8217;ve been meaning to write a script to rename all of the files in my iTunes library so that they&#8217;re in proper English title case. In large part, this project was inspired by reading John Gruber&#8217;s post about a Perl script that he&#8217;d written to convert text [...]]]></description>
			<content:encoded><![CDATA[<p>For a little more than a year now, I&#8217;ve been meaning to write a script to rename all of the files in my iTunes library so that they&#8217;re in proper English title case. In large part, this project was inspired by reading <a href="http://daringfireball.net/2008/05/title_case">John Gruber&#8217;s post</a> about a Perl script that he&#8217;d written to convert text strings into title case programmatically. After reading Gruber&#8217;s post, I grabbed a copy of <a href="http://github.com/samsouder/titlecase/tree/master/lib/">Sam Souder&#8217;s translation</a> of Gruber&#8217;s Title Case script into Ruby and set about trying to use it as part of a home-grown Ruby script to clean up my iTunes library. During my first pass, I tried to combine Sam&#8217;s convenient utility method with RubyCocoa to produce a script that could access the iTunes methods directly and rename my files automatically without editing the MP3 files directly. Unfortunately, the RubyCocoa documentation was too sparse at the time for me to figure out the relevant method calls to be making.</p>
<p>Thankfully, I spent some time this week reading the MacRuby documentation and realized in the process how to write my desired script. The results are now on <a href="http://github.com/johnmyleswhite/titlecase-itunes-tracks">GitHub</a>. The only original bit of code is below:</p>

<div class="wp_codebox"><table><tr id="p36252"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="code" id="p3625code2"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/macruby</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># We iterate over every track, stripping bounding whitespace and putting things into proper title case.</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'titlecase'</span>
&nbsp;
framework <span style="color:#996600;">'cocoa'</span>
&nbsp;
load_bridge_support_file <span style="color:#996600;">'ITunes.bridgesupport'</span>
&nbsp;
framework<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;ScriptingBridge&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
itunes = SBApplication.<span style="color:#9900CC;">applicationWithBundleIdentifier</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;com.apple.itunes&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
music_playlist_tracks = itunes.<span style="color:#9900CC;">sources</span>.<span style="color:#9900CC;">objectWithName</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Library&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">userPlaylists</span>.<span style="color:#9900CC;">objectWithName</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Music&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">fileTracks</span>
&nbsp;
music_playlist_tracks.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>track<span style="color:#006600; font-weight:bold;">|</span>
  old_artist = track.<span style="color:#9900CC;">artist</span>
  new_artist = track.<span style="color:#9900CC;">artist</span>.<span style="color:#9900CC;">strip</span>.<span style="color:#9900CC;">titlecase</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> old_artist != new_artist
    track.<span style="color:#9900CC;">artist</span> = new_artist
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Artist: #{old_artist} =&gt; #{new_artist}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  old_album = track.<span style="color:#9900CC;">album</span>
  new_album = track.<span style="color:#9900CC;">album</span>.<span style="color:#9900CC;">strip</span>.<span style="color:#9900CC;">titlecase</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> old_album != new_album
    track.<span style="color:#9900CC;">album</span> = new_album
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Album: #{old_album} =&gt; #{new_album}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  old_name = track.<span style="color:#9900CC;">name</span>
  new_name = track.<span style="color:#9900CC;">name</span>.<span style="color:#9900CC;">strip</span>.<span style="color:#9900CC;">titlecase</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> old_name != new_name
    track.<span style="color:#9900CC;">name</span> = new_name
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Name: #{old_name} =&gt; #{new_name}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Outside of this little snippet of MacRuby code that I had to write, I made two small changes to Sam Souder&#8217;s original code:</p>
<ol>
<li>I defined a <code>titlecase</code> method for the <code>NSString</code> class rather than the <code>String</code> class.</li>
<li>I pulled the list of English prepositions out of the main code and put it into a separate YAML file to make it easier for a non-programmer to edit the list.</li>
</ol>
<p>I know from experience with checking the results in a half gleeful and half paranoid frenzy that this code works properly on my own two machines, both of which are running MacRuby 0.5. That said, I won&#8217;t vouch for the reliability of this program in any way. If you notice any bugs, please do let me know, so that I can fix my own iTunes library with a revised version of the script.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnmyleswhite.com/notebook/2009/11/20/cleaning-up-an-itunes-library-with-macruby/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Why You Shouldn&#8217;t Be Clever</title>
		<link>http://www.johnmyleswhite.com/notebook/2008/08/20/why-you-shouldnt-be-clever/</link>
		<comments>http://www.johnmyleswhite.com/notebook/2008/08/20/why-you-shouldnt-be-clever/#comments</comments>
		<pubDate>Wed, 20 Aug 2008 10:53:21 +0000</pubDate>
		<dc:creator>John Myles White</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.johnmyleswhite.com/?p=3092</guid>
		<description><![CDATA[Today I started reading the Ruby Snips website, which has a pretty good sample of interesting snippets of Ruby code on it. I was particularly intrigued by the following snippet from a post on Prime Numbers dating back to March 23rd, 2007: 1 2 3 4 5 class Fixnum def prime? &#40;'1' * self&#41; !~ [...]]]></description>
			<content:encoded><![CDATA[<p>Today I started reading the <a href="http://rubysnips.com">Ruby Snips</a> website, which has a pretty good sample of interesting snippets of Ruby code on it. I was particularly intrigued by the following snippet from a post on <a href="http://rubysnips.com/prime-mixin">Prime Numbers</a> dating back to March 23rd, 2007:</p>

<div class="wp_codebox"><table><tr id="p30926"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p3092code6"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#CC00FF; font-weight:bold;">Fixnum</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> prime?
    <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'1'</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#0000FF; font-weight:bold;">self</span><span style="color:#006600; font-weight:bold;">&#41;</span> !~ <span style="color:#006600; font-weight:bold;">/</span>^<span style="color:#006666;">1</span>?$<span style="color:#006600; font-weight:bold;">|</span>^<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">11</span><span style="color:#006600; font-weight:bold;">+</span>?<span style="color:#006600; font-weight:bold;">&#41;</span>\<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">+</span>$<span style="color:#006600; font-weight:bold;">/</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>At first, I was convinced this code was broken. Before I had given much thought to the algorithm, I was ready to assume that the &#8220;prime?&#8221; name was a misnomer: I assumed the code was actually testing for members of a specific class of palindromes. After a minute or two, I pieced together what was really happening when testing a number:</p>
<ol>
<li>The number, n, is expanded into a string of 1&#8242;s of length n.</li>
<li>The string of 1&#8242;s is testing using a regex with back-references that finds the presence of a repeated divisor, a technique that works because a string of length a * b = n is composed of b copies of a string of length a.</li>
</ol>
<p>At that point, I began to marvel at the simplicity of the algorithm relative to the obscurity of the code. And while I was so amazed by this, it occurred to me: this is an absolutely terrible way to test for primality. Because you have no control over the loop bounds for the regex, you effectively test every number up to n as a possible divisor if n is a prime. But you really only need to test up to the square root of n to determine if n is prime. So your code runs for the square of the time it should run. And the expansion of n into a string, at least theoretically, requires exponentially more space than an integer expressed in binary would. This seemed like one of the worst possible ways to test for primality I had ever seen.</p>
<p>Still, I wanted to verify this empirically as well as theoretically, so I typed in</p>

<div class="wp_codebox"><table><tr id="p30927"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p3092code7"><pre class="ruby" style="font-family:monospace;"><span style="color:#006666;">399839483</span>.<span style="color:#9900CC;">prime</span>?</pre></td></tr></table></div>

<p>during an IRB session. The CPU and memory usage were absurd for a primality test on such a small number. I didn&#8217;t even bother letting the code complete after a few seconds of the watching interpreter hanging there, silently wasting CPU cycles. In contrast, the simpler, clearer code,</p>

<div class="wp_codebox"><table><tr id="p30928"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p3092code8"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#CC00FF; font-weight:bold;">Fixnum</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> prime?
    <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2</span>..<span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">sqrt</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">self</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_i</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>i<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> i <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">self</span> <span style="color:#006600; font-weight:bold;">/</span> i<span style="color:#006600; font-weight:bold;">&#41;</span> == <span style="color:#0000FF; font-weight:bold;">self</span>
        <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">true</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>runs fairly quickly.</p>
<p>The lesson I think everyone should take from this is a simple one: don&#8217;t be clever when writing code. At the very least, don&#8217;t be clever in the way the author of this snippet was. Your code is likely to end up being unclear, slow and wasteful with memory.</p>
<p>Perhaps I should be clearer about the problems of cleverness. Clever code is a mistake; clever algorithms are wonderful. Quick sort is a clever algorithm that always confuses me until I think carefully about it &#8212; and then I marvel at its superiority over other less efficient sorting algorithms; this snippet is a mediocre algorithm written in a style of code that&#8217;s needlessly confusing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnmyleswhite.com/notebook/2008/08/20/why-you-shouldnt-be-clever/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.324 seconds -->

