Rails Extend and Include

From time to time, I blog about the different things I learn in Ruby on Rails. Recently, I have been engrossed in the metaprogramming aspect of rails. There are some excellent tutorials on the web, but the hierarchy of how methods are called when classes or objects are extended is not discussed thoroughly anywhere. I ran many experiments and found this for myself, so hope that other people will be able to learn from this as well.

Extend vs. Include

“extending” a class with a module adds methods from the module into the class as class methods.
“including” a module into a class adds methods from the module into the class as instance methods.

There is a lot of discussion around this concept, and this is simple to demonstrate. So, if you ‘extend’ a class (say Foo) with a module with method (say bar), then you can call Foo.bar. However, if you on include the module into the class, then you can call foo.bar, where foo is an instance of the class Foo. This is pretty simple to understand.

However, what happens if you already have a method called bar in the original definition of the class. In that case, if you ‘include’ the module into the class, and then call foo.bar(), which method gets called? the bar method in the class definition, or the one defined in the module?

According to the ruby method name resolution algorithm, Ruby searches through the following steps for a name resolution:

  1. As the first step, Ruby checks the eigenclass of o for singleton method named m.
  2. If the method named m is not found in the eigenclass, Ruby search the class of o for an instance method name m.
  3. If the method m is not found in the class, Ruby searches the instance methods of any modules included by the class of o. If there are modules included, they searched in the reverse of the order which they are included.
  4. If no instance method m is found in the class of o or in its modules, then the search moves up the inheritance hierarchy of the super class. Step 2 and 3 are repeated for each class in the inheritance hierarchy until each ancestor class and its included modules have been searched.
  5. If no method named m is found after completing the search, then a method named method_missing is invoked instead. In order to find an appropriate definition of this method, the name resolution algorithm starts over at step 1. The Kernel module provides a default implementation of method_missing, so this second pass of name resolution is guaranteed to succeed.

According to this, the method bar defined in the class will win over the method included in the class. Note that if you extend the class with the module, and there is a method defined in the class as ‘self.bar’ will prevail over the one in the module.

This is pretty easy to understand. However, this gets confusing when the instance of the class itself is extended with a module.

  module Mod
     def hello
       "Hello from Mod.\n"
     end
   end

   class Klass
     def hello
       "Hello from Klass.\n"
     end
   end

   k = Klass.new
   k.hello         #=> "Hello from Klass.\n"
   k.extend(Mod)   #=> #<klass :0x401b3bc8>
   k.hello         #=> "Hello from Mod.\n"
</klass>

As you can see from the above example, if the object itself is extended with the module, then the method from the module wins over the one defined in the class.

Confusing, isn’t it?

Lessons from the Dancing Man – Build only when asked for it

A few weeks ago, Derek Sivers gave a talk on how to make a movementand things we could learn from a video he took (or maybe someone else did) of a dancing man in a park. I encourage everyone who hasn’t to go and read his article, but for completeness sake, and because I am not taking any ownership of the idea itself, I am embedding the video here. Derek Sivers gives a voice-over on the video, and it is very very instructive. Before I rant on an on, the lessons are obvious once you watch the video and hear Derek describe what is happening. Here you go:

Starting a movement

Pretty amazing, isn’t it? In just 3 minutes, the video and the example of the dancing man bring the idea to the brain so forcefully that the power of the first follower becomes more than apparent. I was thrilled when I saw this video, and the lessons are profound. But I think there are also many more lessons that can be learned if we just extrapolate the example and apply it to the consumer internet (because that’s where I spend most of my time and energy these days).

To recap, the idea presented in the video is that the lone nut is a lone nut until the first follower comes along and validates the lone nut. The lone nut at this point publicly embraces the follower, and accepts him as an equal. This encourages the first follower to continue dancing, and even call out to his friends. One friend comes along, then two and soon the lone nut is transformed into a leader. There is validation, and soon there is momentum. The crowd then explodes, and people who didn’t want to join earlier for fear of appearing stupid must now join for fear of appearing uncool. Powerful idea indeed.

Consumer internet companies follow a very similar pattern as well. For every idea, every product, every feature, the product developer/entrepreneur is the lone nut. Notice that it is important that the lone nut appears to be doing his thing because that’s what he is all about. This soon attracts a few other people who have similar tastes and they join in. This is the crucial juncture. These are the people who shouldn’t leave, but keep dancing with you. These are the people who are going to attract other followers and turn your product into a movement. Unlike the free-flowing dance, the initial followers cannot express themselves in any way they want. They are restricted by the features that are available in the space. Thus, it is VERY important at this point for the product designer/entrepreneur to publicly acknowledge the initial followers and listen to their feedback. Unless you listen to their feedback, you cannot let them be part of the movement. Remember that by accepting the first follower as an equal, the lone nut transformed his idea into the follower’s idea as well. If the follower was forced to go along with the moves of the first follower, the movement would probably not have happened (unless they were doing the hustle).

If we were to place ourselves in the park with the dancing man, it is not difficult to see that if the movement had failed to pick up when there were 5-6 people, then it would have died unceremoniously. The initial followers would have stopped one by one and soon, the lone nut would go away to another part of the park. We can see this happening everywhere. If a few people leave from a party, suddenly everyone leaves from the party. A few people leaving from MySpace suddenly makes everyone leave as well. This is very very true for internet companies. Therefore, it is absolutely essential that the initial followers MUST NOT leave. These are the people who provide validity to your product, and will help it become a movement.

As an entrepreneur and of a consumer internet product, it is important for your product that there are at least some people who will form the foundation for the product by living and breathing it everyday. These people will evangelize your product and go on to attract their friends, and help transform it into a movement. Most of the other people will join because that’s what momentum does, but if you lack the support of this basic group, then the movement just might never happen.

I believe that every product begins with an idea that someone finds useful. As a result, you will always attract a few people initially. It is important at this point to listen to their feedback, and really give them something that they want, and not something that you think they might want, or something else that you think that many other people might want. Unless people are asking you for something, don’t build it.

Learning how to pitch

I attended the Twiistup event last couple of days in Los Angeles. It was a great event with lots of interesting people, and some decent companies. As usual, the best part of the conference is meeting with the people, and also seeing where the energy lies in the software space right now. There were 9 companies that were selected to show-off their product, with a tenth slot open for a wildcard entry. The wildcard companies got to present the day before, with an audience vote sending them to the show-off event.

It was really amazing to see that out of the 10 or so wildcard companies, only 2 managed to pitch well. Not really well, but well. The rest 8 were terrible. For all entrepreneurs out there, before you go out to pitch, do yourself a favor, and read the two excellent books by Gene Zelazny – Say it with Presentations, and Say it with Charts.

Not only do these two books make you a better presenter, they will help you structure your content in the most logical way, and present ideas in ways that make sense. And yes, please please please, practice your pitch a few times in front of friends before pitching to others. If that makes you a little uncomfortable, well, that’s the whole idea.

GMail, why can’t I regain full control of my account after being hacked?

So my gmail account got hacked. Yes, painful, but also very instructive. Firstly, I still do not know exactly how it got hacked. I don’t use any public computer. In fact, I haven’t used any other machine besides my own laptop (Mac) and my iPhone in a very very long time. I don’t sign up for any offers on the internet, and do not install any crap software. Besides, isn’t the Mac supposed to be very safe?

Anyhow, I got hacked and that’s that. The hacker then started sending emails from my account to everyone I have ever communicated with asking for money. The amazing thing about this story is that all the emails sent are very very impersonal, don’t salute the recipient in any way, and are full of grammatical and spelling errors. Yet, the content matter is so sensational (being robbed at gunpoint in some foreign country), that everyone gets worried about my safety. If I received a similar letter, I wouldn’t sit and analyze this, and would fall for it as well. So far, they have preyed on the emotions of their victims through me as the medium.

During the course of trying to get my account back, I ran into some of the issues and got a sneak peak about exactly how these hackers then try to exploit the system, GMail in particular. I had my Yahoo account set up as the secondary email in case of emergencies, or verification. The hacker was quick to change the secondary account first. Gmail has a system of sending verification to a mobile device. This too got changed quickly to some mobile number in Nigeria. During this time, I tried in vain to gain control by asking Gmail to reset my password and send me the password reset code. Gmail only shows that they sent the reset code to xxxx@yahoo.com, but not the username at the yahoo.com address. So while I was waiting for my password reset code to arrive at my yahoo.com address, the hacker was seeing password reset requests come in to the temporary yahoo address he had set up. I am sure he was laughing at my stupidity and the fact that I sent in multiple requests when the first one failed.

Ok, I was baffled. So I went through the GMail system to report that my account has been compromised. I had to fill in multiple details, including when my account was first started, and the invitation code I used to join (if at all). Obviously, I didnt have any of these, but I made best guesses, and lo and behold, GMail returned my account back to me. I was able to reset my password, and rejoice.

Alas, too soon!

After proclaiming victory, I tried to send a few emails, etc. and it all worked fine. I promptly sent emails to a huge list of people warning them that I had been hacked, and to ignore requests from me for money. There were a few people in the list that I wouldnt have minded getting some money from, but this had to be done.

The hacker, during this time, had very smartly set up a forwarding rule so that he was getting all the emails that I was receiving on my account. This, by itself, is not much. But here comes the most amazing part of how Google engineers missed seeing this as a threat, but these hackers have managed to exploit it. Before I explain what the flaw is, a little diversion into the background.

GMail allows one account to send emails while masquerading as another account. This was designed primarily so that I can have multiple gmail accounts (including Google Apps email accounts like I have a @gmail.com and a @gigzee.com account), and still be able to use one primary account and send emails from it for all the different accounts. Great idea, and I love it. All this takes to set up is a simple verification email. So, say you have a1@gmail.com and b2@gmail.com. If you want b2@gmail.com to be able to send emails and still show up as a1@gmail.com, you can go to your settings, set up another email address and this will send a verification email to a1@gmail.com. After clicking on the verification link and entering the code, b2@gmail.com can now send as a1@gmail.com. If you delete the verification email from the a1 account, there is NOTHING in the settings or account panel of a1@gmail.com that shows that b2 is still sending emails as a1.

This is exactly what the hacker has done. He has set up another gmail account, and is sending emails on behalf of my gmail account. During this time, he is also receiving the auto-forwarded emails of my account. So even though I have changed my password, and declared victory, he can still receive and send emails just as if he were in full control.

So, step 1, I removed the forwarding rule. Ok, now he cannot get any emails sent to me. Yayyy!
What about his ability to send emails? Turns out that there isn’t any additional verification after the initial verification. What’s more, there is no indication anywhere on my account settings that shows me how many other people can send emails as me. This is terrible. So while I have full control with brand new passwords, the hacker can simply keep sending emails to anyone he likes pretending to be me, ruining my reputation in the process.

GMail – I am not sure how you could have missed this in one of your threat model analyses. But please add an option in account settings where I can control who all can send emails pretending to be me. Meanwhile, the hacker has a field day in sending emails from my account, and can do so as and when he pleases. I am writing a letter to GMail as well so that they can fix this, but if you get any email from me asking for money (personal or not), please don’t wire it to somewhere in Europe. Now, if you want to hand over some cash to me in person, feel free to give me a call!

The real price of gold in the USA

So, I have been very interested in buying some gold for investment purposes since the last year. Gold has been rallying like a crazy bull for the past year, with no correction in sight. Partly, this has been because the US dollar has been devaluing, mostly because speculators worldwide are involved in the dollar carry trade, replacing the yen carry trade. However, despite this, the price of gold has been going on up in currencies which are not pegged to the dollar, for example, the euro and the yen. Only the Australian dollar has appreciated in value respective to gold, but this is primarily because the US dollar carry trade is happening with Australian dollars (the Australians are leading the recovery and have had to increase their interest rates).

The chart below shows the price of gold in US dollars. The period before 1967 is not of interest, as the dollar was on the gold standard, thus the price of gold didn’t fluctuate much. In fact, the price of gold remained constant from 1893 to 1918 (world war I).

Price of gold in US dollars

The real question, of course, is whether this is a good time to invest in gold. I am not looking for a short-term play, but my motivation is primarily to protect myself and the family savings from another round of redistribution of wealth that will be brought upon by another round of recession, inflation or devaluation of the currency. So, I decided to compute the buying power of gold, and how that has changed in the last 30 years. For this, I compute the price of 1 lb of flour, needed to make bread. Computing the 1oz gold/1 lb flour ratio, we can see how many lbs of flour would be bought by 1 oz of gold. Luckily, we have this data for the last 30 years, but not much more. Of course, gold had surged in price following the stagflation of the 70s, so 1980 marks the highest point of this ratio, but we seem to be inching our way to those levels now. Thus, the real buying power of gold has gone up significantly, more than anything in the past 3 decades.

gold/flour ratio


Credit: Gold prices from Kitco, and flour prices from FoodTimeline.org

This is a real pickle. On one hand, this signifies that we are going to see inflation, in which case, the price of flour will increase, but so will the price of gold in terms of US dollars. The other side of the coin is that gold is overpriced, as the gold/flour ratio should be relatively constant. However, examining the lows of the ratio in 2001 gives some sense of why gold has appreciated like a raging bull in the past decade. Another fact that is not captured in the graphs is the confidence of the rest of the world in US dollars. As confidence in the dollars increases, people prefer to hold dollars as opposed to gold. A reversal in that sentiment will drive the price of gold higher. This is the reason that we are seeing central banks in India and other emerging countries emptying the gold reserves of the IMF by selling their dollars and hoarding gold instead.

Typical investment strategy says that we should invest at least 10% in gold, to protect from devaluation of the paper currency. What do you think? I would love to know in the comments.

Rails 2.3.4 and acts_as_favorite incompatibility

Usually, I try to write about information problems, and what we can do to better parse from the myriad of information. I have been involved in gigzee, which is built in Ruby on Rails, and like everyone else, we upgraded to Rails 2.3 a few weeks ago. We also use a customized version of the acts_as_favorite plugin internally to track which artists, gigs and venues people like. So, it was very disconcerting when after the upgrade the acts_as_favorite plugin stopped working for us. Worse, since user favorites is a central theme of our website, it pretty much brought down our entire system.

After lot of looking around the web, and poking around on our servers, we figured out the problem, and are posting our solution so that other people can find it useful. The problem, as we found, is that the acts_as_favorite overloads method_missing to extend the methods for the base class, say the User model. This way, it is able to provide new methods to that class, for example user.favorite_blogs.

Unfortunately, in rails 2.3.4, the file /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/associations/association_proxy.rb got changed, to include the highlighted lines. These end up raising a NoMethodError before the overloaded method_missing is called for the @target.

def method_missing(method, *args)
  if load_target
    unless @target.respond_to?(method)
      message = "undefined method `#{method.to_s}' for \"#{@target}\":#{@target.class.to_s}"
      raise NoMethodError, message
    end

    if block_given?
      @target.send(method, *args)  { |*block_args| yield(*block_args) }
    else
      @target.send(method, *args)
    end
  end
end

Instead of messing with the gem itself, and breaking who-knows-what-else, we decided to simply overload the respond_to? method for the user class.Our code (in app/models/user.rb):

def respond_to?(method_sym)
  if method_sym.to_s =~ Regexp.new("^favorite_(\\w+)")
    return true
  elsif method_sym.to_s =~ Regexp.new("^old_favorite_(\\w+)")
    return true
  elsif method_sym.to_s =~ Regexp.new("^has_favorite_(\\w+)\\?")
    return true
  elsif method_sym.to_s =~ Regexp.new("^has_old_favorite_(\\w+)\\?")
    return true
  else
    super
  end
rescue
  super
end

This essentially goes around the problem by telling ActiveRecord that these methods do exist for the User model, and then the method_missing from the acts_as_favorite plugin is called.

Simple fix, and I hope it can save other people a lot of headache too.

How many people do you know who have never got a speeding ticket?

When I was in graduate school, one of my roommates asserted that he planned to go through life without getting a speeding ticket. I met him a couple of months ago, and I asked him how he was doing on that plan. He had got one speeding ticket! Amazingly, even though I had never made my intentions public, I also planned to go through life without getting a parking ticket. Yet, despite my best intentions, I too got a ticket a few years ago.

I know what you are thinking. Clearly, both my friend and I should have been more careful sticking to the posted signs on the limits. And for the most part, we do. The trouble is that there is no well-defined boundary about where we are breaking the law. It is more like a gray area. If the posted speed limit is 60 mph, then the boundary lies at 60mph. If you go faster than 60mph, you are speeding and must get a parking ticket. The trouble is that most of the traffic travels at a speed greater than 60 (typically somewhere between 65 and 70mph – the “accepted” 5-10mph above the limit), making it an illegal-but-acceptable zone of 5-10mph.

This zone exists for a variety of reasons. First and foremost is the technicality of the margin of error of speed checking guns or various other devices, the calibration errors. etc. Smart lawyers try to get their clients off based on such technicalities. So, the police try to catch people outside this range of error. But this is not always so. Sometimes, the cops will catch you even if you are going only 4 mph above the posted limit (say 64 in a 60 zone). Why this discrepancy?

One way to deal with this is to always follow the posted speed limit. If the general traffic is going faster, then not only will you be the slowest car on the road, but you might also be holding up some traffic, thereby causing a more potentially dangerous situation. Furthermore, if you were following the posted limit, why should you be the one to be punished by having to spend more time for the same task that everyone else does in a shorter period of time? Law-abiding citizens should be rewarded, and not disadvantaged. If someone is traveling above the posted limit, it is the duty of the police officer in charge to issue a ticket. Every time the police officer neglects to perform his duty, he is abetting a misdoing.

I have been asking all my friends who have been driving for more than 5 years, and so far, every single one has got a speeding ticket. Some people are habitual speeders, but even the more cautious, gentler drivers have managed to be caught speeding at least once.

Do you know anyone who has been driving for a long time without ever getting a speeding ticket? Please add it in the comments, I would love to know.