|
Red Squirrel Reflections
Dave Hoover explores the psychology of software development
|
|
Wed, 28 Feb 2007sudo gem install facets require 'rubygems' require 'facets/more/times' puts 0.weekdays.from_now # Wednesday (today) puts 2.weekdays.from_now # This Friday puts 3.weekdays.from_now # Next Monday puts 4.weekdays.ago # Last ThursdaySee http://facets.rubyforge.org/src/lib/facets/more/times.rb for details. Fri, 23 Feb 2007Jamis posted yet another nugget of wisdom. This one was about Ruby's method visibility, which can be tricky for people coming to Ruby from Java or C#. Jamis left one aspect of the protected access level as an exercise for the rest of us, so I figured I'd write up an example that helps illustrate when you would use protected vs. private.
class Sibling
def ask(sib)
sib.tell
end
def spy_on(sib)
sib.secret # will always complain
end
protected
def tell
secret
end
private
def secret
"Charlie tooted"
end
end
rose = Sibling.new
ricky = Sibling.new
begin
puts ricky.tell
rescue
puts "Ricky will only tell another sibling"
end
begin
puts rose.spy_on(ricky)
rescue
puts "Ricky complains when Rose tries to find the secret"
end
puts rose.ask(ricky) # Ricky will tell if Rose asks nicely
One of the main differences for Java developers is that objects of the same class can't see each other's private methods.
Thu, 22 Feb 2007After helping Ryan with some routing issues in which a single character (a period) was the cause of confusion. I nearly fell off my chair laughing after this little interchange...
Ryan: yeah, the breakthrough was the dot.
thanks for the help
:-)
Dave: it's always one stupid character
Ryan: yes, and that character is often me
Sat, 17 Feb 2007Relentless Simplicity with ActiveRecord The Active Record pattern is a wonderfully simple and sufficient approach to ORM on many projects. I first used it in Java and it worked well on a small project. But in a staticly typed language like Java, using Active Record is limiting and/or awkward. It wasn't until I starting using ActiveRecord in Rails that I saw just how powerful this pattern could be when applied within a more flexible, readable language. Where nasty getter/setter hell and XML configurations are the standard in Java, we get clean, readable classes and objects in Ruby. One of the things we do at Obtiva is provide coaching and development for Rails projects that are in trouble. I call them rescue missions. We've found that the downside to Rails' power and simplicity is that people can crank out functionality with minimal understanding of how to write maintainable, scalable software. It's only a matter of time until they hit a wall, and that's where we step in. We find people usually get into trouble with ActiveRecord when they allow themselves to write ugly code. I'm sure that there are some cases where ActiveRecord doesn't do what you need and an ugly solution is required, but I think those cases are exceptionally rare for most Rails apps. During one of our rescue missions, I discovered a fat controller with lots of calls to find_by_sql. Again, I'm sure there are cases where this nasty method is needed, perhaps for optimization, or for some odd cases that I can't imagine (since I've never used it), but this was just plain ActiveRecord abuse. Most of us aren't aren't writing abusive ActiveRecord code, but many of us need to be more relentless in our pursuit of clean, readable, ActiveRecord usage. We're kicking off a Rails e-commerce project so I downloaded a copy of the Rails e-commerce book to brush up on ActiveMerchant. By the way, I recommend the book to anyone coming to Rails with an immediate need to write an e-commerce site. It's also a good book for anyone wanting to see an example of TDD in Rails. But on page 175, I found a snippet of code that spurred me to write this post ... it wasn't ugly ActiveRecord code, but I would go so far as to say that it is just plain bad.
class Post < ActiveRecord::Base
belongs_to :category
def self.find_all_in_category(category)
category = Category.find_by_name(category)
self.find :all, :conditions => "category_id = #{category.id}"
end
...
end
I can read this code and understand what the author was trying to do. The method is returning all of the Posts for a given Category name. But what happens if the call to Category.find_by_name returns nil? And why would a simple thing like this require 2 separate calls to the database?
SELECT * FROM categories WHERE (categories.`name` = 'foo') LIMIT 1 SELECT * FROM posts WHERE (category_id = 1)This is an example of not pushing hard enough to keep your code clean and simple. The first solution you can think of isn't necessarily the simplest. Don't be satisfied with anything less than elegance when you're using ActiveRecord and you'll be much better off. Here's how I would rewrite that little method:
class Post < ActiveRecord::Base
belongs_to :category
def self.find_all_in_category(category_name)
category = Category.find_by_name(category_name, :include => :posts)
category ? category.posts : []
end
...
end
Which, thanks to the eager loading of :posts, would result in just 1 call to the database, and (to me) reads better.
Wed, 14 Feb 2007Victoria's Journey toward Craftsmanship I've completely neglected my apprenticeship patterns over the last year. Ruby and Rails is partly to blame for this. But the other reason is that I have an opportunity to apply Pete McBreen's ideas for the first time and, to me, that takes priority over almost anything else in my professional life, because opportunities like this don't come around very often. Stories like the one that Victoria just related over on DevChix get me very excited about the future, and reinforce the direction the apprenticeship patterns are headed. [/craftsmanship] permanent link Sun, 11 Feb 2007
Even cooler still, Obtiva has just hired our first apprentice (and female), Victoria Wang. This is another important step toward establishing our software studio in Wheaton. Apprentices bring enthusiasm and an appetite for learning that inspires. On top of this, Victoria brings some other important qualities with her: excellent visual design abilities (that's her RailsConf-inspired drawing) and a non-male perspective. Welcome Victoria! |