Floppy Fail
Here’s a geeky image, courtesy of The FAIL Blog.
Next Tuesday is the second Tuesday of the month, which means: Ruby/Rails Project Night, hosted by TSOT!
The Quick Version
- When: Tuesday, February 12th, 2008:
- Doors open around 5:30 p.m.
- Presentations begin sometime between 6 – 6:30 p.m.
- Arrive early to get fed!
- Where: TSOT developer office, 151 Bloor Street West (just east of Avenue Road), Suite 1130
- Admission: FREE (but please register!)
- Register with: Corina Newby or Joey deVilla
About Ruby/Rails Project Night
Ruby/Rails Project Night is a Toronto-area gathering held at the TSOT developer office on the second Tuesday of every month. It’s an event that lets people developing projects in either Ruby or Ruby on Rails show them off in front of their peers in 20-30 minute presentations. Presenters are encouraged to go into as much technical detail as they like (even showing the code, if they’re so inclined) and cover all sorts of aspects of their projects, from programming issues to visual design and usability to the business of making a living off their software.
Whether you code in Ruby and Rails for a living like we do, dabble in it in your spare time or are just curious as to what the fuss is all about, we encourage you to come to our office next Tuesday for Ruby/Rails Project Night! It’s a chance for you to see software that’s being developed right here in town and to mingle with other developers interested in Ruby and Rails. We provide food and drink, so you can focus on the presentations and not your grumbling stomach.
Who’s Presenting
Yours Truly will start the night with an opening monologue to get things going, after which I’ll be followed the the evening’s main presentations:
- How to Avoid Hanging Yourself in Rails, by Rowan Hick. This presentation is subtitled “or: Optimizing Your ActiveRecord Associations”.
- EasyBrandingTools.com: Mike Bowler and Steve Vetzal will talk about their project that helps new businesses be memorable.
- CRMS – Clinical Research Management System. Luke Galea will present this project, a Rails and Prolog/XSB application that manages drug and procedure trials at some of the biggest hospitals in the U.S..
What Happened at the Last Ruby/Rails Project Night?
Check out this article, which has a quick write-up and photos.
Welcome to the third installment in my series of articles on the methods of Ruby’s Enumerable
module. This series is meant to address some of the shortcomings in the official documentation
In case you missed the first two, here they are:
In this installment, I’m going to cover the find
method. This is a particularly interesting one because it covers detect
/find
‘s little-talked about optional parameter.
detect, a.k.a. find
Enumerable#detect
/ Enumerable#find
- A block containing the criteria.
- An optional argument containing a proc that calculates a “default” value — that is, the value to return if no item in the collection matches the criteria.
- The first item in the collection that matches the criteria, if one exists.
- If no such item exists in the collection:
nil
if no argument is provided- The value of the argument if one is provided
detect
and find
are synonyms — you can use either. I personally prefer find, as it’s shorter and a good match with a related method, find_all
. I also just think that “find” conveys the method’s functionality much better than “detect”.
Using detect
/find
with Arrays
When used on an array without an argument, detect
/find
passes each item from the collection to the block and…
- If the current item causes the block to return a value that doesn’t evaluate to
false
,detect
/find
stops going through collection and returns the item. - If no item in the collection causes the block to return a value that doesn’t evaluate to
false
,detect
/find
returnsnil
.
classic_rock_bands = ["AC/DC", "Black Sabbath", "Queen", "Scorpions"] classic_rock_bands.find {|band| band > "Led Zeppelin"} => "Queen" classic_rock_bands.find {|band| band > "ZZ Top"} => nil
Using the optional argument is a topic big enough to merit its own section, which appears later in this article.
Using detect
/find
with Hashes
With hashes, detect
/find
passes each key/value pair in the hash to the block, which you can “catch” as either:
- A two-element array, with the key as element 0 and its corresponding value as element 1, or
- Two separate items, with the key as the first item and its corresponding value as the second item.
detect
/find
is one of those methods of Enumerable
that works a little oddly since:
- The result it returns depends on the order of the collection
- We’re always told that hashes don’t really any order (there seems to be one, but it’s shrouded in mystery).
metacritic_ratings = {"Juno" => 81, "American Gangster" => 76, \ "Golden Compass" => 51, "Meet the Spartans" => 9} => {"American Gangster"=>76, "Golden Compass"=>51, "Juno"=>81, "Meet the Spartans"=>9} metacritic_ratings.find {|metacritic_rating| metacritic_rating[1] > 80} => ["Juno", 81] metacritic_ratings.find {|film, rating| rating > 80} => ["Juno", 81] metacritic_ratings.find {|film, rating| rating > 90} => nil
Using detect
/find
with the Optional Argument
detect
/find
‘s optional argument lets you specify a proc or lambda whose return value will be the result in cases where no object in the collection matches the criteria.
(Unfortunately, a complete discussion of procs and lambdas is beyond the scope of this article. I highly recommend looking at Eli Bendersky’s very informative article, Understanding Ruby blocks, Procs and methods.)
I think that the optional argument is best explained through examples…
classic_rock_bands = ["AC/DC", "Black Sabbath", "Queen", "Scorpions"] # Let's define a proc that will simply return the default band's name # for cases where none of the bands in the array meets the criteria. default_band = Proc.new {"ABBA"} # Procs are objects, so using a proc's name alone isn't sufficient to invoke its code -- doing so will simply return the proc object. default_band => #<Proc:0x00553f34@(irb):31> # (The actual value will be different for you, but you get the idea.) # To call a proc, you have to use its "call" method: default_band.call => "ABBA" # detect/find calls the "call" method of the object you provide as the argument # if no item in the collection matches the criteria in the block. classic_rock_bands.find(default_band) {|band| band > "Led Zeppelin"} => "Queen" classic_rock_bands.find(default_band) {|band| band > "ZZ Top"} => "ABBA" # Let's try something a little fancier, and use a lambda this time. # The differences between procs and lambdas are very fine -- I suggest # you check Eli Bendersky's article for those differences. random_band = lambda do fallback_bands = ["Britney Spears", "Christina Aguilera", "Ashlee Simpson"] fallback_bands[rand(fallback_bands.size)] end # Let's give it a try... classic_rock_bands.find(random_band) {|band| band > "ZZ Top"} => "Britney Spears" >> classic_rock_bands.find(random_band) {|band| band > "ZZ Top"} => "Ashlee Simpson" >> classic_rock_bands.find(random_band) {|band| band > "ZZ Top"} => "Christina Aguilera"
To see a “real” application of detect
/find's
optional argument, see this Ruby Quiz problem.
SEO Tips for Rails Apps
Default Routes Considered Harmful, and Other Rails SEO Tips covers SEO for Rails apps, with both on-page SEO tips (Prettier URLs, Better Title Tags and DRY in Content) and off-page SEO tips (Easy Linking and Bookmarks).
10 Reasons to Learn and Use Regular Expressions: Yes, they’ll drive you crazy every now and again, but as the authors of Programming Perl wrote, “if you take ‘text’ in the widest possible sense, perhaps 90% of what you do is 90% text processing.”
Adding Type Checking in Ruby
Here’s an article on adding type-checking to Ruby which pays a lot of attention to the Types framework.