The intersection of technology and leadership

Tapping into dynamic programming with Ruby

I had a task to analyse the value of a cookie set by a tool on the subdomain. The value of the cookie set looked something like this:

"18337|20120404|True#Q0A|18342|21-30|20120404|18344#Q1|18349|NO PARTNER|20120404|18351#Q2|18352|EMPLOYED|20120404|18353#Q4|18432|STRUGGLING|18539|WANT|20120404|18541#Q3|18358|EMPLOYED|20120404|18359#"

My task was to try to decipher the values of set inside the cookie and how they changed depending on the progress through the application that set the values. I was told the answers to questions sat next to the ID of the question. For example, the answer to the “age” question (21-30) was related to the question 18342 and would always appear as |18342|21-30|. I started out with some tests and ended up with a method like this:

class Answers
  attr_accessor :age, :employment_status, :has_partner

  def parse(cookie_contents)
    items = cookie_contents.split("|")
    items.each_index do | i |
       current = items[i]
       if (current == "18342")  
         @age = items[i+1]
       elsif (current == "18352") 
         @employment_status = items[i+1]
       elsif (current == "18349") 
         @current_partner = items[i+1]
       end
    end    
  end
end

Of course, I wanted to avoid the growing if-else statement so found a way that I could do it dynamically and focus just on the mapping from an ID to an attribute. The resulting code looked like this:

class Answers
  attr_accessor :age, :employment_status, :has_partner
  
  Mappings = {
    "18342" => :age=, 
    "18352" => :employment_status=, 
    "18349" => :has_partner=
  }  

  def parse(cookie_contents)
    items = cookie_contents.split("|")
    items.each_index do | i |
       current = items[i]
       if (Mappings.has_key?(current))
          self.public_send(Mappings[current], items[i+1])
       end
    end    
  end
end

By the end of the analysis, I discovered that multiple IDs mapped to the same properties and all I had to do was add another entry into the map defining which ID mapped to what property on the object. With java/.net being more of my background, I was pleased to see how brief the code turned out to be.

2 Comments

  1. Phil Calçado

    I guess this has to do more with reflection than dynamic typing? Assuming you are not changing the attributes of the class dynamically, just populating the known fields from a list of values, you could use Method.invoke in Java. Of course you would have to deal with the checked exceptions 😛

  2. Patrick

    Hi Phil,

    Yes I believe it has to do with reflection than it does with typing. I just see reflection a part of dynamic programming (it’s funny how in Java it’s always considered an “advanced” topic). It definitely would have been even more verbose in java. I probably would have used Field.set instead but it definitely would have been more code. Besides, I’m on a mainly ruby based project, so why write it in java?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2024 patkua@work

Theme by Anders NorenUp ↑