I was lucky enough to attend RubyConf 2008. I really enjoyed last year’s conference, and I felt this year was better.
There was lots of great content, and more than handful of time slots where I wanted to attend both. I’m eagerly waiting for Confreaks to post all the talks so I could watch the ones I missed, as well as re-watch the ones I attended.
Among all the talks I attended, there were three talks that really enjoyed.
Ruby Heavy-Lifting: Lazy load it, Event it, Defer it, and then Optimize it
This was given by Ilya Grigorik of AideRSS, and was my favorite talk of the weekend. Ilya went over their experiences developing PostRank and main optimization techniques they used with Ruby.
Primarily:
- Message Queues
- EventMachine
- Process Forking
- Custom C Extensions
Ilya didn’t just gloss over each point in a tutorial fashion, but instead described how they used each item and the resulting effects.
It was very refreshing to hear someone speak of their roadblocks and creative solutions to work around them. Hearing that PostRank is making around 5 million requests per day, and is spread over 100 servers is pretty inspiring.
What Every Rubyist Should Know About Threads
Jim Weirich from EdgeCase gave this talk. Now I’ve been interested in fairly interested in concurrency this year. Especially as we see hardware trends stalling out on speed and moving towards multiple cores. I really appreciated this talk for two reasons.
First, it shamed me. Yup, I’ll admit it. As snobby as I acted about concurrency, and as much as I touted I understood deadlocking and thread safety code, Jim’s talk exposed me to my ignorance, and for that I’m very grateful.
This talk may not appeal to others the same way it did to me, however for those interested in threading basics as well as virtual machine quicks this was worthwhile.
Dramatis: Actors for Ruby
Steven Parks gave a great talk about his Actor-based Concurrency library for both Ruby and Python Dramatis. Now Dramatis is rather young, but has a lot of potential. Not to mention Steven’s presentation and conversation afterwards indicates he has been working in this particular field a while.
Earlier this year I played with Erlang quite a bit, and despite the syntax annoyances, the actor model was very interesting. Steven mentioned explicit vs implicit receiving, which happens to be one of the bold stances this API takes. Erlang is an explicit receive model. Which means the code has to explicitly request the next message.
An explicit receive example with Ruby:
while message = receive
# do something with the message and then re-loop
end
An implicit receive example:
def some_method
# this will get called when a message is sent
end
The second example doesn’t look too foreign, and that’s because it’s not. The entire class becomes an API, and the messaging framework calls the appropriate method. When I worked with Erlang, I liked the Actor model, but I didn’t like the boilerplate code that was copy-pasted for every Actor.
I don’t expect everyone to prefer this type of messaging, but for me it makes the concurrency model more transparent, and the actors easier to read as well as easier to test.
That’s a lot of concurrency
As you can tell all my favorite talks all had some connection with concurrency and scale. That’s because I’ve been very interested in scaling Ruby applications. Not because I’m some outside developer who is evaluating Ruby as a language and concerned about FUD. It’s because I am a Ruby developer, and I’ve been writing in Ruby for the past couple years, but I have rarely heard talks addressing scaling.
There were many other great talks at the conference. For those on the fence on whether to attend next year, I definitely recommend it.
I’ve been developing in Ruby (and Rails) for the past 2.5 years. Over time, I’ve molded my own flavor of CRUD controllers and resulting specs. Unfortunately, it’s so different than the Rails and RSpec generated code that it takes me as long to alter the code as it does to create it from scratch. However, in laziness, I’ve pushed off writing my own generators. Until yesterday.
The Issue
Now I’m not a big fan of generated code. However I do agree that the templates fit the basic CRUD functionality nicely. Despite their usefulness, one of the things that irks me about generators is making changes and not being confident if the code generated is valid. Parse errors, invalid logic, and variable misspellings are easy examples to get tripped up on. So I wanted these generators to be tested. Sounds odd doesn’t it?
Enter Cucumber
Cucumber is a recent project released that replaces the RSpec Stories Framework. You use it very similarly to the older Stories, but since Cucumber is written with Treetop it provides a lot more niceties. I won’t give a tutorial of Cucumber here (perhaps in another post), but I do want to illustrate the flexibility of the testing framework.
When first picking up Cucumber, the immediate use that comes to mind is Rails Integration testing (which it is very useful for). However it can also be applied to domains outside of Rails and even web development. When writing these generators I mainly wanted to know: “when I use a generator, is all the code valid, and do all the tests pass?”.
Here’s an example of using Cucumber to describe my intentions:
Feature: Generating Controller Templates
In order to generate standard CRUD controllers
A Developer
Should be able to generate a CRUD controller and the resulting specs
Scenario: Generating Rails CRUD
Given I'm using a Rails 2.2 code base
When I generate 'my_controller customer'
Then 'app/controllers/customers_controller.rb' should be created
And 'spec/controllers/customers_controller_spec.rb' should be created
And all the tests should pass
And here’s the backing steps to accomplish the feature:
Given(/^I'm using a (.*) code base$/) do |key|
key = key.downcase.gsub(" ", "")
available_codebases = { "rails2.2" => File.join(codebases_path, "2.2") }
available_codebases.keys.should include(key)
blast_and_create_tmp!
extract_codebase!(key)
@current_codebase = File.join(tmp_path, key)
end
When /^I generate '(.*)'$/ do |command|
`#{@current_codebase}/script/generate #{command}`
end
Then /^'(.*)' should be created$/ do |file_path|
File.exist?(File.join(@current_codebase, file_path)).should be_true
end
Then /^all the tests should pass$/ do
output = `cd #{@current_codebase} && rake spec`
output.should_not match(/\s0 examples/i)
output.should match(/0 failures/i)
$?.exitstatus.should == 0
end
I have all the code in github if you want to see the working example of code.
Pretty straightforward and sexy.
I’ve heard a few people on Twitter not sure about the etiquette on following others. Particularly:
If you are following me, is it rude if I don’t follow you?
Twitter makes this difficult for two reasons
- Twitter is slightly more personal than other social networking applications
- Everyone uses Twitter in a different manner
I use Twitter as my Public Stream of Consciousness
This means about approximately 93.76% of my posts are dismissible. I have a very scientific process for analyzing my tweets that involves starting with “9″, and choosing three digits at random.
See? That’s a perfect example of the type of garbage that I flood the internet with.
However, unlike other people, I am perfectly ok with others not following me. I won’t be insulted if others don’t want to subject themselves to my endless stream of rants. If I do get upset, that’s my issue to deal with or adjust my behavior to suit.
So if Twitter is becoming less fun for you because I’m flooding your fire hose, but you feel I’ll think less of you if you don’t follow me back; don’t worry about it at all.