I’ve launched the first version of my blog site, and launched it at clemensp.com. The content will be migrated over soon.

See you there. =)

Today I was working on a bit of view logic.  One of the logics involved having an id if the item was just added, and no id otherwise.

Initially, the view had some ugly logic such as(I am using HAML btw):

- if some_condition
  %tr.special_id
- else
  %tr

The problem I ran into this was that I initially did not know how to include the following td’s into the tr’s.  In erb, I would just include the td’s before the </tr>.

So I re-factored the logic into a view helper, and ended up with the following in the view:

- get_row_for(item) do
  %td first cell
  %td second cell

and in application_helper.rb, I had:

def get_row_for(item)
  style_id = item == @current_item ? "current_item" : nil
  tr = content_tag(:tr, :id => style_id)
  concat(tr)
  yield
end

This worked fine, but an issue that arised was that the outputted html did not format well in conjunction with haml.

So with a bit of searching, I found that haml has a helper called haml_tag, which functions similarly to content_tag, but outputs directly into the haml template.

Armed with this new haml helper, I was able to refactor the code into the following:

def get_row_for(item)
  style_id = line_item == @current_item ? "current_item" : nil
  haml_tag(:tr, :id => style_id) do
    yield
  end
end

With this change, everything works as expected, and the html gets outputted formatted correctly by haml.
Learning new things everyday. =)

I’ve been playing around with rspec and cucumber lately after I’ve started to read The RSpec Book, and I’ve learned a ton so far.  One of the things I’ve gained so far from practicing TDD/BDD is that I have a lot of opportunities to refactor code.  I can already feel the repeated refactorings increasing my knowledge of ruby.

Today, I’ve been playing around with a small game that I’ve written using BDD/TDD, trying to refactor where I can.

Among the refactored areas, I’d say the two coolest refactorings have been where I’ve used method_missing to add dynamic method definition, and inject to remove a bunch of code smell.

Let me show you the two changes.

method_missing:

I initially had a method called check_last_move, which called check_vertical, check_horizontal, check_SW_to_NE, check_NW_to_SE, to see if any of those directions had a winning line.  Having read about method_missing while going through Ryan Heath’s blog, I decided to give it a shot.

def method_missing(method)
  if method =~ /check_([\w]+)/
    send(:check, $1)
  else
    super
  end
end

def check_all_directions
  won = false
  directions = %w(vertical horizontal SW_to_NE NW_to_SE)
  directions.each do |direction|
    won = send("check_#{direction}")
    break if won
  end
  won
end

def check(direction)
  @board.send("get_last_played_#{direction}").join =~ /#{@board.last_added_piece}{4,}/
end

With the change to using method_missing, I was able to get rid of four near-duplicate methods.

The next task was to get rid of some code smell, so I re-factored the check_all_directions method above to the following, using inject:

def check_all_directions
  %w(vertical horizontal SW_to_NE NW_to_SE).inject(false) do |won, direction|
    break won if won = send("check_#{direction}")
  end
end

Much cleaner functions now. =)

I am definitely loving the fact that TDD allows me to do so much re-factoring without worrying about existing functionalities breaking.

The fifth solution to kata two has been posted on github:

https://github.com/clemensp/code_kata/blob/master/two/5/lib/kata_two.rb

For this implementation, I decided to go with the fastest implementation I had so far (solution #4), and improve it.  One of the key parts of the chop method is determining where to cut the search range.  In the previous implementations, I took the median index of the min and max indices, and updated the min or max index depending on the value at the median index.  I decided to improve this “getNextIndex” function.

For each iteration, we have a search range from min_index up to max_index.  Since the numbers in the array are sorted incrementally, I determined that instead of using the index in the center of the search range, I could set the next search index to be the location where ‘int’ had the highest chance of being located.

The method I used to calculate the next index was to look at the values at min_index and max_index, look at int, and determine how far int would be from min_index.  The ratio of the distance from min_int is (int – min_int) / (max_int – min_int), where min_int is the value at min_index and max_int is the value at max_index.  I multiplied the ratio to the current index range (max_index – min_index), and added this value to the min_index.

The result was an implementation that ran about 20% faster than the previous fastest implementation (solution #4).  I am definitely pleased with the impact that the improved indexing had on the runtime of the method.  =)

I think that this is where I’ll leave kata two for now.  I’ll re-visit if a potential improvement comes to mind sometime.

Continuing on with kata two, I’ve implemented a solution with one loop, no recursions.  Surprisingly, this turned out to be the fastest implementation so far, and the code itself is quite elegant as well.  This implementation is 30% faster than solution #2 with the recursive sub-method, and about 125% faster than the recursive solution #3.

The solution is posted on github:

https://github.com/clemensp/code_kata/blob/master/two/4/lib/kata_two.rb

Now the straight-forward implementations are done.  Time to come up with unorthodox solutions.  =)

Just finished implementing the third solution for kata two, using just one method for recursion.  A sub-array was passed to the next iteration instead of passing indices as in solution #2.  This implementation had less special cases compared to the previous implementation.  Less special cases == more elegant solution == easier to understand.  However, this solution runs about 30% slower than the previous implementation.  In any case, I’m pleased with this solution.

Something to note is that this solution was written and ran flawlessly in about 10 minutes.  Maybe this code kata thing will turn out to be useful after all.  =)

In any case, the solution is posted on github as usual:

https://github.com/clemensp/code_kata/blob/master/two/3/lib/kata_two.rb

I’ve come up with the second solution for kata two, the first solution that actually performs a binary search.

I’ve decided to use a recursive binary search, squeezing in the indices for the range to check.  Most of the end/special cases were straight-forward.  The one case that caught me for a short while was the case where the next range was equal to the previous range.

The code is at github as usual:

https://github.com/clemensp/code_kata/blob/master/two/2/lib/kata_two.rb

Follow

Get every new post delivered to your Inbox.