rake gems:unpack

April 13th, 2009

Ever run the “gems:unpack” Rake task in a Rails app, and wondered why one or more of your gems was silently skipped?

Any gem that is loaded in your Rakefile (e.g. metric_fu, vlad, etc) is considered to be a ‘framework gem’ by Rails, and such gems are not unpacked. Given that the vendor/gems directory is not yet in the load path when the Rakefile is loading, this is probably a good idea.

In other words, if you have a library that provides Rake tasks, or is otherwise necessary for your .rake files to be valid, don’t expect “config.gem” and friends to handle it for you.

Calling in the dark

June 7th, 2008

Some of you may have overheard me on the first day of RailsConf bitching about some crazy piece of code in RSpec that was totally broken in Rubinius. If not, well, here is that code:

eval("caller", registration_binding_block.binding)

Wow, what is going on here? After tracing through the RSpec code, I learned that ‘registration_binding_block’ was a block being turned into a Proc via block_pass.

For example:

def describe(&block)
  @registration_binding_block = block
  yield
end

So now we know what’s being returned by this method, but what about the rest of that line? Some people may not know that eval can take a Proc as a second argument. For the purposes of eval, a Proc and that Proc’s binding produce the same result. So we should also be able to say:

eval("caller", registration_binding_block)

What does it even mean to ask for “caller” in a Proc’s binding? What are we asking for? The Proc in question may not even have executed yet. It could just be sitting around, waiting to be called.

It turns out that RSpec wants to know the stack trace, not from this call to ‘eval’, but back from where the “registration_binding_block” was originally written; for example, one of the user’s spec files. RSpec uses this fairly extreme meta-programming trick in order to match your specs back to the file and line they were written on.

After the massive headache of understanding what the fix was, it turned out to be fairly easy to hack into Rubinius, and most of the RSpec specs now pass.

For everyone running benchmarks on unfinished Ruby implementations.. good luck keeping your speed when you are done with the really fun Ruby features.

Anyone out there know an easier way to ask a Proc what its “definition trace” is than what RSpec uses? I can’t think of one myself yet..

GitHub is pretty awesome

June 4th, 2008

Here are some of the things the GitHub team totally nailed:

  • Projects do not get a homepage. At SourceForge and its clones, you get this lame default page that you have to maintain, even if you don’t want it. At this point in history, I think we can assume that projects will already have a homepage, no matter how small.
  • Bi-directional connections between parent projects and forks. This lowers the barrier to entry for a typical open source patch tenfold. A simple idea that seems obvious in retrospect.
  • Having user URLs so close to the toplevel makes it trivial to remember the path to a particular project without searching. Imagine github.com/users/wilson/projects/213?name=foo and give thanks for what we have instead.
  • No need to fear github turning ‘evil’ or shutting off all the servers. Every clone of the project is another complete backup, unlike the nightmare of Subversion.
  • A ‘forker’ can trivially request an upstream developer’s attention via a pull request.
  • Optimized for storing and displaying source code, rather than downloading binaries.

There is a little bit of pain here during the ‘transition period’ as github takes over the open source world; existing projects will have to either enforce a single technique, or start checking two different places for patches. Presumably better Trac / Lighthouse integration with GitHub is forthcoming, however.

I recently had the opportunity to spin off a fork of RSpec in order to work on better Rubinius support; thus far the process has been painless for both me and the RSpec team. Nice work, GitHub.

➞ rbx script/console
Loading development environment (Rails 2.0.2)
>> Snippet.find(:all)
=> [#<Snippet id: 1, user_name: "Defiler", language: "ruby", description: "foo", body: "def foo\r\n  p 5\r\nend", created_at: "2008-05-17 15:33:34", key: "cbb30968">]
>>

RubySpec in MRI

May 16th, 2008

Check out the bottom of the MRI 1.8 Makefile:

http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8/Makefile.in

Merb on Rubinius

May 10th, 2008

Now that we have working OpenSSL support, we can run Merb:
fastness ➞ merbinius -a webrick
 ~ Loaded DEVELOPMENT Environment...
 ~ Compiling routes...
 ~ Using 'share-nothing' cookie sessions (4kb limit per client)
 ~ Using Webrick adapter
 ~ WEBrick 1.3.1
 ~ ruby 1.8.6 (05/07/2008) [i686-apple-darwin9.2.2]
 ~ TCPServer.new(0.0.0.0, 4000)
 ~ Rack::Handler::WEBrick is mounted on /.
 ~ WEBrick::HTTPServer#start: pid=61939 port=4000
 ~ accept: 127.0.0.1:59883
 ~ Rack::Handler::WEBrick is invoked.
 ~ Request: 
 ~ Routed to: {:action=>"index", :controller=>"hello"}
 ~ Params: {"action"=>"index", "controller"=>"hello"}
 ~ {:after_filters_time=>1.8e-05, :before_filters_time=>3.1e-05, 
     :dispatch_time=>0.069112, :action_time=>0.068106}

This question cropped up in #rubinius today, and I'll toss the answer out there because Google wasn't particularly helpful at the time.

There are several common ways to search for a commit message in git, but in this case, we are looking for a piece of text that will only appear in the full diff.

Since you already know the string you are searching for, paging through all the changes in a particular file seems wasteful.

I am (now) aware of two ways to do this with git:

  • git log -S'some_string'
  • git whatchanged -p (after the pager comes up, type '/' and then 'some_string')

If you know of a better trick, feel free to post a comment.

Captured On Video

February 18th, 2008

InfoQ just posted a video interview they recorded with me at the last RubyConf. I haven’t been brave enough yet to watch it, but you could check it out and then come tell me how badly I embarrassed myself.

Click here to unveil the terror

Implementing define_method

September 17th, 2007

A walkthrough of how 'define_method' is implemented in Rubinius
Read the rest of this entry

Lame Code Considered Harmful

December 28th, 2006

In this chapter, our intrepid hero writes slightly-more-tolerable code. Read the rest of this entry

Making a mockery of ActiveRecord

December 22nd, 2006

A code walkthrough; specifying the behavior of an ActiveRecord model 'mock-first'... Read the rest of this entry