Skip to main content

Deals You Can't Miss

1 Year Subscription

When to freeze, clone or dup in Ruby?

I try out expressing my intent in different forms to see what works effective. This time around, I'd like to story tell the code as if it's evolving over a pair-programming session. I'd appreciate your constructive feedback.

Warning the examples in story you're about to read might be super contrived and redundant. I'm merely trying the story-telling way to explain concepts with examples in the hope that you get near first-hand experience of pair-coding and experience learning. Chew on the concept leaving the contrived examples and story behind :P

The Context


In a fairy tale island called Maamu in Divided States of Fundia (DSF), there was this super successful Agile consulting shop that boasts itself of crafting high-end, complex, mission-critical social-networking software solutions in Ruby on Rails.

In this company there was a veteran TDD practitioner by the name Bob and expert Ruby/Rails programmer by name David. While Bob loves and evangelises TDD sharing his experience, David from time to time bowls people over with his ideas, opinions and experiences. Incidentally, they both were once assigned in the same project and had to pair program. As client would have it, David suddenly became not so passionate of TDD and thankfully Bob being the veteran he is, was very accommodative to different ideas to see if he can be of influence or be influenced by David for right cause.

The Pairing Session


In one of the pair programming sessions between David and Bob, David ended up writing the following method in one of his classes.
def salutation(name, informal=true)
  return name.replace "Hi #{name}!" if informal
  name.replace "Hello #{name}!"
end
and said, "Yay!, I'm done". Bob smiled and said "May be not. Mind if I write the test for the method to check for its correctness?" David being David said, "Sure, have fun!"

By writing a few tests, Bob said, "Dude, we've a problem. This method mutates the string argument name that is passed to it. And this is bad. Want to change the code to pass my tests?". David was delighted to see value in tests and went about writing code to pass the tests. David sighed, "I now see some value in tests but test first TDD is something I'm still not really convinced about." Bob smiled, "You're awesome.. some day you'll appreciate writing code Test first. And I'll see if I can be of any help to you in this." Bob then, casts his eye on the code that David just wrote and it looked like below:
def salutation!(name, informal=true)  # Note the ! suffix to the method name
  return name.replace "Hi #{name}!" if informal
  name.replace "Hello #{name}!"
end
Bob remarked, "I thought you'd remove the name.replace thingy altogether". David replied, "Well, that is not a bad idea. I'd still wish to not change that piece of code and rather warn the client of using the method's mutant property with that single bang in the method suffix. Let the sensible caller pass on the name's duplicate like the code snippets below:"
salutation!(name.clone);
salutation!(name.dup);
Bob sighed, "What if the object is frozen before the call to salutation? Won't your code throw an error?"

David, "No problem. The client will then have to call name.dup instead of name.clone because the only difference between clone and dup is that clone copies freeze-state as well which dup method doesn't....Also, when somebody marks an object frozen it is especially for the purpose of protecting the object's state from any accidental mutation."

Bob, "Interesting..Do you know that there is a little catch in freezing the object?"

David, "Now what is it?"

Bob, "Gimme the keyboard, lemme explain you with an example."
class User
  attr_accessor :name, :age, :password

  def initialize(name, password, age)
    @name = name
    @password = password
    @age = age
  end
end

user = User.new("karthik", "mypassword", 17)
user.freeze

greetings = salutation!(user.name) #will raise an error??
Bob asks quizzically, "What do you think will happen to the above code when you execute it?". And David replies, "Well it's gonna spit out a runtime error saying you can't modify a frozen object".

Bob sighs "See, that is what happens to the human mind - it tends to miss the nuances. It doesn't throw an error. The code executes and after the code execution the username changes its value with the salutation prefixed. And that is because when an object is frozen it's static values or object references cannot be changed. But the value of the object it refers to can change, as in the case of the User object's username."

David extends his hand and says, "Yeah, I agree and second your thoughts. It was a pleasure pairing with you". Bob leans forward, shakes his hand, hugs David and whispers in his ears, "The pleasure is mine. I had my share of learning. Pairing and TDD is fun any day. Will pair again sooner".

Lessons learnt


1. Pair programming is real awesome, even when you're pairing with a good if not great developer instead of a jerk.
2. TDD is fun and productive. Give it a genuine try, pairing with a few seasoned folks setting aside your ego. Practise, practise practise solving problems with and without it.  You'll end up being pragmatic instead of being dogmatic about or rebel to it.
3. Needless to mention the importance and nuances of freeze, clone and dupe methods in Ruby's Object.

My Popular Posts

Ten Commandments of Egoless Programming

We are nothing but the values we carry. All through my life thus far, I tried to influence people around me with the virtues I value. Thanks to some good reading habits I had inculcated, and the fortune of being in good community of peers and mentors alike, I managed to have read some real good books. This post is about the 10 commands of egoless programming in Weinberg's book. I shall explain the commandments based on my experience here. So very many decades ago, Gerald M. Weinberg authored  The Psychology of Computer Programming . In it, he listed The Ten Commandments of  Egoless Programming , which remains relevant even today for us as not just programmers but as team-members. Weinberg is regarded as a pioneer in taking a people-centric approach to computing, and his work endures as a good guide to intelligence, skill, teamwork, and problem-solving power of a developer. When they appear to inspire and instruct, we find that they can apply to just about every business area, and e

Should I buy refurbished laptop from Amazon?

This post is based on my experience with amazon.in and guess it to be true on all other platforms as well. At least you can check out and verify for these pointers before you make that decision to buy renewed/refurbished laptop on Amazon with your hard earned money. I see this question propping up in several forums and on many different occasions. In the recent past, I had my 5 year old dell laptop that gave up because its motherboard failed. One of the options that I had in my mind was to re-use the HDD and the 16GB DDR4 RAM of that old laptop in the one that I purchase next as secondary.  I had come to a conclusion that it is not worth buying a refurbished/renewed laptop at all. Why? For the following reasons, most of which I see as BIG #RedFlags: You got to remember that Amazon provides a platform for 3rd party sellers to sell their products as well. So in your search for refurbished laptops you wouldn’t want to choose some random 3rd party seller who Amazon doesn’t endorse. You cou

Multi-tenant Architectures

  Multi-tenancy Application Deployment Architecture could be modeled in 4 broad ways: Separate Apps & Separate Databases Shared Apps & Shared Databases Separate Apps & Shared Databases Shared Apps & Separate Databases There is no right or wrong here. It's about choice and consequence that you should consider taking into your business context and constraints. In this post I intend to jot down a some key points to keep in mind for each of these multi-tenant architecture. These are more of quick notes for my quick reference, a cheat-sheet of sorts when I have to make choices. And I guess this can come handy to you too in your wise decision making. Separate Apps & Separate Databases Easiest to implement from development and deployment stand-point. Just automate the deployment infrastructure for every tenant for quick set-up. Most expensive of all the models from infrastructure cost stand-point. Relatively longer deployment t