Posted by Rick DeNatale
Fri, 15 Feb 2008 13:29:00 GMT
One of the classics in the Smalltalk literature, which has also had a big influence on the Ruby community is Kent Beck’s “Smalltalk Best Practice Patterns”
, which captures the best practices for designing and coding Smalltalk programs. Back when it was published, I used to see Kent a few times a year, and happened to be in the Bay area when he made an author appearance at the Computer Literacy Bookstore in San Jose, where I got my copy, and the autograph shown here.
The Ruby language has many similarities with Smalltalk, so much of Kent’s advice applies to Ruby. I frequently hear prominent Rubyists mention the book.
On the other hand, Ruby is not exactly Smalltalk, so Kent’s book isn’t an exact fit to Ruby. I’ve been wanting to start writing about adapting some of these patterns to Ruby for a while, so this article will hopefully be the first in a series.
The Motivation For This Article
Recently on the ruby-talk forum a thread discussing accessor methods vs. direct instance variable access came up. This was a hot debate topic in the Smalltalk community back in the 90s, and Kent addressed it in two competing patterns in the book, one of which Ryan Davis (a.k.a ZenSpider) brought up in the conversation.
Read more...
Posted in ruby, smalltalk, best_practices | Tags bestpracticepatterns, kentbeck, patterns | no comments | no trackbacks
Posted by Rick DeNatale
Fri, 08 Feb 2008 15:38:00 GMT
One of my current Rails projects involves generating an RSS feed. While I was working on this the other night, it seemed to be working, so I deployed it to the staging server. Everything looked fine. If I fetched it with Firefox, the browser offered to let me subscribe to the feed with Google Reader, and if I used Safari I'd see a nice view of the feed just like I expected.
So I sent a note via our campfire to check it out, and a colleague replied that his Safari was saying that it was in an invalid format.
So I went to the W3 RSS Feed Validation Service and worked through the validation issues, after which his browser was as happy as mine.
Of course, having been through that, I wanted to make sure that RSS validation was covered in the specs for the project.
I went looking for an existing RSpec matcher, and found a matcher to validate XHTML but nothing for RSS.
I then found the feedvalidator gem which provides a Ruby interface to the SOAP interface to the W3 feed validator. You would think that W3 would be providing a REST interface! The gem already provides assertions for use with Test::Unit, so I just built an RSpec matcher.
class BeValidFeed
require 'feed_validator'
require 'tmpdir'
require 'md5'
def matches?(response)
return true if validity_checks_disabled?
v = W3C::FeedValidator.new()
fragment = response.body
filename = File.join Dir::tmpdir, 'feed.' + MD5.md5(fragment).to_s
begin
response = File.open filename do |f| Marshal.load(f) end
v.parse(response)
rescue
unless v.validate_data(fragment)
@failure = " could not access w3 validator to validate the feed."
return false
end
File.open filename, 'w+' do |f| Marshal.dump v.response, f end
end
v.valid?
end
def description
"be valid xhtml"
end
def failure_message
@failure || " expected xhtml to be valid, but validation produced these errors:\n #{@message}"
end
def negative_failure_message
" expected to not be valid, but was (missing validation?)"
end
private
def validity_checks_disabled?
ENV["NONET"] == 'true'
end
end
def be_valid_feed
BeValidFeed.new
end
I saved this as spec/be_valid_feed.rb
And in a view or controller spec, I can include this file, and test a response with:
response.should be_valid_feed
If you use this in a controller spec, you will need to tell RSpec to integrate_views, or you won't have much of a feed to check. If you use nested example groups, integrate_views needs to be inside the inner group.
Posted in ruby, best_practices, rails | Tags Rspec, rss, validation | 4 comments | no trackbacks
Posted by Rick DeNatale
Mon, 22 Oct 2007 14:43:00 GMT
Trans just posted a
question on ruby-talk.
It seems that he uncovered a conflict between the facet's library and the Ruby standard open_uri library. Open-uri defines a module called Meta which it uses to extend certain StringIo instances. The Meta module adds several methods including one called meta, which returns a hash of meta information. In two places in open_uri, the message "respond_to? :meta" is used to test whether a particular StringIO instance has been extended.
The problem is that Facets also defines a method in either Object or Kernel called meta which provides a clever way to access the singleton class of an object. So the respond_to? in open_uri was getting false positives.
Trans asked "So where lies the fault in this conflict? Are extensions the bad guy,
or is respond_to? really not a good oop concept? Or..?"
David Black replied that he thinks "this is just the age-old issue about adding methods to
existing classes and hitting conflicts. #respond_to? is relatively
dumb; it can't tell you what the method actually does. I think of it
as an important tool for "soft" duck typing, in contrast with "hard"
duck typing where you just send the object the message.
"
Reading this made me realize that a much better name than "soft" duck typing, for using kind_of?/is_a?, respond_to?, or other such "sniff first" techniques, is Chicken Typing
Read more...
Posted in ruby, best_practices | Tags chickens, ducks | 5 comments | no trackbacks
Posted by Rick DeNatale
Wed, 17 Oct 2007 17:01:00 GMT
Quick, in the Ruby expression:
What's the class of a?
Many beginning, and intermediate, rubyists whould instinctively say Array! The real answer is that given just this code, you don't know.
Recently, on the rails-talk mailing list there was a discussion of this idea from Jamis Buck. Jamis uses alias_method in ActiveRecord::Base so that he can use shortcuts like:
as a shortcut for:
This is particularly nice when playing with ActiveRecord in the rails console, but many seem to think that this should be made part of Rails core, and I don't see a real objection.
Now one objection raised by the folks who answer Array to the opening question is that, since ActiveRecord rows can be deleted, Person[2] might fail even though Person[1], and Person[3] work. The reasoning is that the [] makes it "look like an array" and arrays don't act like that.
To me this is a case of judging a book by looking at it's cover. Something which I strongly suggest needs to be resisted in order to achieve ruby mastery.
Let's have a look at a couple of "can't see past the cover" traps in Ruby.
Read more...
Posted in ruby_for_nubys, ruby, best_practices | 7 comments | no trackbacks
Posted by Rick DeNatale
Thu, 11 Oct 2007 10:47:00 GMT
Today on
Ruby Fleebie, Frank poses some ruby code to be "rubyized." I took this as an opportunity to do a little exposition of re-factoring under the watchful eye of
autotest.
So I've taken Frank's code and run it through the re-factoring machine several times. A word to the 'squeamish' because of the use case, there are a few words in the code which some folks, and spam filters might find mildly offensive, but we're all adults here right?
Now I've got to admit that I really came up with the final solution pretty quickly after seeing the blog post, but then I went back and eased up to it for pedagogical purposes. So if you're in the mood, sit down and lets re-factor some ruby!
Read more...
Posted in ruby, best_practices | Tags autotest, bdd, refactoring, tdd | 8 comments | no trackbacks
Posted by Rick DeNatale
Thu, 11 Oct 2007 10:47:00 GMT
Today on
Ruby Fleebie, Frank poses some ruby code to be "rubyized." I took this as an opportunity to do a little exposition of re-factoring under the watchful eye of
autotest.
So I've taken Frank's code and run it through the re-factoring machine several times. A word to the 'squeamish' because of the use case, there are a few words in the code which some folks, and spam filters might find mildly offensive, but we're all adults here right?
Now I've got to admit that I really came up with the final solution pretty quickly after seeing the blog post, but then I went back and eased up to it for pedagogical purposes. So if you're in the mood, sit down and lets re-factor some ruby!
Read more...
Posted in ruby, best_practices | Tags autotest, bdd, refactoring, tdd | 8 comments | no trackbacks
Posted by Rick DeNatale
Tue, 02 Oct 2007 11:04:00 GMT
Conventional wisdom in Ruby is to use do/end to delimit blocks which contain more than one line of code, and braces for one-line blocks. I've always tended to loosely follow this advice.
Thanks to ruby-talk, I just became aware of Jim Weirich's suggestion to use braces for blocks when the value is being used, and do/end for blocks which are primarily sequences of statements. Jim actually posted this over three years ago, and Joe O'Brien brought it up more recently.
On the whole, I like this idea and will probably adopt it to tune my use of do/end vs. braces.
Read more...
Posted in ruby, best_practices | Tags rubystyle | 3 comments | no trackbacks
Posted by Rick DeNatale
Tue, 04 Sep 2007 15:28:00 GMT
I’ve noticed that some rubyists like to use indentation to delineate method visibility.
The first time I noticed this was when Marcel Molina Jr. used it during the
charity testing workshop at the Ruby Hoedown.. I just encountered it again in at least one piece of sample code from Rob Orsini’s “Rails Cookbook.”
During the testing workshop, Chad Fowler expressed displeasure with this style, and I’ve got to agree.
Read more...
Posted in ruby, best_practices | Tags metaprogramming, style | 6 comments | no trackbacks
Posted by Rick DeNatale
Mon, 20 Aug 2007 18:25:00 GMT
Besides being a master werewolf, Marcel Molina Jr. gives great presentations!
In his keynote presentation on the second day of the Ruby Hoedown, Marcel talked about
“What Makes Code Beautiful”,
click on the link for the confreaks video of this session.
The talk started with an exploration of the classical Philosophy of Beauty, from Plato to Descartes.
Marcel summarized this by proposing that beauty lies in the balance between three aspects which,
at times, either strengthen or oppose each other:
Read more...
Posted in ruby, best_practices | Tags beautiful_code, ruby, rubyhoedown | 1 comment | no trackbacks
Posted by Rick DeNatale
Mon, 23 Jul 2007 00:59:06 GMT
If you subscribe to my feed, you might have noticed a mysterious "Testing Testing" article today.
I was trying a desktop blogging client called BloGTK, and it doesn't appear to honor the checkbox in the UI which is suppose to prevent actually posting an article.
Posted in best_practices | no comments | no trackbacks