<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Wonderland - Home</title>
  <id>tag:blog.leshill.org,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  <link href="http://blog.leshill.org/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://blog.leshill.org/" rel="alternate" type="text/html"/>
  <updated>2008-08-24T23:28:34Z</updated>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-08-24:25</id>
    <published>2008-08-24T23:28:00Z</published>
    <updated>2008-08-24T23:28:34Z</updated>
    <category term="git"/>
    <link href="http://blog.leshill.org/2008/8/24/git-setting-your-upstream-default" rel="alternate" type="text/html"/>
    <title>Git: setting your upstream default</title>
<content type="html">
            &lt;p&gt;I  recently set up a new repository on &lt;a href=&quot;http://www.github.com/&quot;&gt;github&lt;/a&gt;.  Creating the repository on github yields a page of instructions covering the two common scenarios: new and existing repositories.  After following the new repository instructions,  I had a repository on github, a local repository, and the following in response to my &lt;code&gt;git pull&lt;/code&gt; command:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;You asked me to pull without telling me which branch you want to merge with, and 'branch.master.merge' in your configuration file does not tell me either.  Please name which branch you want to merge on the command line and try again (e.g. 'git pull &amp;lt;repository&amp;gt; &amp;lt;refspec&amp;gt;'). See git-pull(1) for details on the refspec.

If you often merge with the same branch, you may want to configure the following variables in your configuration file:

  branch.master.remote = &amp;lt;nickname&amp;gt;
  branch.master.merge = &amp;lt;remote-ref&amp;gt;
  remote.&amp;lt;nickname&amp;gt;.url = &amp;lt;url&amp;gt;
  remote.&amp;lt;nickname&amp;gt;.fetch = &amp;lt;refspec&amp;gt;

See git-config(1) for details.
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Not exactly what I wanted, and certainly not what I expected.  What I &lt;em&gt;expected&lt;/em&gt; was a local repository with the upstream for &lt;strong&gt;master&lt;/strong&gt; to be set to point at &lt;strong&gt;master&lt;/strong&gt; on the github repository.&lt;/p&gt;


	&lt;p&gt;Setting this up can be done easily in two similar ways:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;You can edit the configuration file as directed by the error message&lt;/li&gt;
		&lt;li&gt;You can use &lt;code&gt;git config&lt;/code&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;I opted for &lt;code&gt;git config&lt;/code&gt; as it was easier and required no thinking&#8212;the commands are always the same&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;; here they are:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;% git config branch.master.remote origin
% git config branch.master.merge refs/heads/master&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt;  For the scenario of a local empty repository pushed up to a remote, where the remote will be the upstream master.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-08-24:24</id>
    <published>2008-08-24T13:53:00Z</published>
    <updated>2008-08-24T13:53:28Z</updated>
    <category term="rails"/>
    <category term="ruby"/>
    <category term="test"/>
    <link href="http://blog.leshill.org/2008/8/24/focusing-autotest" rel="alternate" type="text/html"/>
    <title>Focusing autotest</title>
<content type="html">
            &lt;p&gt;The usual &lt;a href=&quot;http://www.zenspider.com/ZSS/Products/ZenTest&quot;&gt;autotest&lt;/a&gt; workflow goes something like this:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Edit and save&lt;/li&gt;
		&lt;li&gt;Autotest runs associated specs&lt;/li&gt;
		&lt;li&gt;Are there failures?  Fix and start over&lt;/li&gt;
		&lt;li&gt;Autotest runs the entire suite&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Sometimes though, you want autotest to just ignore most of your specs and focus on a few specs.&lt;/p&gt;


	&lt;p&gt;Last week, while Kevin, Rick, and Yossef  (&lt;a href=&quot;http://bl.ogtastic.com&quot;&gt;OG&lt;/a&gt;) were here, they  shared an autotest tweak that does exactly that.&lt;/p&gt;


	&lt;p&gt;The tweak allows you to specify a regular expression to limit the files which autotest watches; for example, to autotest only files matching &lt;code&gt;*user*.rb&lt;/code&gt; you would (&lt;em&gt;atest&lt;/em&gt; is an alias):&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;% atest user&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Here is the (lightly modified) code to do this; in your &amp;lt;u&gt;.autotest&amp;lt;/u&gt; file add:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;if ENV['AUTOTEST'] and not ENV['AUTOTEST'].empty?
  only_these_files_re = Regexp.new(ENV['AUTOTEST'])

  Autotest.send(:alias_method, :real_find_files, :find_files)
  Autotest.send(:define_method, :find_files) do |*args|
    real_find_files.reject do |k, v|
      !only_these_files_re.match(k)
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And in your &amp;lt;u&gt;.bash_profile&amp;lt;/u&gt; add:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;# Autotest
  function fn_autotest() {
    AUTOTEST=$1 autotest
  }
  alias atest='fn_autotest'&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Now use the alias to invoke autotest.  For standard autotest behavior:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;% atest&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;To limit what autotest is watching, pass a regular expression (which can be a simple string):&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;% atest user.*html&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-08-15:22</id>
    <published>2008-08-15T12:00:00Z</published>
    <updated>2008-08-15T12:01:43Z</updated>
    <link href="http://blog.leshill.org/2008/8/15/obvious-money" rel="alternate" type="text/html"/>
    <title>Obvious Money</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.loudthinking.com&quot;&gt;David Heinemeier Hansson&lt;/a&gt; recently gave an awesome talk  titled &lt;a href=&quot;http://www.omnisio.com/startupschool08/david-heinemeier-hansson-at-startup-school-08&quot;&gt;The secret to making money online&lt;/a&gt; at the &lt;a href=&quot;http://ycombinator.com&quot;&gt;Y Combinator&lt;/a&gt; Startup School.  Aside from being entertaining, David keeps hammering at the VC-fueled dreams of today&#8217;s web entrepreneurs.  David has been at this for a long time, and what he is saying is &lt;em&gt;obvious&lt;/em&gt; and &lt;em&gt;common-sense&lt;/em&gt; (and David will tell you so).&lt;/p&gt;


	&lt;p&gt;And yet, we always hear people talking about the &lt;strong&gt;Money Maker&lt;/strong&gt;, or how they are going to target 1% of a &lt;strong&gt;$10 billion industry&lt;/strong&gt;, or other self-defeating filters.  If you find yourself uttering those kind of phrases in response to your own ideas or the ideas of others, &lt;strong&gt;stop&lt;/strong&gt;.&lt;/p&gt;


	&lt;p&gt;Refocus on what the idea is, and evaluate it on its merits.  Thinking about how to build a &lt;a href=&quot;http://www.37signals.com/svn/archives2/google_yahoo_microsoft_gym.php&quot;&gt;&lt;span class=&quot;caps&quot;&gt;GYM&lt;/span&gt;&lt;/a&gt; acquisition or targeting a market that will attract $10 million in VC funding is a waste of your time.&lt;/p&gt;


	&lt;p&gt;Should you ignore pricing and profits?  Maybe; if you do look at them, examine them in a reasonable context&#8212;what do I need to just run the service on a minimal server?  With no paid staff?  With minimal time commitments?  How would it look like if I had 100 customers?  1000 customers?&lt;/p&gt;


	&lt;p&gt;Yes, this means you are no longer playing in the VC startup space&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Cool.  If you really want to play there, you will be &lt;strong&gt;much&lt;/strong&gt; better off playing there after you already have those 100 customers.&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; I am unsure about investors like Y Combinator, as they &lt;em&gt;seem&lt;/em&gt; to be advocates for this way of thinking.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-08-14:21</id>
    <published>2008-08-14T15:06:00Z</published>
    <updated>2008-08-14T15:07:48Z</updated>
    <category term="biz"/>
    <link href="http://blog.leshill.org/2008/8/14/obvious-intangibles" rel="alternate" type="text/html"/>
    <title>Obvious Intangibles</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://sethgodin.typepad.com/seths_blog&quot;&gt;Seth Godin&lt;/a&gt; has just put up a fantastic post on &lt;a href=&quot;http://sethgodin.typepad.com/seths_blog/2008/08/the-intangibles.html&quot;&gt;The intangibles&lt;/a&gt;&#8212;ways to set your product or service apart.&lt;/p&gt;


	&lt;p&gt;Many of them read as &lt;em&gt;common-sense&lt;/em&gt; or &lt;em&gt;obvious&lt;/em&gt;, but like most &lt;em&gt;common-sense&lt;/em&gt; and &lt;em&gt;obvious&lt;/em&gt; advice, it is rarely actually practiced; often the advice is even actively dismissed with an annoyed &#8216;Of course we do that!&#8217;&#8212;only you do not do that, and you are fooling yourself by saying so.&lt;/p&gt;


	&lt;p&gt;Take stock of what you are doing, and ask yourself if you are really doing the &lt;em&gt;common-sense&lt;/em&gt; and &lt;em&gt;obvious&lt;/em&gt; things.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-07-13:18</id>
    <published>2008-07-13T03:33:00Z</published>
    <updated>2008-07-13T03:36:23Z</updated>
    <category term="ruby"/>
    <link href="http://blog.leshill.org/2008/7/13/voodoo-send" rel="alternate" type="text/html"/>
    <title>Voodoo send</title>
<content type="html">
            &lt;p&gt;Recently when looking through some plugin&#8217;s code, we found the following line:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;self.send(:include, Foo)&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This &lt;em&gt;seems&lt;/em&gt; to be an acceptable variant of the commonly used&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;ActiveRecord::Base.send(:include, Foo)&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;As you may have surmised, it is not an acceptable variant.  This is a &lt;a href=&quot;http://en.wikipedia.org/wiki/Voodoo_programming&quot;&gt;Voodoo programming&lt;/a&gt; smell, as it indicates a misunderstanding of exactly what the semantics of &lt;code&gt;send&lt;/code&gt; are.  There is also a clearer, more intention revealing, and identical&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; alternative:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;include Foo&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;or with the omitted parenthesis:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;include(Foo)&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This of course, leads us to why &lt;code&gt;ActiveRecord::Base.send(:include, Foo)&lt;/code&gt; is acceptable.  The &lt;code&gt;include&lt;/code&gt; method is private, so the most elegant way to invoke it on &lt;em&gt;another&lt;/em&gt; object is by using &lt;code&gt;send&lt;/code&gt;; this is possible because &lt;code&gt;send&lt;/code&gt; ignores access control allowing us to invoke &lt;code&gt;include&lt;/code&gt; directly.&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; &lt;em&gt;Almost&lt;/em&gt;, the difference is that &lt;code&gt;send&lt;/code&gt; is in the call stack.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-07-02:17</id>
    <published>2008-07-02T03:50:00Z</published>
    <updated>2008-07-02T12:33:05Z</updated>
    <link href="http://blog.leshill.org/2008/7/2/rspec-1-1-4-and-helpers" rel="alternate" type="text/html"/>
    <title>RSpec 1.1.4 and Helpers</title>
<content type="html">
            &lt;p&gt;Last week, RSpec 1.1.4 was released; and given my optimistic disposition I immediately upgraded.  Happily, the upgrade was almost seamless.  Two interdependent issues kept this from being a flawless upgrade:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;A new deprecation warning on our helper specs (&lt;em&gt;no one really likes to see deprecation warnings&lt;/em&gt;)&lt;/li&gt;
		&lt;li&gt;A bug in the new way to write helper specs (&lt;em&gt;a show stopper&lt;/em&gt;)&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Lets see what happens when we run our spec&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;Wonderland$ spec spec/helpers/dog_helper_spec.rb 
Modules will no longer be automatically included in RSpec version 1.1.4.  Called from ./spec/helpers/dog_helper_spec.rb:8
.Modules will no longer be automatically included in RSpec version 1.1.4.  Called from ./spec/helpers/dog_helper_spec.rb:16
.
Finished in 0.393129 seconds
2 examples, 0 failures&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Lets examine the helper spec that generated these warnings:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe DogHelper do

  describe &amp;quot;name_or_description()&amp;quot; do
    it &amp;quot;should return a description for a dog without a name&amp;quot; do
      dog = mock_model(Dog, :name =&amp;gt; nil, :sex =&amp;gt; 'male', :breed =&amp;gt; 'Labrador', :color =&amp;gt; 'black')
      name_or_description(dog).should == &amp;quot;(male Labrador, black)&amp;quot;
    end
  end

  describe &amp;quot;owner_link()&amp;quot; do
    it &amp;quot;should return a link to the owner&amp;quot; do
      owner = mock_model(User, :login =&amp;gt; 'sally_smith', :to_param =&amp;gt; 'sally_smith')
      dog = mock_model(Dog, :owner =&amp;gt; owner)
      owner_link(dog).should =~ /users\/sally_smith/
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;So, what does this deprecation warning tell us?  We are being warned that calls to &lt;strong&gt;name_or_description&lt;/strong&gt; and &lt;strong&gt;owner_link&lt;/strong&gt;, which are called on the implicit &lt;strong&gt;self&lt;/strong&gt; of the RSpec &lt;em&gt;it&lt;/em&gt; blocks, are going to fail in the future when the helper module (&lt;strong&gt;DogHelper&lt;/strong&gt; in this example) is no longer automatically included by RSpec.&lt;/p&gt;


	&lt;p&gt;Or put another way, calling helper methods like &lt;strong&gt;name_or_description&lt;/strong&gt; directly, &lt;em&gt;exactly as one might in a view&lt;/em&gt;, will no longer work.&lt;/p&gt;


	&lt;p&gt;The new way to call helper methods is through the &lt;strong&gt;helper&lt;/strong&gt; attribute of RSpec, giving access to an &lt;strong&gt;ActionView::Base&lt;/strong&gt; instance with the helper module included.  Lets go ahead and make this change to our two helper calls:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe DogHelper do

  describe &amp;quot;name_or_description()&amp;quot; do
    it &amp;quot;should return a description for a dog without a name&amp;quot; do
      dog = mock_model(Dog, :name =&amp;gt; nil, :sex =&amp;gt; 'male', :breed =&amp;gt; 'Labrador', :color =&amp;gt; 'black')
      helper.name_or_description(dog).should == &amp;quot;(male Labrador, black)&amp;quot;
    end
  end

  describe &amp;quot;owner_link()&amp;quot; do
    it &amp;quot;should return a link to the owner&amp;quot; do
      owner = mock_model(User, :login =&amp;gt; 'sally_smith', :to_param =&amp;gt; 'sally_smith')
      dog = mock_model(Dog, :owner =&amp;gt; owner)
      helper.owner_link(dog).should =~ /users\/sally_smith/
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Lets try this out!&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;Wonderland$ spec spec/helpers/dog_helper_spec.rb 
.F
1)
NoMethodError in 'DogHelper owner_link() should return a link to the owner'
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.url_for
(eval):17:in `user_path'
/Users/leshill/src/rails/rspec114/app/helpers/dog_helper.rb:9:in `owner_link'
./spec/helpers/dog_helper_spec.rb:16:
Finished in 0.398686 seconds
2 examples, 1 failure&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Hmmm, we have gotten rid of the deprecation warnings, but we now have a new (and truly unexpected!) failure.&lt;/p&gt;


	&lt;p&gt;This is a bona-fide bug in 1.1.4, and might lead to our having to rollback to 1.1.3 if there was no easy workaround.  Thankfully, there is a fix already available for 1.1.5 , and that fix can be easily adapted within our own specs.&lt;/p&gt;


	&lt;p&gt;Lets add this &lt;strong&gt;before&lt;/strong&gt; block to our spec:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;before(:each) do
    # Patch until 1.1.5
    helper_controller = @controller
    helper.instance_eval { @controller = helper_controller }
  end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And then try it out:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;Wonderland$ spec spec/helpers/dog_helper_spec.rb 
..
Finished in 0.40663 seconds
2 examples, 0 failures&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Much better!&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; I am using a mock spec to demonstrate the issue, the minimal Rails app which fits around this spec is left as an exercise for the reader.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-05-12:11</id>
    <published>2008-05-12T01:02:00Z</published>
    <updated>2008-05-12T03:26:27Z</updated>
    <link href="http://blog.leshill.org/2008/5/12/a-cognitive-surplus" rel="alternate" type="text/html"/>
    <title>A participation deficit</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.shirky.com&quot;&gt;Clay Shirky&lt;/a&gt; is brilliant, and I have been reading his essays for a very long time&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Recently, he has been discussing his notion of a &lt;a href=&quot;http://www.herecomeseverybody.org/2008/04/looking-for-the-mouse.html&quot;&gt;Cognitive Surplus&lt;/a&gt; .  Good stuff; if you have not read it, go read it now.&lt;/p&gt;


	&lt;p&gt;The headline is that if we just switch 1% of yearly TV consumption hours to &#8216;participation&#8217; we get the equivalent of 100 Wikipedia projects a year (that is development, comments, authors, editors, talk; the whole corpus as it stands today).&lt;/p&gt;


	&lt;p&gt;This the &lt;em&gt;Cognitive Surplus&lt;/em&gt;; previously the surplus was masked by mind-numbing television until we switched from just being able to &lt;em&gt;consume&lt;/em&gt; media to &lt;strong&gt;consuming, producing, and sharing&lt;/strong&gt; media.&lt;/p&gt;


	&lt;p&gt;We are in a new media landscape, transformed irrevocably from mass consumption of media due to the communication advances of the last few decades.&lt;/p&gt;


	&lt;p&gt;Those advances enabled us to erase a &lt;strong&gt;participation deficit&lt;/strong&gt;.  The way the deficit manifested for me was an apparent inability to be alone (so says my wife) in spite of being a person who values solitude.  Before the nascent intertubes, I had no way to participate.  I could (&lt;em&gt;and did&lt;/em&gt;) watch television.  But I also did many other things, including hack on computers.  Only there was no sharing, no participation.  Once the nascent intertubes arrived, I&lt;sup&gt;&lt;a href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; and many others did participate.  Our participation accelerated on the wave of Moore&#8217;s and Metcalfe&#8217;s laws to transform society in ways we could not anticipate, but that we were already exploring.  We still cannot anticipate how we are changing society, and we are still exploring.&lt;/p&gt;


	&lt;p&gt;If you have read this, take a moment and write your own blog entry or tweet or upload a photo/video or post a message or whatever-social-sharing-thing-you-might-do and revel in your participation.&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; A decade?&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;2&lt;/sup&gt; My first email (lost forever) was in 1982.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-05-08:8</id>
    <published>2008-05-08T23:10:00Z</published>
    <updated>2008-05-08T23:11:20Z</updated>
    <category term="personal"/>
    <link href="http://blog.leshill.org/2008/5/8/a-little-bit-of-history" rel="alternate" type="text/html"/>
    <title>A little bit of history</title>
<content type="html">
            &lt;p&gt;I am a bit late on the history &lt;a href=&quot;http://diveintomark.org/archives/2008/04/15/history-meme&quot;&gt;meme&lt;/a&gt;.  Here I am:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;Wonderland$ history | awk '{a[$2]++}END{for(i in a){print a[i] &quot; &quot; i}}' | sort -rn | head
149 git
60 spec
46 ls
45 gst
42 cd
28 rake
14 ssh
8 ss
7 houston
7 gco&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Things to note&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;3 are git&lt;/li&gt;
		&lt;li&gt;3 are Rails development related&lt;/li&gt;
		&lt;li&gt;4 are common unix commands&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; 4 are aliases&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-05-06:7</id>
    <published>2008-05-06T04:26:00Z</published>
    <updated>2008-05-06T13:11:58Z</updated>
    <category term="ajax"/>
    <link href="http://blog.leshill.org/2008/5/6/stone-knives-and-bearskins" rel="alternate" type="text/html"/>
    <title>Stone knives and bearskins</title>
<content type="html">
            &lt;p&gt;Recently while discussing &lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt;, we got onto the topic of &lt;a href=&quot;http://en.wikipedia.org/wiki/Ajax_%28programming%29&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt;&lt;/a&gt;.  This prompted me to declare:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;&lt;em&gt;Before AJAX, we used stone knives and bearskins to make our web apps&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Actually, we were using JavaScript and &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; to drive our web apps, we just did not call it &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt;, and it was a very challenging task.  In spite of the difficulty of building it, we stuck with it and we were pretty darn happy with our &lt;strong&gt;pre-web 2.0 web2.0&lt;/strong&gt; app; so much so that we actually had people coming by just to see our UI in action.&lt;/p&gt;


	&lt;p&gt;I went back and looked for some of our old code, hoping to find the &lt;span class=&quot;caps&quot;&gt;CVS&lt;/span&gt; repository&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, but only finding a tarball of version 1.4.  The following code is from &amp;lt;u&gt;client/script/services.js&amp;lt;/u&gt; and dated &lt;strong&gt;August 24, 2001&lt;/strong&gt;&#8212;although some version of this code would have existed in the spring of &lt;strong&gt;2000&lt;/strong&gt;:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;BrServices.prototype.issueRequest = function (action) {
...
    var request = brUtils.newXmlDOM(action);
    brUtils.dumpError(request.parseError);
    var tryCount = 0;
    var condition = brServices.isOkay;
    var s = &amp;quot;&amp;quot;;
    while (condition == brServices.isOkay) {

        try {
            s += &amp;quot;\n&amp;quot;;
            var httpOb = new ActiveXObject(&amp;quot;MSXML2.XMLHTTP&amp;quot;); // Was Microsoft.XMLHTTP
            s += &amp;quot;new: &amp;quot; + httpOb.readyState;
            httpOb.open(&amp;quot;POST&amp;quot;, brServices.brxmlURL, false);
            s += &amp;quot;, open: &amp;quot; + httpOb.readyState;
            httpOb.setRequestHeader(&amp;quot;Content-Type&amp;quot;, &amp;quot;text/xml; charset='UTF-8'&amp;quot;);
            s += &amp;quot;, setRequestHeader: &amp;quot; + httpOb.readyState;

            httpOb.send(request);
...&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Just looking at this snippet from our internal library makes me all the happier that we made the thing work at all.  Kudos to &lt;a href=&quot;http://markjudd.com&quot;&gt;Mark Judd&lt;/a&gt; and &lt;a href=&quot;http://brianlevine.blogspot.com&quot;&gt;Brian Levine&lt;/a&gt;, two of our very talented small team, who were responsible for our UI.&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; You already know this, but just in case, &lt;span class=&quot;caps&quot;&gt;CVS&lt;/span&gt; was a source code repository that pretty much everyone used before Subversion (unless you bought one from a vendor).&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-04-22:6</id>
    <published>2008-04-22T14:42:00Z</published>
    <updated>2008-04-22T14:44:08Z</updated>
    <category term="rails"/>
    <link href="http://blog.leshill.org/2008/4/22/control-your-layout" rel="alternate" type="text/html"/>
    <title>Control your layout</title>
<content type="html">
            &lt;p&gt;Recently, I added &lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt; ajax tabs to an application.  To reuse the existing views, I moved the relevant view code to partials for each required action:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;render :partial =&amp;gt; &amp;quot;entry&amp;quot;, :object =&amp;gt; journal_entry&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;and using something like the following in all the relevant controller methods:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;format.html { render :partial =&amp;gt; 'index' if request.xhr? }&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;As I added more features to the ajax tabs, I was conditionally rendering partials in &lt;em&gt;every&lt;/em&gt; relevant action, as well as creating a partial.  Not &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt;&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;layout&lt;/strong&gt; provides a much &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt;&lt;/em&gt;-er solution without the need for the partials.  In &lt;em&gt;application.rb&lt;/em&gt;:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;layout proc { |controller| controller.request.xhr? ? false : 'application' }&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;When a controller action is invoked, if it is an &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;XHR&lt;/span&gt;&lt;/strong&gt;, no layout will be used.  Otherwise the default &lt;strong&gt;Rails&lt;/strong&gt; layout, &#8216;application&#8217;, will be used&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; &lt;strong&gt;layout&lt;/strong&gt; expects the name of a layout to be returned from the proc; in this case, I am returning the name of the default.  Returning &lt;strong&gt;false&lt;/strong&gt; indicates that no layout should be used.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-04-07:5</id>
    <published>2008-04-07T02:23:00Z</published>
    <updated>2008-04-16T03:18:43Z</updated>
    <category term="ruby"/>
    <link href="http://blog.leshill.org/2008/4/7/include-and-extend" rel="alternate" type="text/html"/>
    <title>include and extend</title>
<content type="html">
            &lt;code&gt;include&lt;/code&gt; and &lt;code&gt;extend&lt;/code&gt; are commonly used to add methods to &lt;code&gt;Ruby&lt;/code&gt; classes, and sometimes, why we use one or the other is not clear.  Both do similar operations, but they are not equivalent.  &lt;code&gt;extend&lt;/code&gt; is more parsimonious adding only methods, &lt;code&gt;include&lt;/code&gt;also includes constants and module variables.

	&lt;p&gt;A simple guideline is to &lt;strong&gt;include&lt;/strong&gt; instance methods and to &lt;strong&gt;extend&lt;/strong&gt; class methods.&lt;/p&gt;


	&lt;p&gt;Here is an example of a class with an instance method and a class method.  We have reopened the class so that we can show the differences from the original empty class:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def list_diff(label, list1, list2)
  puts &amp;quot;#{label}: #{(list1 - list2).sort.join ' '}&amp;quot;
end

class One
end

methods_from_new = One.new.methods
methods_from_class = One.methods

class One
  def instance_method
  end

  def One.class_method
  end
end

list_diff &amp;quot;Instance One.new diff&amp;quot;, One.new.methods, methods_from_new
list_diff &amp;quot;Class One diff&amp;quot;, One.methods, methods_from_class&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;when run shows the expected differences:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Instance One.new diff: instance_method
Class One diff: class_method
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Now lets create and &lt;strong&gt;include&lt;/strong&gt; a module:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;module ModuleTwo
  CONSTANT_TWO = &amp;quot;two&amp;quot;
  def module_method
  end
end

class One
  include ModuleTwo
end

list_diff &amp;quot;Instance One.new diff&amp;quot;, One.new.methods, methods_from_new
list_diff &amp;quot;Class One diff&amp;quot;, One.methods, methods_from_class
puts &amp;quot;has constant? #{One.constants.sort.join ' '}&amp;quot;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;when run shows that &lt;em&gt;module_method&lt;/em&gt; and &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;CONSTANT&lt;/span&gt;_TWO&lt;/em&gt; are now available:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Instance One.new diff: instance_method module_method
Class One diff: class_method
has constant? CONSTANT_TWO
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And if we &lt;strong&gt;extend&lt;/strong&gt; another module:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;module ModuleThree
  CONSTANT_THREE = 'three'
  def another_module_method
  end
end

class One
  extend ModuleThree
end

list_diff &amp;quot;Instance One.new diff&amp;quot;, One.new.methods, methods_from_new
list_diff &amp;quot;Class One diff&amp;quot;, One.methods, methods_from_class
puts &amp;quot;has constant? #{One.constants.sort.join ' '}&amp;quot;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;When run, shows that &lt;em&gt;another_module_method&lt;/em&gt; is now available as a class method, but &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;CONSTANT&lt;/span&gt;_THREE&lt;/em&gt; is not&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Instance One.new diff: instance_method module_method
Class One diff: another_module_method class_method
has constant? CONSTANT_TWO
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Finally, we can use &lt;strong&gt;include&lt;/strong&gt; instead of &lt;strong&gt;extend&lt;/strong&gt; to &lt;em&gt;include&lt;/em&gt; class methods:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;module ModuleFour
  CONSTANT_FOUR = 'four'
  def yet_another_module_method
  end
end

class One
  class &amp;lt;&amp;lt; self
    include ModuleFour
  end
end

list_diff &amp;quot;Instance One.new diff&amp;quot;, One.new.methods, methods_from_new
list_diff &amp;quot;Class One diff&amp;quot;, One.methods, methods_from_class
puts &amp;quot;has constant? #{One.constants.sort.join ' '}&amp;quot;&lt;/code&gt;&lt;/pre&gt;

When run, shows that &lt;em&gt;yet_another_module_method&lt;/em&gt; is available as a class method, but &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;CONSTANT&lt;/span&gt;_FOUR&lt;/em&gt; is not&lt;sup&gt;&lt;a href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
&lt;pre&gt;&lt;code&gt;Instance One.new diff: instance_method module_method
Class One diff: another_module_method class_method yet_another_module_method
has constant? CONSTANT_TWO
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; Remember, &lt;code&gt;include&lt;/code&gt; does more&lt;sup&gt;&lt;a href=&quot;#fn3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; than &lt;code&gt;extend&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;2&lt;/sup&gt; For more details, check &lt;a href=&quot;http://www.pragprog.com/titles/ruby&quot;&gt;Programming Ruby: The Pragmatic Programmer&#8217;s Guide&lt;/a&gt; .&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;3&lt;/sup&gt; Bonus!&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;module ModuleFive
  CONSTANT_FIVE = 'five'
  def module_five
  end
end

one = One.new
one.extend ModuleFive

list_diff &amp;quot;Instance extends module&amp;quot;, one.methods, methods_from_new
puts &amp;quot;has constant? #{one.class.constants.sort.join ' '}&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;
Instance extends module: instance_method module_five module_method
has constant? CONSTANT_TWO
&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-03-27:4</id>
    <published>2008-03-27T16:30:00Z</published>
    <updated>2008-03-27T16:30:49Z</updated>
    <category term="git"/>
    <link href="http://blog.leshill.org/2008/3/27/patching-with-git" rel="alternate" type="text/html"/>
    <title>Patching with git</title>
<content type="html">
            &lt;p&gt;I patched the Ruby on Rails bundle for &lt;a href=&quot;http://macromates.com/&quot;&gt;TextMate&lt;/a&gt; to allow &lt;em&gt;footnotes&lt;/em&gt; to catch &lt;a href=&quot;http://haml.hamptoncatlin.com/&quot;&gt;Haml&lt;/a&gt; views, which might be in files named &lt;span&gt;something.haml&lt;/span&gt; &lt;strong&gt;or&lt;/strong&gt; &lt;span&gt;something.html.haml&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;The change itself is trivial; making a patch using &lt;a href=&quot;http://git.or.cz/&quot;&gt;git&lt;/a&gt; was something new and, as it turns out, five steps:&lt;/p&gt;


	&lt;h3&gt;1. Grab the source with git&lt;/h3&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&lt;code&gt;Wonderland$ git clone git://github.com/drnic/ruby-on-rails-tmbundle.git&lt;/code&gt;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h3&gt;2. Make your changes&lt;/h3&gt;


	&lt;h3&gt;3. Commit locally, from the root of the source treee&lt;/h3&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&lt;code&gt;
 Wonderland$ git commit -a -m 'add support for html.haml templates'
 Wonderland$ git show
&lt;/code&gt;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h3&gt;4. Generate a patch file&lt;/h3&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&lt;code&gt;Wonderland$ git format-patch origin&lt;/code&gt;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h3&gt;5. Email the patch file&lt;/h3&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-03-24:2</id>
    <published>2008-03-24T05:38:00Z</published>
    <updated>2008-03-24T14:15:15Z</updated>
    <category term="mephisto"/>
    <link href="http://blog.leshill.org/2008/3/24/syntax-highlighting-with-code-highlighter-macro-for-mephisto" rel="alternate" type="text/html"/>
    <title>Syntax Highlighting with the Code Highlighter Macro for Mephisto</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.danwebb.net&quot;&gt;Dan Webb&lt;/a&gt; has an alternative to the built-in syntax highlighting provided by &lt;a href=&quot;http://mephistoblog.com/&quot;&gt;Mephisto&lt;/a&gt; that uses JavaScript to markup your code by using regular expressions to tokenize the code.  Nifty, and based on  &lt;a href=&quot;http://dean.edwards.name/star-light/&quot;&gt;this&lt;/a&gt; &lt;a href=&quot;http://en.wikipedia.org/wiki/HTML_Components&quot;&gt;DHTML behavior&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a summary of the install:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;strong&gt;svn&lt;/strong&gt; to pull from &lt;strong&gt;http://svn.danwebb.net/external/rails/plugins/filtered_column_code_highlighter/trunk/&lt;/strong&gt; into the &amp;lt;u&gt;vendor/plugins&amp;lt;/u&gt; directory&lt;/li&gt;
&lt;li&gt;Do either of:
&lt;ol&gt;
&lt;li&gt;Copy the &amp;lt;u&gt;assets/*.js&amp;lt;/u&gt; to your &amp;lt;u&gt;public/javascripts&amp;lt;/u&gt; directory&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;rake install&lt;/strong&gt; (copies to &amp;lt;u&gt;themes/site-1/javascripts&amp;lt;/u&gt;)&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;Create a new CSS stylesheet (&amp;lt;u&gt;codehighlight.css&amp;lt;/u&gt;) with the syntax coloring you want; I used &lt;a href=&quot;http://www.usefuljaja.com/assets/2007/6/1/codehighlight.css&quot;&gt;this&lt;/a&gt; as a start.&lt;/li&gt;
&lt;li&gt;Add the following to your &amp;lt;u&gt;layout.liquid&amp;lt;/u&gt; template&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;{{ 'codehighlight' | stylesheet }}
{{ 'code_highlighter' | javascript }}
{{ 'html' | javascript }}
{{ 'ruby' | javascript }}
{{ 'css' | javascript }}
{{ 'javascript' | javascript }}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the following markup:&lt;/p&gt;

&lt;p&gt;&amp;lt;filter:jscode lang=&#8221;javascript&#8221;&amp;gt;document.someScriptThing = &#8220;BOO&#8221;&amp;lt;/filter:jscode&amp;gt;&lt;/p&gt;

&lt;p&gt;Generates:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;document.someScriptThing = &amp;quot;BOO&amp;quot;&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-03-23:1</id>
    <published>2008-03-23T06:03:00Z</published>
    <updated>2008-03-23T06:16:54Z</updated>
    <category term="ruby"/>
    <link href="http://blog.leshill.org/2008/3/23/define_method" rel="alternate" type="text/html"/>
    <title>define_method</title>
<content type="html">
            &lt;p&gt;While we were waiting for March 20th &lt;a href=&quot;http://www.rubyjax.com/&quot;&gt;RubyJax&lt;/a&gt; meeting to get started, &lt;a href=&quot;http://b.lesseverything.com&quot;&gt;Steve Bristol&lt;/a&gt; entertained us with a Ruby quiz.  One of the questions was particularly interesting as it had many possible answers.  I will paraphrase the question as:&lt;/p&gt;

&lt;p&gt;&#8220;How many ways are there to add a method to an existing class in Ruby?&#8221;&lt;/p&gt;

&lt;p&gt;I have cataloged the answers that were tossed out as well as a few I just added.&lt;/p&gt;

&lt;p&gt;1 . Open the class and add a new method&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class String
  def method_one
    puts 'method 1'
  end
end

&amp;quot;abcde&amp;quot;.method_one&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;2 . Create a singleton method on an instance&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;s = &amp;quot;12345&amp;quot;

def s.method_two
  puts 'method 2'
end

s.method_two&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;3 . Use Kernel#method_missing&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class String
  def method_missing(name, *args)
    super unless name == :method_three
    puts 'method 3'
  end
end

&amp;quot;abcde&amp;quot;.method_three&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;4 . Use Module#define_method&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class String
  def create_method(name, &amp;amp;block)
    self.class.send(:define_method, name, block)
  end
end

&amp;quot;abcde&amp;quot;.create_method(:method_four) { puts 'method 4' }
&amp;quot;12345&amp;quot;.method_four&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;5 . A variation of #1 : include a module in the class&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;module ExtraMethods
  def method_five
    puts 'method 5'
  end
end

class String
  include ExtraMethods
end

&amp;quot;abcde&amp;quot;.method_five&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;6 . A variation of #4 : use Object#instance_eval&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;String.instance_eval(&amp;quot;define_method(:method_six) { puts 'method 6' }&amp;quot;)

&amp;quot;abcde&amp;quot;.method_six&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;7 . We could use Kernel#eval to execute any of the above as well; here we will emulate instance_eval with a binding&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class String
  def self.get_binding
    binding
  end
end

eval(&amp;quot;define_method(:method_seven) { puts 'method 7' }&amp;quot;, String.get_binding)

&amp;quot;abcde&amp;quot;.method_seven&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Any others?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.leshill.org/">
    <author>
      <name>leshill</name>
    </author>
    <id>tag:blog.leshill.org,2008-02-22:3</id>
    <published>2008-02-22T16:09:00Z</published>
    <updated>2008-03-24T14:33:57Z</updated>
    <category term="haml"/>
    <category term="rails"/>
    <link href="http://blog.leshill.org/2008/2/22/monkey-patch" rel="alternate" type="text/html"/>
    <title>Monkey Patch!</title>
<content type="html">
            &lt;p&gt;So after missing the wisdom[1] of this:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://xkcd.com/386/&quot;&gt;http://xkcd.com/386/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And responding to this:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://b.lesseverything.com/2008/2/19/haml-doesn-t-like-javascript&quot;&gt;http://b.lesseverything.com/2008/2/19/haml-doesn-t-like-javascript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I went to bed.&lt;/p&gt;

&lt;p&gt;This morning I wrote my first Rails (really Haml) Monkey Patch[2].
This adds some of what Steve wanted: undisturbed inline javascript
with variable interpolation.  I am not sure what else he wanted as I
did not read his blog carefully :)&lt;/p&gt;

&lt;p&gt;Throw this into &amp;lt;u&gt;lib/inline_javascript.rb&amp;lt;/u&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;module Haml
  module Filters
    class InlineJavascript
      HEAD =&amp;lt;&amp;lt;EOH
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
//&amp;lt;![CDATA[
EOH

      FOOT =&amp;lt;&amp;lt;EOF
//]]&amp;gt;
&amp;lt;/script&amp;gt;
EOF

      def initialize(text)
        @text = HEAD + text + FOOT
      end

      def render
        @text
      end
    end
  end

  module Precompiler
    def close_filtered(filter)
      @flat_spaces = -1
      filtered = filter.new(@filter_buffer).render

      if filter == Haml::Filters::Preserve
        push_silent(&amp;quot;_hamlout.buffer &amp;lt;&amp;lt; #{filtered.dump} &amp;lt;&amp;lt; \&amp;quot;\\n\&amp;quot;;&amp;quot;)
      elsif filter == Haml::Filters::InlineJavascript
        # suppress eval option does not apply to us
        flush_merged_text
        js = unescape_interpolation(filtered)
        @precompiled  &amp;lt;&amp;lt; &amp;quot;_hamlout.buffer &amp;lt;&amp;lt; #{js};&amp;quot;
      else
        push_text(filtered.rstrip.gsub(&amp;quot;\n&amp;quot;, &amp;quot;\n#{'  ' * @output_tabs}&amp;quot;))
      end

      @filter_buffer = nil
      @template_tabs -= 1
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Throw this at the bottom of your &amp;lt;u&gt;environment.rb&amp;lt;/u&gt;, taken from here &lt;a href=&quot;http://groups.google.com/group/haml/msg/2d890cf1ede761ea&quot;&gt;http://groups.google.com/group/haml/msg/2d890cf1ede761ea&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;require 'inline_javascript'

Haml::Template.options = {
   :filters =&amp;gt; {
     'javascript' =&amp;gt; Haml::Filters::InlineJavascript
   }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then do this in your Haml:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;:javascript
  function oh_yea() {
    alert('Hello' + '#{@message}')
  }
%a{ :href =&amp;gt;&amp;quot;javascript:oh_yea()&amp;quot; } Oh Yea!&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Update&lt;/h2&gt;

&lt;p&gt;I decided to make a patch and submit it to the Haml folks directly.  This gave me the &#8216;opportunity&#8217; to get &lt;strong&gt;git&lt;/strong&gt; going.&lt;/p&gt;

&lt;p&gt;Nathan Weizenbaum took the time to put in a more comprehensive fix to expose the interpolation functionality to all filters &#8211; look for it in an upcoming release.&lt;/p&gt;

&lt;p&gt;[1] It&#8217;s turtles all the way down.&lt;/p&gt;

&lt;p&gt;[2] You do not want to know what my subconscious originally thought up
as the way to do this &#8211; that was twisted.&lt;/p&gt;
          </content>  </entry>
</feed>
