Ruby Hoedown Day 1
by Jason on Aug 08, 2008
Innovation in Ruby
This one started off with a couple of losers talking about innovation in Ruby in the last year. It sucked. We can move on.
Cloud Computing
Robert Dempsey of Atlantic Dominion Solutions gave an extremely interesting talk titled The Future is Now: Leveraging the Cloud with Ruby. Rob is angry like a mad cow because some jerk keeps saying that Rails can't scale. He's angry because he says that Rails can scale as long as you know how to scale it. He gives a definition of scalability and goes in to using Amazon Web Services to scale your site using cloud computing. I think he'll continue to be angry because I'm still going to say it doesn't scale. Weekly.
In unrelated news, Rails can't scale.
Taking advantage of the cloud
You don't have to buy any hardware or support any infrastructure. There are a few different options for taking advantage of cloud computing: AWS itself, Mor.ph, RightScale, Heroku, Joyent Accelerator, and Vertebra. There's also DIY clouds: PoolParty, Scalr, ElasticRails, WeoCEO. He gave us the disclaimer that he is partnered with a couple of them.
RightScale is expensive-- the "Cadillac" of cloud hosting.
Heroku is free for now but will depend on the amount of work later. On the upside it provides automatic scaling and you can edit code in the browser. When he said that I was thinking about how I didn't care for that much and Rob confided that he doesn't like that either.
Joyent Accelerator. It's pay as you go on good hardware with scalable storage. The downside is that you have to call in to scale your app and that you might have some trouble. He says it's not really cloud computing because you have to call in. I'm not sure why that's different from pressing some buttons in a web interface.
PoolParty is free but it's not production ready and there's little documentation. Scalr is free or $50/month. ElasticRails is safe for a virtual environment and provides a GUI management console. It's on 2.0.2 so it's kind of old. WeoCEO provides auto load balancing and scaling but it's command line only. Also the name is strange.
Here's what got me that I didn't know: a standard small EC2 instance will cost $432 / month. This doesn't even include S3 or SimpleDB charges if you're using them. Why is it so expensive? Since you don't know if your server will suddenly go down you need to have redundancy.
During the questions portion of the talk, the topic of mail servers and spam came up. Mail coming from EC2 instances doesn't get past spam filters. Joe O'Brien suggested using AuthSMTP or an external SMTP server for sending mail from a Rails app running on EC2. Truth be told, I would do this regardless of where an app was hosted. Mail hosting is tricky and a company such as AuthSMTP usually has their stuff together. You probably have enough to worry about with your application so just let pros handle it.
Mock Dialogue
This is a mock dialogue about mocking from Jim Weirich and Joe O'Brien. They take the position of a master and novice going through a testing refactoring. It was really interesting to see a reenactment of the evolution of creating and using mock and a mocking framework.
The presentation starts with Joe calling help-desk support because his login is disabled. It turns out that he was using his actual login for his test suite and it got disabled after 3 failed attempts. At first they create a FakeLogin class but eventually move to mocking. This is where Jim says something awesome: "Mocks are not magical. They are just a simple extension of fake test objects." This is very insightful -- I wish I had heard this before I got in to mocking and stubbing and had to figure it all out myself. This act ends with them refactoring the test method to use flexmock.
In the next act they end by refactoring this example in the app code:
1 2 3 4 5 |
def cost_to_send(package) receiving_station = package.customer.address.zip_code.get_closest_station cost_to_send_to(package) end |
To something closer to this:
1 2 3 4 |
def cost_to_send(package) receiving_station = passage.get_closest_station cost_to_send_to(package) end |
Ruby Best Practice Patterns
Rein Henrich starts out the talk with some definitions and concepts of best practices. He then goes on to say that he's come up with a new paradigm: Unfactoring. This is job security through code obscurity. It is the process of taking well designed software and, through an iterative series of small changes, making it unmaintainable by anyone but you. He goes through and shows how to Unfactor using Capistrano as an example. This part of the talk is hilarious and I'm sure we've all seen code like this. I haven't asked but I'm sure he'll be ok with reproducing two of the tips here:
- Don't be DRY. If you have to fix code in 15 different places, that's 15x the amount of money you will make.
- Don't clearly communicate your intent. Name your methods in pig latin or incomprehensible speech
Rein goes on to give his actual presentation. Maintainability is an important consideration. You'll read your code much more than you write it. Your code is legacy code as soon as it's written. Software costs for more to maintain than write. It's like Fight Club for code.
Some patterns from the talk:
Compose method: how do I divide a class in to methods? Don't have a 20 or 30 line method that's hard to scan. Each method should perform one simple tasks with a method revealing name. See capistrano deploy method.
Execute around method: Do stuff, yield, then ensure end block closes. Like reading a file, for example, don't do this:
1 2 3 4 |
f = File.open('tmpfile', 'w') f.write('omfg') f.close |
1 2 3 4 |
File.open('tmpfile') do |file| file.write('omfg') end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class File ... def self.open(path, mode="r") raise Errno::ENOENT if mode == "r" and not exists?(path) f = open_with_mode(path, mode) return f unless block_given? begin yield f ensure f.close unless f.closed? end end end |
Yield and return: how can i send multiple messages to the same object? Call each method in turn? @$!# no! Wrap new to accept a block to a new object like they do in will_paginate:
1 2 3 4 5 |
def self.create(page, per_page, total=nil) pager = new(page, per_page, total) yield pager pager end |
1 2 3 4 5 |
def tap yield(self) self end |
Method object: How can i write a method where many lines of code share the same parameters and temp variables? Create an object to represent an invocation of the method. This way everything can see the params:
1 2 3 4 5 6 7 |
def dot_file_contents(graph) output = [] output_classes_and_i_methods(graph, output) output_i_methods_and_ids(graph, output) output end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
def dot_file_contents(graph) OutputGenerater.new(graph).generate end class OutputGenerator def initialize(graph) @graph = graph @output = [] end attr_accessor :graph, :output def generate output_classes_and_i_methods(@graph, @output) output_i_methods_and_ids(@graph, @output) @output end end |
The point is this: Figure out what problems each pattern solves. Look out for more examples of patterns in the ruby libraries you already use. Apply these patterns to your own code. This was an incredibly useful and insightful presentation.
Lightning Talk Summaries
- God: We're getting preachy. God is a ruby version of monit but it's configurable.
- BDD with RSpec: Test all the f-------- time. If you don't test you're killing babies.
- Truthy gem: there's only false and nil in ruby.
- GChartRB: It makes pretty charts.
Obie Fernandez
Hashrocket is a sponsor of the conference and Obie gets to talk for a bit before Chris's keynote. This turns out to be a quick but valuable talk and an extended version of what he did at RubyFringe. It's about running a successful company.
Marketing: Looking good is a must. Hashrocket paid $25,000 for their logo, and that was just because they knew the guys.
Qualifying: Make sure new leads can reach you easily. Give yourself constraints and keep good track of your leads.
Closing: Always be closing. Use master service agreements with attached statement of work documents.
We got some great book recommendations. I tried to get Obie's Amazon affiliate code in here but I'm not sure if it took.
- Never Eat Alone by Keith Ferrazzi.
- Secrets of Power Negotiating by Roger Dawson.
- Predictably Irrational by Dan Ariely.
He finishes with this: The best solution for successful client management is doing remarkable work. It's a great message and the energy and passion he exudes for what he does is tangible.
Chris Wanstrath Keynote
Chris has no slides and reads an essay. In the future there will be more Ruby everywhere. We have to trust him because he's keynoting. There will be more Ruby Gem servers. Up to 3 books on Ruby may be released in the future. Some day we will be coding in Rails 3.0 and Merb 1.0. This is a very entertaining keynote. The future he describes (minus numbers) is essentially the present.
He talks about John Von Neumann and the invention of the personal computer. Mathemeticians built the first computers to build a bomb. They are the ultimate hackers. He likens it to several high profile current projects that started out as side projects. This will become the theme of his keynote.
A long time ago, he got a job writing php for a trucking company. There were no constants and no version control at this job. They had multiple versions of the same file in the same directory. His first order of business was to extract magic numbers and instantiate subversion. It was at this job that he found Rails and YAML. He wrote SPYC -- a YAML php interpreter for php. He put the code on sourceforge. It was a huge hit in the first month -- at least 70 downloads, as he says. He later goes on to get a job at Gamespot. His work experience didn't get him the job. SPYC did. At this point he realizes that you don't need to make money from code but you can make money thanks to code.
He wraps up his speech with a challenge: Stop reading RSS. Read the blog authors on twitter. Visit a blog aggregator like PlanetRubyOnRails once a month. Stop reading books. Talk to friends/coworkers. The best way to learn about patterns, practices, and idioms is to read open source code. You lose time you could be spending doing a side project and other people will condense and filter the information for you.
I feel like noting, here, that was one of the reasons we started the Rails Envy podcast: filter the news. We distill what's important and new so that you don't have to.
He closes with the following message: Start a side project. You never know what it will grow in to. He did a laundry list of side projects that eventually got him to where he is today. It's a really inspiring and occasionally funny speech.
I'll try and live blog the event tomorrow throughout the day.
Tags: conference |
Meta:
7 comments |
permalink

RSS
iTunes
“I think he’ll continue to be angry because I’m still going to say it doesn’t scale. Weekly.”
I lol’d.
I’d like to openly admit how in regards to testing I’m running an abortion clinic over here.
Eleo: I’m reading your Twitter in my RSS—Chris’ challenge just confuses me.
Thanks for the mention guys. I look forward to seeing your slides. As for the EC2 costs, a standard deployment – 6 servers – costs $432/month using small instances.
Hey, nice blog post.
Theres a small typo error there: def cost_to_send(package) receiving_station = passage.get_closest_station cost_to_send_to(package) end
The right one is “receiving_station = package.get_closest_station”
Regards
Link to Predictably Irrational-book is broken.
Nice compact write-up. Thanks.
Great writeup. I (and the rest of the Hashrocket crew) had a blast hanging out with you railsenvy guys at the Hoedown.
I’d like to make a minor correction in a code example you’ve (graciously) recreated from my talk. Instead of this:
output_classes_and_i_methods(@graph, @output) output_i_methods_and_ids(@graph, @output)
you can simply use:
output_classes_and_i_methods output_i_methods_and_ids
because the @graph and @output instance variables are available in the scope of the instance methods. This is really the point of using the Method Object pattern: to prevent repeated passing of the same arguments to a series of methods that compose a behavior by extracting them into a class where they can be a part of the object’s state. The attr_accessors are there to facilitate the refactoring by allowing the methods to continue referring to graph and output instead of @graph and @output.
Nice