RailsConf 2010 Wrap-Up

Posted by Larry Karnowski Fri, 11 Jun 2010 21:36:00 GMT

My RailsConf experience this year was much better than last year's, despite not being a speaker this year. Baltimore felt like a better fit for us than Vegas. Plenty to do right near the conference center, but nothing so distracting that the conf felt empty or sparse.

The range of talks was interesting -- a bit heavy on the back-end talks, but that's typical of a technical conference. People like crunch.

Interesting new bits of culture:

  • DHH usually gives the high-level motivational keynote, and Yehuda gives the deep-dive tech overviews, but this year they traded roles. It didn't really work for either, with both having only mediocre keynotes. (I'm all for experimenting, and I'm glad they did. Next year, though, let's get back to normal.)
  • Lots more live music at the conference, especially before/after keynotes. I really enjoyed this.
  • A certain person showed his butt on-stage (figuratively, thankfully) by defaming a business competitor. No need to mention names here and increase their Google-ability, but you know who I'm talking about. Very childish.
  • Lastly, the conf, while still hip & fun, is definitely showing it's maturation. Several keynotes, most notably the Engine Yard talk show, which was fun, still felt like a commercial. Worse, instead of a fun "MVC"-style video by Greg Pollack, we had an actual commercial for his new Rails 3 screencasts. Not terrible in either case, just new.

My big take-aways from this year:

  • Chris Wanstrath's ideas of what a good open source maintainer should be feel true: be transparent and ubiquitous; have lots of redundant information sources (blogs, email, getting started guide); and have a philosophy and communicate it, for example, Resque's is "zero features, only plugins".
  • Agile software is real engineering for software, not what folks call "software engineering" in schools. (Thanks to Glenn Vanderburg for a great, great talk.)
  • Multi-core is incredibly important -- Event Machine and especially Clojure. Very cool to see the Clojure-love (or at least, interest) at RailsConf this year.
  • Rails is still fun, but it "arrived" a long time ago and is now a toolset rather than a lifestyle. I expect RailsConf to be officially boring in 2012.

Lastly, a take-away for my own personal life: writing is more effective (for me) than speaking. I will try hard to remember that.

All in all, RailsConf 2010 was fun, educational, and inspiring. It always feels good to go back to the well.

Tags , , ,  | no comments

Silencing Rails 2.2 "gem has no specification" messages

Posted by Larry Karnowski Mon, 02 Feb 2009 23:14:00 GMT

Since upgrading to Rails 2.2, you might be seeing lots of messages like this:

config.gem: Unpacked gem blah-1.0.0 in vendor/gems 
has no specification file. Run 'rake gems:refresh_specs' to fix this.


Running 'rake gems:refresh_specs" takes care of most of these, and upgrading any remaining gems will usually take care of the rest. But it seems like most of the projects I'm on still have one or three home-grown, really old, or really odd gems that just don't have specs. I should write specs for these, I know. So I let Rails complain... but...

But now, months later, I'm realizing there are just a few gems I'm never going to upgrade. And I'm seeing these messages... A LOT. Every time I run a test in TextMate. Every time I run tests from rake. Every time I run almost any rake task, period. It's driving me MAD!

So, if you've been a good boy or girl and taken care of most your gems, and a few are still hanging around, here's the magic to make those messages go away:

In your config/environment.rb file:

# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')

# Add this line at your own risk!  
Rails::VendorGemSourceIndex.silence_spec_warnings = true

Rails::Initializer.run do |config|

Tags , , , ,  | 6 comments

Great Lakes Ruby Bash

Posted by Larry Karnowski Fri, 10 Oct 2008 14:07:00 GMT

I'm flying to Ann Arbor, Michigan later today to give my "Usability on Rails" talk at the Great Lakes Ruby Bash tomorrow. If you're attending, please drop me a note (as I don't know a soul that'll be there). I'll also be hanging out on IRC in #glrb and #midwest.rb. I'm hoping to meet some new friends and convince some geeks of the wonderful ways of "teh us4b1l1t13z"!

Tags , , , , , , ,  | 2 comments

Always Pass a Block When Using alias_method_chain

Posted by Larry Karnowski Fri, 29 Aug 2008 15:00:00 GMT

If you're using Rails' alias_method_chain mechanism, please make sure that your new method always takes a block and passes that block up the chain, even if you don't need the block yourself. Consider this being a good "alias_method_chain" neighbor. Here's why -- if you don't, no one who comes along behind you can add a block to the chain. You've effectively "block-blocked" them.

Here's an example. I wanted to add some functionality to Rails' error_messages_for method. Specifically, I wanted to be able to pass a block to it that implemented a tiny DSL for massaging the errors output before passing them up the chain to the normal error_messages_for functionality. I implemented this by adding an alias_method_chain layer on top of the error_messages_for.

In my tests this worked fine, but when I put it in my actual Rails project, the method just stopped working. It took me a while to find that another developer on the project was also alias_method_chaining the error_messages_for, but was not taking a block, and thus not passing it up the chain. In effect, he was dropping my block on the floor. No good.

So here's the template you should follow when creating an alias_method_chain:

def method_with_something_cool(arg1, arg2, &block)
  ... your custom pre-chain code ...

  method_without_something_cool(arg1, arg2, &block)

  ... your custom post-chain code ...
end

alias_method_chain :method, :something_cool

Call the old method with a block even if the old method never took a block! Don't be a cock-blocker! Err.... block-blocker!

Tags , , ,  | 3 comments

Recurring Dates in Ruby iCalendar Using Runt, Ep. 1

Posted by Larry Karnowski Fri, 14 Mar 2008 20:00:00 GMT

What began as my "learn to write Ruby" project almost a year ago is finally taking shape thanks to Open Source Fridays at my new place of gainful employment -- Relevance!

iCalendar is the open standard for those ubiquitous *.ics files. These are the files we read and write with Apple's iCal, Google Calendars, and other standards-based calendaring programs. (Read that as "all calendars except Outlook.")

Ruby has a partial implementation of the specification at the Rubyforge iCalendar project. However, it's missing one important feature -- recurring dates.

For example, that 1pm Monday meeting that you have every week? The Ruby iCalendar project doesn't support it. Now, don't give the iCalendar folks a hard time -- recurring rules are damn hard to implement, and they've spent their time doing the most important stuff -- reading and writing the *.ics files. Also, since most webapps nowadays just export important dates as one-off dates anyway -- the Ruby implementation of iCalendar just hasn't really needed a recurring date implementation. (But we really want one!)

I started by brute forcing my way through the massive list of examples in the RFC 2445. I foolishly thought it was just a matter of hacking out an example using TDD and then refactoring all previous examples. No... I've found out it's just not that simple. (And let's face it, if that's all it took then the Ruby iCalendar folks would've added it ages ago! Poor, naive Larry.)

Then at one of the Raleigh.rb hack nights, Nathaniel Talbott recommended that I look at a little-known Ruby toolkit called Runt. This toolkit implements something called temporal expressions. You remember that weekly 1pm Monday meeting you have? Come to find out that with Runt they look like this:

  DIWeek.new(Mon) & REDay.new(13, 00,14, 00)

You read this as: "day in week: Monday, and range each day: from 1pm to 2pm". You can use this temporal expression either to generate a list of matching DateTimes or to check if a given DateTime matches. Very powerful stuff, incredibly powerful. (By the way, this all comes from an idea by Martin Fowler and implemented by Matthew Lipper.)

So, now my problem looks like this:

  • Take the iCalendar recurring rule (called a RRULE) syntax and convert it into an appropriate Runt temporal expression.
  • Let Runt do all the work.

I'm home free! Or... well, I'm not. Come to find out, Runt only implemented about 60% of what I needed to implement the full iCalendar spec. The biggest missing piece was the ability to handle dates at a "week precision". That is, I need to be able to know if a given day and another given day are in the same week. I finally got that feature in today!

So now with the weekly precision and a few other temporal expressions I added, I now have all but 14 of the 41 examples working as Test::Unit tests in Runt! That 65% may sound a little low, but it is actually something like 80% of the total iCalendar functionality. It's definitely all the key features. It definitely supports recurring rules based on a given day and month (mark November 15th on your calendar! it's my birthday!), and it definitely supports week-based recurring rules like the 1pm Monday meeting above. What else do you need?

Here's the patch for Runt's current Subversion trunk. I'm now working on my old iCalendar code. I'm going to do the same trick of using the RFC examples as Test::Unit tests.

I'm hoping to have more next week!

Tags , , , , , ,  | 8 comments

Playing MP3s with Rails! (SoundManager2 Rails Plugin)

Posted by Larry Karnowski Fri, 07 Mar 2008 14:55:00 GMT

So you want to play MP3s from your web application? The best tool I've found for that is Scott Schill's SoundManager2 Javascript API. It invisibly uses a very small Flash object to play the MP3s, and the whole thing is very scriptable through Javascript. Getting it set up is not difficult, but it's a little bit of a pain -- so I wrote a Rails plugin!

Here's what you do:

  • Install the Rails plugin like this: ./script/plugin install http://soundmanager2.rubyforge.org/svn/soundmanager2

  • Then run the generator to get the SoundManager2 files in your app: ./script/generate sound_manager2

  • You'll notice the following files are created: public/soundmanager2.swf
    public/javascripts/soundmanager2.js
    public/javascripts/soundmanager2-jsmin.js
    public/javascripts/soundmanager2-rails.js
    public/images/SoundManager2/pause-control.gif
    public/images/SoundManager2/play-control.gif

  • Then, to add basic play/stop functionality to your view, add the following to your ERB file:

<%= javascript_include_tag :defaults %>

<%= 
  sounds = [
      ["sound1", "http://url/to/sound1.mp3"],
      ["sound2", url_for(:controller => "sounds", :action => "listen", :id => "2")],
  ]
%>  

<%= initialize_sounds(sounds) %>

<div>Play sound 1: <%= toggle_sound "sound1" %></div> 
<div>Play sound 2: <%= toggle_sound "sound2" %></div>  
  • Or, if you want more functionality, start calling the SoundManager2 Javascript APIs directly.

Here are some screenshots of this plugin in action. Here you're looking at part of a table with MP3s ready to play...

And then here you've clicked on the middle song. Note the MP3 will start playing immediately, even while it's downloading!

Clicking the "pause" button will stop the playback.

Here are the project links:

Oh, and by the way, both the Javascript API and Rails plugins are released with BSD/MIT licenses!

I'm definitely wanting to put more "off-the-shelf" behavior in this plugin, but for now the simple play/stop behavior is all my application needs. If you need something else, or want to send me some patches, please shoot me an email!

Tags , , , , ,  | 2 comments