MetaGreg

writes code that writes code for food

Coding gems 31-40

without comments

#31 All non-trivial abstractions, to some degree, are leaky. Joel Spolsky

#32 Five different programmers can solve the same problem five different ways

#33 Don’t write 200 lines of code when 10 will do

#34 If the “box” is the boundary of constraints and conditions, don’t think outside the box—find the tbox. Andy Hunt, Dave Thomas

#35 Complexity and communication costs rise with the square of the number of developers, while work done rises linearly. Fred Brooks

#36 Tests only prove the presence of errors – not the absence of them

#37 A metaprogrammer is someone who writes code that writes code for food

#38 The task on a project is not to try for complete communication but to manage the incompleteness of our communications. Cockburn

#39 A good plan violently executed now is better than a perfect plan next week. Patton

#40 Tests first, then code…. or the kitten gets it

Share and Enjoy:
  • Digg
  • Facebook
  • StumbleUpon
  • TwitThis

Written by Greg Moreno

June 23rd, 2010 at 9:48 pm

Posted in Geekiness

Tagged with

DHH’s RailsConf 2010 Keynote Video

without comments

The keynote is about Rails 3.0 and the many enhancements it bring to make web application development more fun. The improvements in writing database queries (via ActiveRelation), routes, ActionMailer are really neat and I believe would make it easier for developers to get on board with Rails.

The official release will be available in a few weeks but the current version is already good enough for production use according to DHH.

Share and Enjoy:
  • Digg
  • Facebook
  • StumbleUpon
  • TwitThis

Written by Greg Moreno

June 11th, 2010 at 3:59 pm

Posted in Sideways

Tagged with , ,

Ruby 101: Make your class behave like a Ruby built-in

without comments

I got re-acquianted with this scenario while working on the OpenAmplify gem – a wrapper for the OpenAmplify API. When you give the api a text like a blog comment, it will return a list of common terms, opinion scores, named locations, and other information that can be used for text mining operations.

The OpenAmplify returns key-value pairs in an XML string by default, but it can also be in JSON, CSV, or RDF format. From a Ruby client’s point of view, we want it in Hash. You can choose to use an XML library like Nokogiri but in my opinion, working with a Hash fits nicely with Ruby.

Anyway, back to the problem. I have an instance variable that holds the data. One approach is to give clients access to the instance variable.

class Response
  attr_reader :data

  def initialize
    @data = {}
  end
end

data = response.data
topics = data[‘Topics’]

One major issue with this approach is you’re exposing the internals of your class. What if you decided to rename the variable into ‘@results_in_hash_form’? Then, all programs that uses your code will break. Worse, you will be limited from enhancing the behavior of your class like lazy loading of the data. You can wrap the access to your data inside a method but that still presents the problem of exposing the internals of your class. Also, that’s an unnecessary extra line of code :)

My suggestion is to make ‘Response’ behave like a Hash so we can do these:

topics = response[‘Topics’]
response.has_key?(‘Topics’)

# And still have our own methods:
response.some_method_we_defined

So, how can we do this? The trick is to delegate the calls to the instance variable. One approach is to define the Hash methods you want to support:

class Response

  [‘[]’, ‘has_key?’, ‘fetch’, ‘empty?’, ‘keys’].each do |method_name|
    class_eval <<-EOS
      def #{method}(*args)
         @data.send(‘#{method_name}’, *args)
      end
    EOS
  end

end

The code above is a shortcut to writing every method by hand. If you want to support all Hash methods, that would be a lot of typing.

A better approach is to just take advantage of Ruby’s ‘method_missing’ which is called every time an undefined method is called.

class Response

  def method_missing(name, *args, &amp;block)
    @data.send(name, *args, &amp;block)
  end

end

Of course, how your ‘method_missing’ will look like depends on your requirements. In our simple case, we can simply delegate to @data.

This approach is called a “Dynamic Proxy” from the book Metaprogramming Ruby by Paolo Perrota. If you want to take your Ruby skills to the next level, I highly recommend this book.

Share and Enjoy:
  • Digg
  • Facebook
  • StumbleUpon
  • TwitThis

Written by Greg Moreno

June 9th, 2010 at 7:10 pm

Posted in Geekiness

Tagged with ,

Ruby 101: Hash initialization gotcha

with 2 comments

I have a code that counts how many times a word occurs – a perfect fit for Hash.

def word_counts(words)
  counts = Hash.new(0)
  words.each do |word|
    counts[word] += 1
  end
end

categories = {
  :a => word_counts(‘some text’)
  :b => word_counts(‘another set of text’)
}

Somewhere, I use the hash returned by the word_counts method to do some calculation.

def score(word_scores, words)
  words.each do |word|
    v = word_scores[word]
    v = 0.1 if v.nil?

    score += Math.log( v / some_value )
  end
end

categories.each do |category, word_counts|
  score(word_counts, %w{some random text})
end

When I run the score, I always get an ‘Infinity’. After some debugging, the problem is this piece of code:

v = word_scores[word]
v = 0.1 if v.nil?

‘word_scores’ returns 0 if ‘word’ doesn’t exist; not nil which is the default behavior. Later, I realized I initialized it via Hash.new(0) which makes 0 the default value. In fact, it is not even necessary to check for nil or 0. All we want is to retrieve the value referenced by the key, and if the key does not exist, give me 0.1.

v = word_counts.fetch word, 0.1

By the way, the code is from a simple exercise on Naive Bayes algorithm to classify text.

Share and Enjoy:
  • Digg
  • Facebook
  • StumbleUpon
  • TwitThis

Written by Greg Moreno

May 11th, 2010 at 5:32 pm

Posted in Geekiness

Tagged with ,

Starting a Q&A website: Canada Work Visa

without comments

Last week I created a Q&A website for things related to Canada work visa. (This is actually a project of my wife’s cousins and I’m just helping them out sort out the technical details.) If you have questions about getting a work visa or issues with your Canadian work permit,  just post your questions and the nice people over there will help you out. Here are some popular questions:

Interesting because my wife and I came to Canada under a work visa two years ago but we neither needed both. Our situation might be different than yours, though.

The Canada Work Visa site runs on Shapado – an open-source software based on the popular StackOverflow model.  It’s like a forum where members can post their questions and members can answer. The problem with forums is often the best answer is buried somewhere in the myriad of responses.  A member, especially a new one, would have to read every replies until he finds the best answer.   In Shapado, members can vote for the answer like in Digg and the answer that has the most votes will go to the top of the thread along with the number of votes. This approach makes it much easier to find the answer.

Members  can only also vote down an answer. Take that spammers!  I think the ability to vote-down an answer is as important as voting-up to filter the noise from the signal.  One time, I was browsing a forum related to Canada immigration and there’s one member who posted that he’s working for the Canada Immigration Center and asking members to share their email and  application details.  Later in  the discussions,  somebody warned that the Canadian government doesn’t ask for this kind of information. Unfortunately, some took the bait. In the Canada Work Visa website, this answer will be voted-down and would go all the way to the bottom. And with all the negative votes it had, every visitor is warned immediately.

If you know somebody with  Canada work visa related question, please share this website.

If you want to start a question and answer website, I highly recommend Shapado.

Share and Enjoy:
  • Digg
  • Facebook
  • StumbleUpon
  • TwitThis

Written by Greg Moreno

April 30th, 2010 at 4:45 pm

Posted in Sideways

Tagged with ,