<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>The Hippy Hacker</title>
    <link>http://evan.tiggerpalace.com/rss/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>On spreading heavenly glory</description>
    
    
        <item>
          <title>RVM + Bundler + RubyMine</title>
          <description>&lt;p&gt;On my current project, we needed to be able to use RVM with Bundler but we want access to our bundled gems from Rubymine.&lt;/p&gt;

&lt;p&gt;You&amp;#8217;re going to want to write an alias in your .bashrc/.zshrc/.&lt;em&gt;whatever&lt;/em&gt;shrc for this one. You can use most of the below:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export PROJECT_PATH=the_path_to_your_Rails_project_using_bundler_goes_here
alias rubymine=&quot;rvm ruby-1.8.6-tv1_8_6_287 ;\
export GEM_HOME=#{PROJECT_PATH}/vendor/bundler_gems/ruby/1.8;\
export GEM_PATH=${GEM_HOME};/Applications/RubyMine\ 2.0.1.app/Contents/MacOS/rubymine&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What we&amp;#8217;re doing here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We then override the gem repo to point to our bundled gems (which are conveniently formatted as a gem repo)&lt;/li&gt;
&lt;li&gt;Then we fire up Ruby Mine with the above environment (Thanks to Brennan Dunn here).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now close and reopen your shell.&lt;/p&gt;

&lt;p&gt;From there, you go into RubyMine&amp;#8217;s settings, click on &amp;#8220;Add SDK&amp;#8221;&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;width: 100%&quot; src=&quot;http://img.skitch.com/20100129-bgwsh6pnj4kd3pk8pnuueybmuf.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&amp;#8230; unhide the hidden directories like so&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://img.skitch.com/20100129-gir3rrwneykuxra1e4u2868f2e.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&amp;#8230; then navigate to your Ruby VM and hit OK:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://img.skitch.com/20100129-bt1ycd7w6e8egmy5awys5xpfbk.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;Voila!&lt;/p&gt;</description>
          <pubDate>Fri, 29 Jan 2010 14:09:27 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/01/29/rvm-bundler-rubymine/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/01/29/rvm-bundler-rubymine/</link>
        </item>
    
        <item>
          <title>Mocking mocking (or "Why I am learning to hate isolating the unit under test")</title>
          <description>&lt;p&gt;Mocking basically sucks.&lt;/p&gt;

&lt;p&gt;There.  I said it.&lt;/p&gt;

&lt;p&gt;Using mocks in your tests almost always results in fragile tests.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;h2&gt;A case against mocking&lt;/h2&gt;

&lt;p&gt;Let&amp;#8217;s say that you&amp;#8217;re working on a hypothetical (simplified) financial application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class AccountTest &amp;lt; ActiveSupport::TestCase
  setup do
    @balance = 42.00
    @account = factory_to_create_a_test_account :with_balance =&amp;gt; @balance
    @mock_bank_manager = mock(BankManager)
  end

  def test_overdrawing_account_sends_notification
    @mock_manager.expects(:notify_of, :overdrawn_account, :amount =&amp;gt; 1)
    @account.withdraw(@balance + 1)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above example is attempting to illustrate how mocks can be useful for specifying a causal relationship.  &amp;#8220;Overdrawing the account&amp;#8221; results in &amp;#8220;notifying the bank manager of the amount over balance&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Mocking seems like such a natural and even expressive way to design an API.  It&amp;#8217;s, quite literally, behavior driven development: your tests/specifications, where you are mocking the API, are helping you design the API itself!  That&amp;#8217;s terrific.&lt;/p&gt;

&lt;p&gt;So let&amp;#8217;s pretend that, like a good TDDer, I&amp;#8217;ve gone and implemented the BankManager class.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class BankManager
  def notify_of(event_type, options = {})
    case event_type:
    when :notify_of
      # send the notification
    when ...
      ...
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Perhaps I even wrote a test/spec for &lt;em&gt;BankManager&lt;/em&gt;.  But, then, in a fit of refactoring rage, I decide that I must have a second argument to &lt;em&gt;BankManager#notify_of&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class BankManager
  def notify_of(event_type, account, options = {})
    case event_type:
    when :notify_of
      # send the notification
    when ...
      ...
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Our old friend &lt;em&gt;AccountTest&lt;/em&gt; above will still pass because it&amp;#8217;s using a mock.  However, the API to &lt;em&gt;BankManager&lt;/em&gt; has changed; we want &lt;em&gt;AccountTest#test_overdrawing_account_sends_notification&lt;/em&gt; to fail!&lt;/p&gt;

&lt;p&gt;So, in short, mocking an internal API is a recipe for pain and (Ni!) woe.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After you implement the API, you still have mocks lying around in the test that helped you mock out the API design in the first place.  This test is now fragile.  &lt;strong&gt;If the API changes, the tests containing the mocks will still pass!&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;You can double back and replace those mocks with actual calls to the API &lt;strong&gt;but you just made more work for yourself&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Where mocking makes sense&lt;/h2&gt;

&lt;p&gt;In my experience, the only place that mocks have served me at all well is when I&amp;#8217;m interfacing with an external service from a unit test.  I certainly don&amp;#8217;t want my unit test invoking services beyond my own system.  I usually write an interface layer between my business logic and the external service.  In my unit tests, I then mock the interface layer only.  Testing integration with the external service, predictably, becomes a chore solely for the integration test.&lt;/p&gt;

&lt;h2&gt;We have the technology. We can rebuild it.&lt;/h2&gt;

&lt;p&gt;I believe that there is a better path: one that will let us have our mocking cake but now force us to eat brittle tests.  I&amp;#8217;ve had some ideas about this on the back burner for about a year now.  However, I hope to have something concrete to discuss in a few weeks.&lt;/p&gt;</description>
          <pubDate>Mon, 25 Jan 2010 20:47:11 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/01/25/mocking-mocking-or-why-i-am-learning-to-hate-isolating-the-unit-under-test/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/01/25/mocking-mocking-or-why-i-am-learning-to-hate-isolating-the-unit-under-test/</link>
        </item>
    
        <item>
          <title>On Craftsmanship and Practice</title>
          <description>&lt;p&gt;Reading a passage from the &amp;#8220;E-Myth Contractor&amp;#8221; got me to thinking about how we practice (when we practice) our skills that we apply on a regular basis.&lt;/p&gt;

&lt;p&gt;When we practice our craft, performing &amp;#8220;katas&amp;#8221; as they have come to be called, why do we perform them on arcane problems such as Langdon&amp;#8217;s Ant or Conway&amp;#8217;s Game of Life?&lt;/p&gt;

&lt;p&gt;You don&amp;#8217;t encounter these problems in your day-to-day work.&lt;/p&gt;

&lt;p&gt;I agree that solving these problems a few times over may improve your overall problem solving skills.  But that&amp;#8217;s only true until you settle on an optimal implementation.&lt;/p&gt;

&lt;p&gt;Given the above then there seems to be greater value in routinely exercising what we consider routine.  &lt;/p&gt;

&lt;p&gt;If I can build a signup, login,and forgotten password capability, a text-based search across multiple model objects, or a recurring payment ecommerce system rapidly and reliably, isn&amp;#8217;t that more valuable to most customers than finding clever ways to move a hypothetical ant around a grid?  These are the sorts of tasks that we routinely encounter in our work.  Or perhaps not.  Maybe you typically employ a CMS to expedite these chores.  This is because craftsmen use tools to work in their craft.  &lt;/p&gt;

&lt;p&gt;So you should be practicing with those same tools.&lt;/p&gt;

&lt;p&gt;If you have a good toolbox, full of tools ideally suited to solving problems your typical problems, then these tools are your weapons.  Each tool probably does certain things better than others.  You should then practice &amp;#8220;weapon katas.&amp;#8221;&lt;/p&gt;

&lt;p&gt;You should master your tools.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s assume for a moment that your current project/product/service du jour is not a unique and special snowflake.  If what we do is a craft, then repetition and understanding of the routine tasks should enable us to deliver faster, more reliably, and more consistently.&lt;/p&gt;

&lt;p&gt;Perhaps studying Langdon&amp;#8217;s and Conway&amp;#8217;s, ultimately, is a study of basic forms, i.e. this is how I BDD something different.  Once we grasp these basic forms, it is then time to move on to how we employ our tools, i.e., our favorite plugins and gems, until we&amp;#8217;ve mastered those as well.&lt;/p&gt;

&lt;p&gt;Doesn&amp;#8217;t this make us better craftsmen?&lt;/p&gt;

&lt;p&gt;&amp;#8230; that is, until someone introduces a better weapon.&lt;/p&gt;

&lt;p&gt;I freely admit that this is not how I currently practice.  I feel that my basic form is solid.  Howver, I admit, I do need to better acquaint myself with my weapons.  As of now, this is what I intend to practice.  I will try to report on how it goes.&lt;/p&gt;</description>
          <pubDate>Mon, 11 Jan 2010 23:26:06 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/01/11/on-craftsmanship-and-practice/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/01/11/on-craftsmanship-and-practice/</link>
        </item>
    
        <item>
          <title>Shouldn't developer tools be for developers first?</title>
          <description>&lt;p&gt;As (I believe) Jonas Nicklas pointed out in response to &lt;a href=&quot;http://robots.thoughtbot.com/post/304910866/history-ruby-integration-testing&quot;&gt;ThoughtBot&amp;#8217;s post on integration testing&lt;/a&gt;, &lt;a href=&quot;http://cukes.info/&quot;&gt;Cucumber&lt;/a&gt; is largely ineffectual in a project until you build up a library of domain-specific matchers and their respective code blocks.&lt;/p&gt;

&lt;p&gt;What this represents is external domain-specific language design via regular expression.&lt;/p&gt;

&lt;p&gt;The reasonable use of this is to facilitate the expression of desired behaviors by non-developers. For example, I have tell of organizations where QA people, for instance, write automated acceptance tests using Cucumber.&lt;/p&gt;

&lt;p&gt;I share the Cucumber team&amp;#8217;s belief that customer communication is essential. That&amp;#8217;s facilitated, in Cucumber, by writing features in plain text (Gherkin). Cost is saved when issues are addressed in specs versus code &amp;#8211; likely why the waterfall model was so popular at first. It&amp;#8217;s just common sense. &lt;/p&gt;

&lt;p&gt;It&amp;#8217;s a form of risk management.&lt;/p&gt;

&lt;p&gt;Every feature goes hand in hand with the risk that it will fail to be implemented to meet customer expectation. A risk becomes an issue, in this case, when a feature is implemented in a fashion differing from the customer&amp;#8217;s expectation. The earlier that risk is mitigated, the less money/effort/time is wasted on the project handling risks that manifest into issues.&lt;/p&gt;

&lt;p&gt;One way of mitigating that risk is to communicate to the customer how that feature will behave in the language of the customer&amp;#8217;s domain.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://coulda.tiggerpalace.com&quot;&gt;Coulda&lt;/a&gt; solves the same problem. It has a rake task for marshaling the Feature, contained Scenarios, and all of the statements (Givens/Whens/Thens) into plain text.&lt;/p&gt;

&lt;p&gt;However, Coulda shares many of the considerations Dan cites above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;#8220;Features&amp;#8221; are just Test::Unit::TestCases &lt;/li&gt;
&lt;li&gt;&amp;#8220;Scenarios&amp;#8221; are just tests&lt;/li&gt;
&lt;li&gt;&amp;#8220;Statements&amp;#8221; (Given/When/Then) are just steps taken within a particular test&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I use Coulda on a project (I&amp;#8217;ve used it on the job at this point), I don&amp;#8217;t start with the intent of building a language. I know that I probably will, because I have, as my work progresses. I start by writing pending Features, pending Scenarios, pending Statements, and then I begin putting flesh on the bones. I refactor my tests. When I encounter duplication within a Feature, I Extract Method. When I encounter duplication across Features, I Extract Module (I&amp;#8217;m guessing that&amp;#8217;s in Ruby Refactoring but you likely get the intent: I create a module, move my method into the module, and include the module in my Coulda Features), and so on.&lt;/p&gt;

&lt;p&gt;What bothers me so much about so many libraries, in general, is that they try to solve all of my problems. &lt;/p&gt;

&lt;p&gt;That&amp;#8217;s great but I don&amp;#8217;t want that. Just like I don&amp;#8217;t want to buy a car with a 500hp engine because I simply won&amp;#8217;t need it. I just need a car.&lt;/p&gt;

&lt;p&gt;So I kept Coulda simple. If you need more, great, then write it! If you find that you need the same thing repeatedly, great, make a new gem from it!&lt;/p&gt;

&lt;p&gt;Automate what you need to do often. If you have an edge case, keep it out of your libraries, thank you! My brain has a hard enough time absorbing the ever-increasing size of the Rails API (and this from a guy who worked in J2EE hell for years).&lt;/p&gt;

&lt;p&gt;Remember, these are the kinds of practices that gave us Rails. Don&amp;#8217;t try to solve everyone&amp;#8217;s problems. Focus on the frequently recurring problems. Scratch your own itch (I did!).&lt;/p&gt;</description>
          <pubDate>Mon, 04 Jan 2010 22:45:18 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/01/04/shouldnt-developer-tools-be-for-developers-first/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/01/04/shouldnt-developer-tools-be-for-developers-first/</link>
        </item>
    
        <item>
          <title>"Grid" layout in Android</title>
          <description>&lt;p&gt;You know how your mother (or, in this case, your front end developer friends/colleagues) always say &amp;#8220;never use a table for formatting unless you&amp;#8217;re really making a table&amp;#8221;&lt;/p&gt;

&lt;p&gt;That may be true for HTML.  However, it doesn&amp;#8217;t seem to hold when you&amp;#8217;re working with Google&amp;#8217;s Android.&lt;/p&gt;

&lt;p&gt;You see, now that I have a shiny new Motorola Droid (see my previous post), I&amp;#8217;m now working with Android in my spare time.&lt;/p&gt;

&lt;p&gt;I was struggling with using Android&amp;#8217;s UI XML to layout a simple login page.  And I was going nuts.&lt;/p&gt;

&lt;p&gt;I was trying to use A &lt;em&gt;LinearLayout&lt;/em&gt; containing several &lt;em&gt;RelativeLayout&lt;/em&gt;s, one for each row.  &amp;#8220;Row&amp;#8221; should have been the clue.&lt;/p&gt;

&lt;p&gt;After poking through the PragProg &lt;strong&gt;Hello, Android&lt;/strong&gt; book for a bit, I found an example later in the book that used a &lt;em&gt;TableLayout&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That was my aha moment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;TableLayout&lt;/em&gt; is pretty simple to use.  It is designed to contain several &lt;em&gt;TableRow&lt;/em&gt; (a &lt;em&gt;ViewGroup&lt;/em&gt; child as are other &lt;em&gt;*Layouts&lt;/em&gt;).  A &lt;em&gt;TableRow&lt;/em&gt; looks thus:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  &lt;pre&gt;
&amp;lt;TableLayout
  android:layout&lt;em&gt;width=&quot;fill&lt;/em&gt;parent&quot; 
  android:layout&lt;em&gt;height=&quot;wrap&lt;/em&gt;content&quot;
  android:stretchColumns=&quot;1&quot; 
  android:padding=&quot;10dip&quot; &amp;gt;
  &amp;lt;TableRow
    android:layout_marginBottom=&quot;10dip&quot;&amp;gt;
    &amp;lt;TextView
      android:id=&quot;@+id/login_label&quot;&lt;br/&gt;
      android:layout&lt;em&gt;height=&quot;wrap&lt;/em&gt;content&quot; 
      android:text=&quot;@string/login&quot; /&amp;gt;
    &amp;lt;EditText
      android:id=&quot;@+id/login_field&quot; 
      android:layout&lt;em&gt;width=&quot;fill&lt;/em&gt;parent&quot; 
      android:layout&lt;em&gt;height=&quot;wrap&lt;/em&gt;content&quot; 
      android:lines=&quot;1&quot; /&amp;gt;
  &amp;lt;/TableRow&amp;gt;
  &amp;lt;TableRow
    android:layout_marginBottom=&quot;10dip&quot;&amp;gt;
    &amp;lt;TextView
      android:id=&quot;@+id/password_label&quot; 
      android:layout&lt;em&gt;height=&quot;wrap&lt;/em&gt;content&quot; 
      android:text=&quot;@string/password&quot; /&amp;gt;
    &amp;lt;EditText
      android:id=&quot;@+id/password_field&quot; 
      android:layout&lt;em&gt;width=&quot;fill&lt;/em&gt;parent&quot; 
      android:layout&lt;em&gt;height=&quot;wrap&lt;/em&gt;content&quot; 
      android:lines=&quot;1&quot; /&amp;gt;
  &amp;lt;/TableRow&amp;gt;&lt;br/&gt;
&amp;lt;/TableLayout&amp;gt;
  &lt;/pre&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;android:layout_marginBottom&lt;/em&gt; attributes on the &lt;em&gt;TableRow&lt;/em&gt;s are entirely optional.  However, odds are that you will want to add some sort of formatting to your &lt;em&gt;TableRow&lt;/em&gt;s.&lt;/p&gt;

&lt;p&gt;Incidentally, there may be DRYer ways of representing rows in Android XML (i.e., something similar to a Rails partial); however, admittedly, I&amp;#8217;m still very much learning Android.&lt;/p&gt;</description>
          <pubDate>Sat, 28 Nov 2009 15:09:25 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2009/11/28/grid-layout-in-android/</guid>
          <link>http://evan.tiggerpalace.com/articles/2009/11/28/grid-layout-in-android/</link>
        </item>
    
        <item>
          <title>A brief review of the Motorola/Verizon Droid</title>
          <description>&lt;p&gt;On the last leg of the return from my road trip, I picked up a Droid from the Best Buy in Salisbury, MD. &lt;img src=&quot;/motorola-droid-side.jpg&quot; style=&quot;float: left; width: 50%; height: 50%;&quot;/&gt;&lt;/p&gt;

&lt;p&gt;In a nutshell: I love it.&lt;/p&gt;

&lt;p&gt;And, yes, more than an iPhone.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;h2&gt;The Device&lt;/h2&gt;

&lt;p&gt;From photos, I had thought that the Droid was just an ugly brick.  In the &amp;#8220;flesh&amp;#8221;, it&amp;#8217;s more like an F-22: oblique surfaces but with rounded edges.  This results in a device that is comfortable to hold with or without the keyboard open (which, sadly, I could not say the same of my former Palm Pre; it could be painful to type upon).&lt;/p&gt;

&lt;p&gt;The Droid is a heft to it.  It feels like it means business.  And it&amp;#8217;s solid: no flimsy plastic casing here that gives when you squeeze it.&lt;/p&gt;

&lt;p&gt;The keyboard slides open easily enough, snapping in place when fully open.  However, there are no springs involved; the slider requires gentle but constant pressure.  The keyboard itself is spacious enough.  However, I haven&amp;#8217;t seen keys like this since the old Timex Sinclair home computer.  The keyboard is covered in a slightly flexible but thick sealed plastic.  The keys are only barely raised above the slider with the actuators themselves set in the slider.&lt;/p&gt;

&lt;p&gt;While the keyboard takes some getting used to, I can tell that my typing is already improving.&lt;/p&gt;

&lt;p&gt;The speaker on this thing is amazing.  In fact, audio, overall, is lovely.  But the speaker is simply the loudest that I&amp;#8217;ve heard in any smartphone &amp;#8211; even louder than the Pre.&lt;/p&gt;

&lt;p&gt;Oh, and the device uses micro USB.  I had never seen this connector before the Amazon Kindle.  However, it seems to be becoming more common on contemporary smart phones.&lt;/p&gt;

&lt;h2&gt;The Software&lt;/h2&gt;

&lt;p&gt;Speaking of keyboards, Android 2.0 comes with a soft keyboard.  However, I&amp;#8217;m sad to say that this is not an iPhone keyboard.  I could type lightning fast on the iPhone.  When I start to work up a head of steam on the Droid&amp;#8217;s virtual keyboard, I notice that the virtual keyboard seems to acknowledge that I&amp;#8217;m tapping keys; however, the letters themselves do not always make it into the text area that I&amp;#8217;m editing.  However, I don&amp;#8217;t encounter this problem when using the physical keyboard.&lt;/p&gt;

&lt;p&gt;Do I really need to tell you about Google Navigation?  It&amp;#8217;s awesome.  Jaw droppingly awesome.&lt;/p&gt;

&lt;p&gt;Otherwise, it&amp;#8217;s an Android phone.  However, that is not a bad thing, as it happens.  &lt;/p&gt;

&lt;h2&gt;Customizing the Droid&lt;/h2&gt;

&lt;p&gt;Unlike Apple, neither Google nor Verizon put much in the way of restrictions on the Droid.  Background apps?  Check (although watch that battery, folks).  Re-skinnable user interface?  Check.  Crappy Facebook app?  Check (woops. Nice one, Facebook).&lt;/p&gt;

&lt;h2&gt;Quirks&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;ve had a few minor problems with the Droid in the first 48 hours.&lt;/p&gt;

&lt;p&gt;Occasionally, the Droid has a difficult time connecting to my wifi network. That may be because I run an 802.11g network with a range extender; the Droid may occasionally have a difficult time selecting which access point to use.&lt;/p&gt;

&lt;p&gt;Also, this morning, I noticed that the devices speaker volume dropped significantly.  Rebooting the phone solved the problem.&lt;/p&gt;

&lt;p&gt;A few times, I&amp;#8217;ve had an app randomly open unbidden while I was in another app.  The android revolution begins?  At least it didn&amp;#8217;t a suction cup, an eye stalk, and intone, &amp;#8220;Exterminate!&amp;#8221;&lt;/p&gt;

&lt;p&gt;And then there&amp;#8217;s the virtual keyboard issue that I mentioned above.&lt;/p&gt;

&lt;h2&gt;Overall&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;m extremely pleased.  Yes, so pleased that I don&amp;#8217;t miss my iPhone (although I do miss Cultured Code&amp;#8217;s Things).&lt;/p&gt;

&lt;p&gt;Now if only the API wasn&amp;#8217;t pure Java and/or the Dalvik team would fix &lt;a href=&quot;http://code.google.com/p/android/issues/detail?id=3005&quot;&gt;this damn bug so that I could write Android apps in JRuby&lt;/a&gt; (or pick your interpreted JVM language of choice that relies on reflection to get anything done).&lt;/p&gt;

&lt;p&gt;In the meantime, it&amp;#8217;s time to learn some Scala&amp;#8230;&lt;/p&gt;</description>
          <pubDate>Sun, 08 Nov 2009 14:37:25 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2009/11/08/a-brief-review-of-the-motorolaverizon-droid/</guid>
          <link>http://evan.tiggerpalace.com/articles/2009/11/08/a-brief-review-of-the-motorolaverizon-droid/</link>
        </item>
    
        <item>
          <title>A meditation for the (aspiring) Rubyist</title>
          <description>&lt;p&gt;You&amp;#8217;re new to programming.  You&amp;#8217;ve got an idea that you&amp;#8217;re aching to make manifest.  You&amp;#8217;ve heard of this awesome Ruby on Rails thing.  You&amp;#8217;ve even bought &lt;em&gt;Agile Web Development with Rails [AWDR]&lt;/em&gt;.  Now what?&lt;/p&gt;

&lt;p&gt;Yes, you can probably take &lt;em&gt;AWDR&lt;/em&gt; and try to use Rails right away.  However, if you want to do anything the least bit different from the examples in &lt;em&gt;AWDR&lt;/em&gt;, you&amp;#8217;re in for some trouble.&lt;/p&gt;

&lt;p&gt;Hold your horses there, cowboy.  You&amp;#8217;re just starting to learn how to walk, someone gives you an airplane, and you&amp;#8217;re going to fly it?&lt;/p&gt;

&lt;p&gt;Bad idea.&lt;/p&gt;

&lt;p&gt;So where to begin?&lt;/p&gt;

&lt;h2&gt;First learn some Ruby&lt;/h2&gt;

&lt;p&gt;Over the past couple of months, I&amp;#8217;ve given several informal introduction to Ruby classes &amp;#8211; sometimes on a one-on-one basis and other times for small groups of five to ten people.  In that time, I&amp;#8217;ve received the same good question a couple of times: can you point me at a few good books and or blogs to read that will help get me started?&lt;/p&gt;

&lt;p&gt;Well, maybe.  The Pragmatic Programmers offer a book called &lt;em&gt;Learn to Program&lt;/em&gt; which, as it happens, uses Ruby as its language of choice.  Lacking firsthand knowledge of the book, I&amp;#8217;m a little hard-pressed to recommend it.&lt;/p&gt;

&lt;p&gt;Most of the technical books that I consume are targeted at programmers with at least a modicum of programming experience in some language.  Even the the &amp;#8220;Pickaxe&amp;#8221; or the O&amp;#8217;Reilly Matz-Flannigan (sp?) Ruby books are really aimed at, at a minimum, the somewhat experienced programmer.&lt;/p&gt;

&lt;p&gt;Besides, we learn by doing, not reading.  This is why several small businesses offer Ruby training.  However, training is expensive. It&amp;#8217;s short.  It&amp;#8217;s chock full of knowledge.  And if you don&amp;#8217;t use that knowledge right away, you lose it before it can become experience.&lt;/p&gt;

&lt;p&gt;Where&amp;#8217;s an aspiring Rails/Ruby developer to turn?&lt;/p&gt;

&lt;h2&gt;Meditate on it&lt;/h2&gt;

&lt;p&gt;Jim Weirich created a wonderful teaching tool called the &lt;a href=&quot;http://github.com/edgecase/ruby_koans&quot;&gt;Ruby Koans&lt;/a&gt;.  The Koans come complete with the simple instructions necessary to execute them.  Learning comes from solving each tiny problem, one after another, that Jim presents along the path.&lt;/p&gt;

&lt;p&gt;While I haven&amp;#8217;t discussed the Koans with Jim (maybe at Scottish Ruby Conf next year), I believe that the Koans may have been initially aimed at rounding out experienced Rubyists. However, I&amp;#8217;ve found that they are so simple yet so informative that I recommend them to nearly every Rubyist, beginner and otherwise.&lt;/p&gt;

&lt;p&gt;A side-effect and bonus resulting from the Koans being hosted on Github: several people who have completed the Koans have posted their work on Github as well.  If you get stuck, you&amp;#8217;ve already rifled through your &amp;#8220;Pickaxe&amp;#8221; or O&amp;#8217;Reilly Ruby book, and are pulling your hair out in frustration, you can look at how someone else solved the particular Koan.&lt;/p&gt;

&lt;p&gt;Just be sure to meditate on those easily acquired answers.&lt;/p&gt;</description>
          <pubDate>Sat, 07 Nov 2009 17:56:04 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2009/11/07/a-meditation-for-the-aspiring-rubyist/</guid>
          <link>http://evan.tiggerpalace.com/articles/2009/11/07/a-meditation-for-the-aspiring-rubyist/</link>
        </item>
    
        <item>
          <title>Playing with Proc#bind</title>
          <description>&lt;p&gt;When I write internal DSLs in Ruby, I tend to do so by leveraging &lt;em&gt;Object#instance_eval&lt;/em&gt;.  &lt;em&gt;#instance_eval&lt;/em&gt; is powerful because it&amp;#8217;s yet another way that you can repoint &lt;em&gt;self&lt;/em&gt; in Ruby.  &lt;em&gt;Object#instance_eval&lt;/em&gt; executes its supplied Proc in the context of the calling &lt;em&gt;Object&lt;/em&gt;  Below is a simple example.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  &lt;pre&gt;
  def car(&amp;amp;block)
    # self is &quot;main&quot; (an Object) here
    c = Car.new
    # self refers to Car instance when Proc is evaluated on the line below
    c.instance&lt;em&gt;eval(&amp;amp;block) if block&lt;/em&gt;given?
    c
  end&lt;/p&gt;

&lt;p&gt;class Car&lt;br/&gt;
    def make(v); @make = v; end
    def model(v); @model = v; end
    def engine(v); @engine = v; end
  end&lt;/p&gt;

&lt;p&gt;car do
    make &quot;Ford&quot;
    model &quot;Fusion&quot;
    engine :piece_of_crap
  end
  &lt;/pre&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You could implement the same code by replacing &lt;em&gt;Object#instance_eval&lt;/em&gt; with calls to &lt;em&gt;Proc#bind&lt;/em&gt; as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  &lt;pre&gt;
  def car(&amp;amp;block)
    # self is &quot;main&quot; (an Object) here
    c = Car.new
    # self refers to Car instance when Proc is evaluated on the line below
    block.bind(c).call if block_given?
    c
  end
  &lt;/pre&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Remember, &lt;em&gt;Proc&lt;/em&gt;s are also closures.  That is, they take the context within which they were created along with them.  For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  &lt;pre&gt;
  def make_incrementer
    x = 0
    Proc.new { puts self; x += 1}
  end&lt;/p&gt;

&lt;p&gt;inc = make_incrementer
  # Will print 1 to 5 interleaved with &quot;main&quot;
  5.times { puts inc.call }
  &lt;/pre&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&amp;#8230; gives us &amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  &lt;pre&gt;
  # &gt;&gt; main
  # &gt;&gt; 1
  # &gt;&gt; main
  # &gt;&gt; 2
  # &gt;&gt; main
  # &gt;&gt; 3
  # &gt;&gt; main
  # &gt;&gt; 4
  # &gt;&gt; main
  # &gt;&gt; 5
  &lt;/pre&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Wherever you pass that Proc, when you call it, &lt;em&gt;puts self&lt;/em&gt; would always say &lt;em&gt;main&lt;/em&gt; (which is just the &amp;#8220;root&amp;#8221; &lt;em&gt;Object&lt;/em&gt; of the Ruby interpreter).&lt;/p&gt;

&lt;p&gt;So now we add the following code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  &lt;pre&gt;
  class Foo
  end    &lt;/p&gt;

&lt;p&gt;foo = Foo.new
  rebound_inc = inc.bind(foo)&lt;/p&gt;

&lt;p&gt;5.times { puts rebound_inc.call }
  &lt;/pre&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We didn&amp;#8217;t change the &lt;em&gt;Proc&lt;/em&gt;.  We just created a &lt;em&gt;Method&lt;/em&gt;, &lt;em&gt;rebound_inc&lt;/em&gt;, where &lt;em&gt;self&lt;/em&gt; now points to our instance of &lt;em&gt;Foo&lt;/em&gt;_.  So our code, with the above additions, when executed, now returns:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  &lt;pre&gt;
    # &gt;&gt; main
    # &gt;&gt; 1
    # &gt;&gt; main
    # &gt;&gt; 2
    # &gt;&gt; main
    # &gt;&gt; 3
    # &gt;&gt; main
    # &gt;&gt; 4
    # &gt;&gt; main
    # &gt;&gt; 5
    # &gt;&gt; #&amp;lt;Foo:0x10019092&amp;gt;
    # &gt;&gt; 6&lt;br/&gt;
    # &gt;&gt; #&amp;lt;Foo:0x10019092&amp;gt;
    # &gt;&gt; 7&lt;br/&gt;
    # &gt;&gt; #&amp;lt;Foo:0x10019092&amp;gt;
    # &gt;&gt; 8&lt;br/&gt;
    # &gt;&gt; #&amp;lt;Foo:0x10019092&amp;gt;
    # &gt;&gt; 9&lt;br/&gt;
    # &gt;&gt; #&amp;lt;Foo:0x10019092&amp;gt;
    # &gt;&gt; 10
  &lt;/pre&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the example above, &lt;em&gt;rebound&lt;/em&gt;inc_ is still a closure over &lt;em&gt;x&lt;/em&gt;, defined in &lt;em&gt;make_incrementer&lt;/em&gt;, but it&amp;#8217;s &lt;em&gt;self&lt;/em&gt; now points to whatever object we like.&lt;/p&gt;</description>
          <pubDate>Thu, 05 Nov 2009 22:23:53 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2009/11/05/playing-with-procbind/</guid>
          <link>http://evan.tiggerpalace.com/articles/2009/11/05/playing-with-procbind/</link>
        </item>
    
        <item>
          <title>Proc#Bind with Bobby Wilson</title>
          <description>&lt;p&gt;The Friday before I left Floyd, I had the opportunity to sit down with Bobby Wilson of Entryway.  Bobby and I had been hacking earlier on a hypothesis of mine that ActiveSupport&amp;#8217;s &lt;em&gt;Proc#bind&lt;/em&gt; could be used effectively to write a DSL instead of somewhat more evil/ugly approaches using &lt;em&gt;Object#instance_eval&lt;/em&gt;.  Ironically, I found earlier this week that &lt;a href=&quot;http://github.com/thoughtbot/shoulda&quot;&gt;Shoulda&lt;/a&gt; already does just that.  However, it was fun coming to the same conclusion on my own.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Proc#bind&lt;/em&gt; is a funny beast.  It effectively converts a &lt;em&gt;Proc&lt;/em&gt; into a &lt;em&gt;Method&lt;/em&gt; object where &lt;em&gt;self&lt;/em&gt; refers to the parameter passed to &lt;em&gt;Proc#bind&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  &lt;pre&gt;
class Proc #:nodoc:
  def bind(object)
    block, time = self, Time.now
    (class &amp;lt;&amp;lt; object; self end).class_eval do
      method&lt;em&gt;name = &quot;&lt;/em&gt;&lt;em&gt;bind&lt;/em&gt;#{time.to_i}_#{time.usec}&quot;
      define&lt;em&gt;method(method&lt;/em&gt;name, &amp;amp;block)
      method = instance&lt;em&gt;method(method&lt;/em&gt;name)
      remove&lt;em&gt;method(method&lt;/em&gt;name)
      method
    end.bind(object)
  end
end
  &lt;/pre&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Defines a method on &lt;em&gt;self&lt;/em&gt;&amp;#8217;s (a &lt;em&gt;Proc&lt;/em&gt;) singleton class using the &lt;em&gt;Proc&lt;/em&gt; itself as the method implementation&lt;/li&gt;&lt;/li&gt;
&lt;li&gt;Grabs a handle to the &lt;em&gt;UnboundMethod&lt;/em&gt; representing the &lt;em&gt;Proc&lt;/em&gt; &lt;/li&gt;&lt;/li&gt;
&lt;li&gt;Removes the method from the &lt;em&gt;Proc&lt;/em&gt;&amp;#8217;s singleton class &lt;em&gt;(but we still have the UnboundMethod from step 2)&lt;/em&gt;&lt;/li&gt;&lt;/li&gt;
&lt;li&gt;Binds the &lt;em&gt;UnboundMethod&lt;/em&gt; to the &lt;em&gt;object&lt;/em&gt; passed to &lt;em&gt;Proc#bind&lt;/em&gt;, returning a &lt;em&gt;Method&lt;/em&gt; object&lt;/li&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Afterward, Bobby and I sat down to BS for a bit about how much we needed beer (hey, it was Friday evening), discuss &lt;em&gt;Proc#bind&lt;/em&gt;, and the merits of describing oneself to non-software craftsman as a software craftsman.&lt;/p&gt;

&lt;p&gt;&lt;object width=&quot;400&quot; height=&quot;300&quot;&gt;&lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /&gt;&lt;param name=&quot;movie&quot; value=&quot;http://vimeo.com/moogaloop.swf?clip_id=7443854&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1&quot; /&gt;&lt;embed src=&quot;http://vimeo.com/moogaloop.swf?clip_id=7443854&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; width=&quot;400&quot; height=&quot;300&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href=&quot;http://vimeo.com/7443854&quot;&gt;Interview with Bobby Wilson&lt;/a&gt; from &lt;a href=&quot;http://vimeo.com/user666967&quot;&gt;Evan Light&lt;/a&gt; on &lt;a href=&quot;http://vimeo.com&quot;&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;</description>
          <pubDate>Wed, 04 Nov 2009 20:53:02 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2009/11/04/procbind-with-bobby-wilson/</guid>
          <link>http://evan.tiggerpalace.com/articles/2009/11/04/procbind-with-bobby-wilson/</link>
        </item>
    
        <item>
          <title>Facebook Connect w/ Facebooker</title>
          <description>&lt;p&gt;Facebook Connect seems to be well on its way to becoming the most popular third party authenticator on the market.  While Facebooker provides support for Facebook Connect, &lt;a href=&quot;http://www.elevatedrails.com/articles/2009/01/02/announcing-facebooker-support-for-facebook-connect/&quot;&gt;the Connect features are given only a light treatment in a blog entry by Mike Mangino&lt;/a&gt; (one of Facebooker&amp;#8217;s authors).  In this article, I will attempt to fill in some of the blanks left by that entry.&lt;/p&gt;

&lt;p&gt;After following Mike&amp;#8217;s example, I put _fb_logout_link in my template, clicked on it, but found that my web app was still convinced that I was logged into Facebook.  That is, I still had the &lt;i&gt;facebook_session&lt;/i&gt; object in my webap.  Mike&amp;#8217;s article show&amp;#8217;s how to handle logging in to Facebook Connect; however, logging out was causing me frustration.&lt;/p&gt;

&lt;p&gt;The below seemed to work for me:&lt;/p&gt;

&lt;p&gt;In your ERB (for example), you will  want:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= fb_logout_link &quot;Logout&quot;, &quot;/logout&quot; %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;fb_logout_link&lt;/em&gt; will log you out of Facebook; however, it does not seem to nil out the the &lt;em&gt;facebook_session&lt;/em&gt; object referred to in Mike&amp;#8217;s example.  As such, you&amp;#8217;ll want to map &amp;#8220;/logout&amp;#8221; to an action that will do this for you.  The logout operation should look something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def logout
  # ...
  clear_facebook_session_information
  # your redirect here    
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;clear_facebook_session_information&lt;/em&gt; is a method in the Facebooker::Rails::Controller module that will do exactly as the name says&lt;/p&gt;</description>
          <pubDate>Tue, 03 Nov 2009 14:10:50 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2009/11/03/facebook-connect-w-facebooker/</guid>
          <link>http://evan.tiggerpalace.com/articles/2009/11/03/facebook-connect-w-facebooker/</link>
        </item>
    
    
  </channel>
</rss>

