Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
class User # This code is buggy and needs several test cases to assert the bugs are fixed. def self.friend(user1, user2, type) r = Relationship.new r.user1 = user1 r.user2 = user2 r.type = type code = 0 if !["friend", "spouse"].include? type type = "undefined" # BUG! We meant to write `r.type = "unknown"`. We are completely reliant on tests to catch it. code = 1 end r.save! r_other = Relationship.find_by_sql(...) logger.info "Interesting new relationship!" if r = r_other # BUG! We meant to write `r == r_other`. A test probably won't catch this. return code end # This code requires fewer tests, but is more verbose. def self.friend_better(final user1, final user2, final type) # These parameter reference are immutable. final r = Relationship.new # This local variable is immutable as well. r.user1 = user1 r.user2 = user2 code = 0 # A normal Ruby variable. if !["friend", "spouse"].include? type type = "undefined" # RUNTIME ERROR! The runtime knows an error exists because we explicitly declared the parameter reference final code = 1 end r.save! final r_other = Relationship.find_by_sql(...) logger.info "Interesting new relationship!" if r = r_other # RUNTIME ERROR! We cannot make the assignment since the `r` reference is immutable. return code end # This best of both worlds. Requires fewer tests while still easy to understand. def self.friend_best(user1, user2, type) # All references are implicitly immutable unless declared otherwise. r = Relationship.new # The reference to `r` is immutable. r.user1 = user1 r.user2 = user2 r.type = type var code = 0 # Must be explicitly declared mutable since we are planning to change it. if !["friend", "spouse"].include? type type = "undefined" # RUNTIME ERROR! We meant to write `r.type = "unknown"`, but the runtime caught it since the `type` reference is immutable. No need to add a test case! code = 1 # Works fine since the variable was declared mutable. end r.save! r_other = Relationship.find_by_sql(...) logger.info "Interesting new relationship!" if r = r_other # RUNTIME ERROR! We meant to write `r == r_other`, but the runtime caught it since the `r` reference is immutable. return code end end
This paste will be private.
From the Design Piracy series on my blog: