I’ll be giving the first presentation, a tour of Ruby Facets. Facets is a pretty huge library (even after they moved some really neat parts into their own projects), and it’s crazy to think we could cover it all in one night. I’ll quickly touch on the simple features, just to let you know they’re there, and I’ll spend more time with some of the interesting parts. If you’re stuck, it’s a good chance Facets has what you need; the trick is knowing it’s there, and where to look – I want to point out enough of Facets to help you with that.
I’ll also start a Tour of Facets series here, starting with this post. I’m aiming for two to four posts a month, and will cover everything in the presentation, and then some. So, on with the tour…
compare_on and equate_on
Remember the first time you saw
attr_writer? These tiny helpers got me excited about ruby, not just because they meant less typing and DRY-er code, but because they meant I could make helpers to generate methods, too, if only I could think of a reason to do it.
Facets has a great example of why you’d want to do that:
Most ruby programmers know you can make your objects sortable by defining
<=>, the spaceship method, on them. Typically, you wind up delegating to some attribute:
1 class Person 2 attr_reader :fname, :lname 3 def initialize(fname, lname) 4 @fname, @lname = fname, lname 5 end 6 def <=>(person) 7 @lname.<=>(person.lname) 8 end 9 end
compare_on, which generates the spaceship method for you, based on that attribute. Not only that, but you can
compare_on multiple fields, and it handles the hairy logic for you automatically:
1 require 'facets/compare_on' 2 3 class Person 4 attr_reader :fname, :lname 5 def initialize(fname, lname) 6 @fname, @lname = fname, lname 7 end 8 compare_on :lname, :fname 9 end 10 11 people =  12 people.push Person.new('Adam', 'Smith') 13 people.push Person.new('John', 'Adams') 14 15 people.sort #=> John Adams, Adam Smith
Correctly implementing the spaceship operator isn’t too hard, but object equality gets tricky in any language. Facets helps you here by implementing ruby’s main three equality methods for you:
1 require 'facets/compare_on' 2 3 class Person 4 attr_reader :fname, :lname 5 def initialize(fname, lname) 6 @fname, @lname = fname, lname 7 end 8 equate_on :lname, :fname 9 end 10 11 a_pres = Person.new('John', 'Adams') 12 another_pres = Person.new('John', 'Adams') 13 [a_pres].include?(another_pres) #=> true
Again, you can equate on multiple attributes (
lname), and it handles all the details for you. Hope to see you at the Hartford Ruby Brigade!