Search This Blog

Loading...

May 30, 2014

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.

May 29, 2014

Exploiting tap in Ruby

The instance method tap is available as part of Object class from Ruby 1.9.x onwards. Rubyists exploit it to different use cases for fun and fashion. This blog post is to share my thoughts on what I think it is best for.

Stackoverflow, the life-saver for many developers has one instance where the accepted correct answer to the use of tap is more misleading. This prompted me to write this blog post. To reproduce the accepted answer, it goes like below:

When readers encounters the code like below, they would have to follow all the three lines and then recognize that is is just creating an instance named user.
user = User.new
user.username = "foobar"
user.password = "mypassword"
user.age = 15
The above code can be re-written as below to make the code immediately clear. A reader would not have to read what is inside the block to know that an instance user is created.
user = User.new.tap do |u|
  u.username = "foobar"
  u.password = "mypassword"
  u.age = 15
end
Based on my experience, in the context of real-world code, there should be many instances of code patterns like above. In such cases, it is much ideal to create an instance method of User like, say build, that is something like below than utilising tap.
class User
  attr_accessor :username, :password, :age
  def build(h)
    h.each do |k,v|
      sym = "#{k}=".to_sym
      self.send(sym, v) if self.respond_to?(sym)
    end
    self
  end
end

u = User.new.build :username => "ganesh", "password" => "mypass!!!", :age => 12, :sex => 'm'
p u

There is another example that states that tap can be used to contain related set methods within its block. I'd much rather build a composite method that contains all these methods within it than using method. It is this way I make my code more readable and concise.

Now you should be wondering, "What on earth can I use the "tap" method for? I'm so vying to exploit its potential."

I'd say the best use of tap method is for debugging and hardly anything else. To be specific, use tap to watch the value of an intermediate expression like below:
(1..10)              .tap {|x| puts "original: #{x.inspect}"}
.to_a                .tap {|x| puts "array: #{x.inspect}"}
.select {|x| x%2==0} .tap {|x| puts "evens: #{x.inspect}"}
.map { |x| x*x }     .tap {|x| puts "squares: #{x.inspect}"}
All the tap calls are meant for debugging the intermediate state of the expression in the chain-calls. Isn't this a lot better?

How tap works?

tap{|x|...} → obj
Yields x to the block, and then returns x. The primary purpose of this method is to “tap into” a method chain, in order to perform operations on intermediate results within the chain.

And for your information, the example and explanation is shamelessly reproduced from Ruby doc.

ProTip: The best way to learn and digest Ruby phrases is to get into the habit of reading Ruby Doc.

More examples of how tap is used in intermediate expressions for debugging purposes
myobject.methods.sort.tap {|arr| p arr}.grep(/taint/)

(a + b) (p - q) / (a - b).tap {|denominator| puts denominator}

def meth
  return (some complex expression).tap {|result| puts result}
end

References

Ruby API Doc for Object#tap
MenTaLguY's blog titled, "Eavesdropping on expression"

May 28, 2014

Require versus Load in Ruby

The big difference


  • While you load a file, you require a feature
  • Every time you load, you load a file into memory. On the other hand, every time you require you is if it has already been required to avoid repetition
  • require is more abstract an API than load. So typically for you're day to day use, you'd require not load.
  • Because you load a file, the load method takes the input argument having file extension. The file extension is excluded in the case of require method.

How require works?

require(filename) -> true or false

It's good to understand how require works under the hood to serve as the high level utility method that it is. 

When you require with a string argument, the file-name is resolved to an absolute path. If the filename does not resolve to an absolute path, it will be searched for in the directories listed in $LOAD_PATH ($:).

If the file is not to be found a LOADError is raised. Otherwise, this resolved file-path is added to the $LOADED_FEATURES array.

It is also good to know that require method returns a boolean true/false depending on weather it is loaded or not.

Side-note: require(..) has similar sibling method require_relative(..) that you can take a peek into.


How load works?

load(filename, wrap=false) -> true or false

Loads and executes the code in the file filename.

If the filename does not resolve to an absolute path, the file is searched for in the library directories listed in $LOAD_PATH ($:).

Setting wrap=true gives additional benefit in that the loaded ruby code is wrapped into an anonymous module before being executed so as to avoid any naming collisions or dirtying the program's global namespace.


Understanding Require and Load by example

Fork my repo ruby_lab and play your way with files in require_load directory to get better understanding.

March 31, 2014

Applying Agile Practices To Manufacturing And Others

Joe Justice applies current software development principles from Lean and Agile (XP and Scrum) to manufacture, achieving extraordinary results in designing a high efficiency and high performance automobile.
http://wikispeed.org/car/

March 30, 2014

Lessons from Mark Zuckerberg at Startup School 2013

Mark Zuckerberg gave a very candid and open interview at Startup School 2013. I liked it so much that I wanted to scribble some points from the talk. And this blog post is a bulleted list of lessons I learned from Mark.