Ruby’s alias_method

Today I learned about an interesting method in Ruby alias_method, this method can be used to refer to an old method in a module. The documentation is here: http://apidock.com/ruby/Module/alias_method. But at first glance, I couldn’t understand what it’s used for. So this simple post will illustrate a little.

Let’s say we have a module initially:

module Mod
  def print_asdf
    puts "lalalala"
  end
end

We can use it like this:

irb> include Mod
 => Object
irb> print_asdf
  lalalala

Later we decided to reopen the module and overwrite the function to add something:

module Mod
  def print_asdf
    print_asdf
    puts "changed"
  end
end

It’s just like calling the superclass method when we’re doing inheritance in OOP, but for this case we can’t use super.print_asdf, if we call the above method, we’ll run into error:

irb> include Mod
irb> print_asdf
SystemStackError: stack level too deep
   from /Users/tanjunrong/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/irb/workspace.rb:80
Maybe IRB bug!

That’s because it’s running recursively! This can be solved by alias_method:

module Mod
  alias_method :hey, :print_asdf

  def print_asdf
    hey
    puts "hehe"
  end
end

Now we can use it properly:

irb> include Mod
irb> print_asdf
  lalalala
  hehe

Simple post. Bye!

Advertisements

Continue a task using Thread after render has returned

As rails is an opinionated framework, it uses the MVC pattern. Whenever it receives a request, it will go through a controller and the controller will render a page to be returned.

def index
    render :action => :index
end

However, sometimes we have to run a longer task.

def index
    # some time consuming task
    render :action => :index
end

When we met with this situation, this browser will be in the loading-forever mode, and the server might even timeout the connection. One of the way to solve it is to render a view for the user first, telling them “your request is running at the background”, then we continue on our long process. So this is how it’s done:

def index
    Thread.new do
        # some time consuming task
    end
    render :action => :index
end

This way, the web app will spawn another thread for the long task, so the view will be returned to the user first, and the long task will still be executed at the background.

However, if the long running task is too heavy, we can use delayed_job or resque to queue up the job for background execution.

How to Fetch Facebook Graph Data with Go

I wrote a script using Go to fetch information on Facebook through their Graph API. So I want to blog about how I do it. First of all, if you’re unfamiliar with Facebook graph, we can see the information using a browser: http://graph.facebook.com/android.

A Json object will be returned:

{
   "id": "350685531728",
   "name": "Facebook for Android",
   "description": "Keep up with friends, wherever you are.",
   "category": "Utilities",
   "subcategory": "Communication",
   "link": "http://www.facebook.com/apps/application.php?id=350685531728",
   "namespace": "fbandroid",
   "icon_url": "http://static.ak.fbcdn.net/rsrc.php/v2/yo/r/OKB7Z2hkREe.png",
   "logo_url": "http://photos-b.ak.fbcdn.net/photos-ak-snc7/v43/207/227200684078827/app_115_227200684078827_474764570.png",
   "company": "Facebook"
}

Let’s start with the Go code. First, we need to fetch the content using the http.Get method from  the “net/http” package. After that, we need to close the response body when it is done. More about defer can be found here

resp, err := http.Get("http://graph.facebook.com/android")
defer resp.Body.Close()

Then we read from the resp(response) into body. More about ReadAll.

body, err := ioutil.ReadAll(resp.Body)  

    fmt.Println("resp.Body: ", resp.Body)   
    fmt.Println("body: ",string(body))
    fmt.Println("err: ",err)

After that, we need to unmarshal the the bytes[] (body) of data into a data structure so that we can use the data. This is a little tricky, so let me explain a bit. For a Json object that look like this:

{
    Name: "Alice"
    Body: "Hello",
    Time: 1294706395881547000,
}

We need to prepare a data structure like this:

type Message struct {
    Name string
    Body string
    Time int64
}

Therefore, in our case, the graph API return a Json that look like this:

{
  "id": "350685531728",
   "name": "Facebook for Android",
   "description": "Keep up with friends, wherever you are.",
   "category": "Utilities",
   "subcategory": "Communication",
   "link": "http://www.facebook.com/apps/application.php?id=350685531728",
   "namespace": "fbandroid",
   "icon_url": "http://static.ak.fbcdn.net/rsrc.php/v2/yo/r/OKB7Z2hkREe.png",
   "logo_url": "http://photos-b.ak.fbcdn.net/photos-ak-snc7/v43/207/227200684078827/app_115_227200684078827_474764570.png",
   "company": "Facebook"
}

So we need to prepare a data structure like this:

type Graph struct {
    Id string
    Name string
    Description string
    Category string
    Subcategory string
    Link string
    Namespace string
    Icon_url string
    Logo_url string
    Company string
}

*Please take note of the upper case of the first letter, it is important! See Exported Identifiers.

Finally we can use the data structure for the unmarshalling:

    var g Graph
      err = json.Unmarshal(body, &g)
    if err == nil {
      fmt.Println("graph: ", g)
    } else {
      fmt.Println("graph error: ",err) // <---error at this line
    }

Now, we can use g whichever way we like after that! 🙂

Here’s the complete and running (but messy :P) code:
https://github.com/worker8/go-lab/blob/master/fetching_graph.go

Transaction class method of Active Record

Today I’m working on my rails project at work as usual, and met with a scenario that needs me to update a model by deleting and saving it in one go. So I learned that there is  a way of doing it by using the transaction class method from ActiveRecord.

It is very simple to use, you simply need to place the desired active record functions as a block argument into the transaction method like such:

Account.transaction do
  balance.save!
  account.save!
end

By using this way, SQL statements will only become permanent if they can all succeed as one atomic action, so it is safe to make a series of active record interactions without worrying that it will fail half way, and left you in an undetermined and hard-to-debug state.

How to leave a task behind on the server to run

Recently, I need to run a huge crawling tasks on the server side, and since I couldn’t leave my ssh connection on and run the task for 100 hours, what if I tripped over the router and got discounnected?

So I considered delayed_job on Rails, but I ran into some problems that I couldn’t solve, so I found another work around to this problem which might be useful in other cases. The solution is using tmux or screen:

http://stackoverflow.com/questions/11190648/how-to-keep-rails-command-from-rails-console-running-after-ssh-client-putty-cl

Here’s how to do it:

  1. ssh into_your_server
  2. tmux
  3. (you should see the tmux screen)
  4. execute whatever you want to run here
  5. press Ctrl-b then d
  6. (you should be detached from the tmux now)
  7. ps aux |grep tmux (you should be able to see tmux is still running your task)
  8. (reattach with your task by) tmux attach-session

Behaviour Driven Design in Rails with Cucumber

Every week, the SaaS course will teach a new topic. This week, the topic is about Behaviour Driven Design (BDD). The main idea about BDD is to write the desired behaviour in plain english text first, then Cucumber will help to turn this plain english text into executable ruby code with regular expression matching (we’ll need to write the matching in regexp). By using BDD with Cucumber, we are actually designing our application from outside-in.

Developing in this way enables a developer and a (non-technical) customer to discuss the desired behaviour in the beginning and can prevent the developer to code something that is unwanted. I will walkthrough how to use Cucumber in the following of this post. I will skip the steps for installation, since it can be found elsewhere, so that I can focus more on explanation.


Introduction to the feature to be added

Let’s say we already have a site called Rotten Potatoes like below, and wanted to make the table title clickable for sorting purpose:

So we write our intended feature in a file call <filename>.feature where <filename> can be anything, examine the sort_movie.feature below, which I used for describing a clickable button for sorting in Cucumber:

Feature: display list of movies sorted by different criteria

As an avid moviegoer
So that I can quickly browse movies based on my preferences
I want to see movies sorted by movie title

Background: movies have been added to database

Given the following movies exist:
| title                                   | rating  | release_date |
| Aladdin                            | G          | 25-Nov-1992 |
| The Terminator              | R          | 26-Oct-1984 |
| When Harry Met Sally  | R          | 21-Jul-1989  |
| The Help                          | PG-13 | 10-Aug-2011 |
| Chocolat                           | PG-13 | 5-Jan-2001   |
| Amelie                              | R         | 25-Apr-2001 |
| 2001: A Space Odyssey  | G        | 6-Apr-1968    |
| The Incredibles               | PG      | 5-Nov-2004   |
| Raiders of the Lost Ark | PG      | 12-Jun-1981   |
| Chicken Run                    | G         | 21-Jun-2000  |

And I am on the RottenPotatoes home page

Scenario: sort movies alphabetically
When I follow “Movie Title”
Then I should see “2001: A Space Odyssey” before “Aladdin”


General Explanation of a .feature file

In the sort_movie.feature above, there are 3 parts, namely the feature, background and scenario. The feature portion describes about the feature that will be added, the text can be whatever without limitation. The background and scenario works almost the same except that the background will run first before the scenario. So we can think of background as giving some pre-condition to all scenarios in a feature. More information here: feature, background, scenario.

In a background or scenario, we can write multiple steps and the steps always revolve around Given-When-Then. (Note that: If I only mention scenario in later portion of the tutorial, it actually applies to background as well.) The steps will help to explain more specifically on what the scenarios is about. Note that the words underlined, such as: Given, When, Then is a special word in Cucumber, they are all used to describe stepsGiven describe the state of the application, When describe the event of something happening, and Then describe what is the consequences that will happen given an event happen at a particular state.


Explanation of sort_movie.feature

Feature:
The chunk of text under feature, is freestyle plain english text and it describes about our sorting feature from a point of view of a moviegoer.

Scenario:
I will introduce scenario before background, as it is more straight forward in this case:

Scenario: sort movies alphabetically
When I follow “Movie Title”
Then I should see “2001: A Space Odyssey” before “Aladdin”

The sentence after the colon in the first line is plain english. However, the When is a keyword, it is used to describe an event. We can now run ‘bundle exec cucumber‘ to execute cucumber. Now cucumber will complain this:

Undefined step: “I follow “Movie Title”” (Cucumber::Undefined)
features/sort_movie.feature:26:in `When I follow “Movie Title”‘

This is because we only write the intended behaviour, but we didn’t tell Cucumber what to do When I follow “Movie Title”. So now we need to add in a chunk of code in features/step_definitions/movie_steps.rb:

When /I followses “(.*)”/ do |sort_choice|
if sort_choice==”Movie Title”
click_on(“title_header”)
end

Note that this is actually ruby code. We write a regular expression to match our sentence in sort_movie.feature, so Cucumber will run this code when it encounters a matching sentence. The (.*) will find a matching word and place into the sort_choice variable. Then,  we check if the sort_choice is “Movie Title”, we can further enchance this code to sort by “Release Date” as well this way.

Note the click_on method. It is a method from Capybara. Capybara is a webkit that we’ll use to help us test our web applications by simulating how a real user would interact with your app. So it can help use simulate a user click on the Movie Title. The argument title_header can be the id, text, or value of the button that you want to click_on. More information about what Capybara can do: here.

Now we can run ‘bundle exec cucumber‘ again, but it will complain again, since we didn’t have a clickable button yet. So we need to add in our controller and view(not shown, just imagine the Movie Title in the top most picture became clickable).

The same goes to Then I should see “2001: A Space Odyssey” before “Aladdin”. We need to add a matching regular expression in movie_steps.rb:

Then /I should see “(.*)” before “(.*)”/ do |e1, e2|
aString = page.body.to_s
       if aString.index(e1)!= nil && aString.index(e2) !=nil
               if aString.index(e1) < aString.index(e2)
               else
               assert false,”jr_fail”
               end
       else
               assert false,”jr_fail”
       end
end

The code has nothing special except page.body.to_s will return us the html that is returned after we click_on the button. Then we use the result aString to check if the movies are arranged in order. More on page.body.

Background:

Given the following movies exist:
| title                                   | rating  | release_date |
| Aladdin                            | G          | 25-Nov-1992 |
| The Terminator              | R          | 26-Oct-1984 |
| When Harry Met Sally  | R          | 21-Jul-1989  |
| The Help                          | PG-13 | 10-Aug-2011 |
| Chocolat                           | PG-13 | 5-Jan-2001   |
| Amelie                              | R         | 25-Apr-2001 |
| 2001: A Space Odyssey  | G        | 6-Apr-1968    |
| The Incredibles               | PG      | 5-Nov-2004   |
| Raiders of the Lost Ark | PG      | 12-Jun-1981   |
| Chicken Run                    | G         | 21-Jun-2000  |

And I am on the RottenPotatoes home page

Note that the And is used after a Given, so it can be interpreted as a Given statement as well. Same as scenario, we need add in the steps:

Given /the following movies exist/ do |movies_table|
     movies_table.hashes.each do |movie|
            Movie.create movie
     end
end

For the And statement, we do no need to write the steps ourselves, since Cucumber-rails in features/step_definition/web_steps.rb already provide use with this:

Given /^(?:|I )am on (.+)$/ do |page_name|
visit path_to(page_name)
end

Note that path_to is defined here: features/support/paths.rb.


Now, if we run ‘bundle exec cucumber‘ again, we should have all pass.

You might wonder why is it so colorful in this tutorial, that is my attempt to differentiate the difference between Ruby, Capybara, Cucumber code. I might make mistake about the coloring, but you can always check like this:

print “movies_table: “, movies_table.class,”\n”
# result# movies_table: Cucumber::Ast::Table
or
print “page.class:”,page.class,”\n”
#result# page.class: Capybara::Session

By knowing where it belongs to, whether Capybara or Cucumber, you can then google the correct documentation.


So that’s it, we are developing from outside-in using BDD methodology and Cucumber tools. A little bit more to graduate from the Saas course that lasts for a month. TDD will be the next topic.

Thanks for reading!

How to get started with Vim

Some Background about me and Vim

Knowing that Vim is a beast that won’t allow me to type straight away, I never want to use it until I started doing embedded programming in Ubuntu, where I can only control the embedded system through telnet/RS232, I’m forced to learn Vim just because it can function in command line.

Hearing about all the good things about the Vim editor on the internet, I tried to use it as my daily editor for editing text and programming. But I quickly gave up as I realize 2 major problems that reduced my productivity significantly:

1. Too many things to learn about Vim
2. Mental focus switch to Vim instead of my on hand task

I never give Vim a second try as my daily editor after that. I only use it to edit a few words in my embedded system. Not until I change my job and met a co-worker who is using Vim and is pretty good at it. Although he’s not using most of the advanced features of Vim, he’s good enough to fly around in Vim and search files properly, split windows and get everything under control. Looking at someone that can actually use Vim so fast is really inspiring for me to try it again. This time, the change is a success! I’m not a Vim pro yet, but I can at least use it as my daily default text editor.

Looking back at why I got so fed up with Vim is due to the wrong approach I use to learn it. So I thought of making a post to address them here.


Don’t try to learn everything, just learn the bare minimum

There are too many things to learn in Vim, so we should learn the bare minimum just enough to get started without reducing our productivity greatly. Until we are comfortable enough with those basics, then we we move on confidently.

When learning something new in Vim, place them into 2 categories: must-learn, and just-know-it-exists. For example, look at this:

  • Forward word movement in Normal Mode: w, W, e and E
  • Backword word movement in Normal Mode: b, B, ge, and gE.

Please DON’T try to memorize all in one shot! Doing so will make your life miserable… So what you should do is to remember w and b, just good enough to move around. 🙂

Remember the commands in category

Our brain memorize organized data better than random ones, so I believe that remembering the commands in categories actually help. When remembering the commands like i, d, w, etc in Vim, try to place them under the category of different modes in your brain, see below to learn about the 4 modes.


My bare minimum tutorial:

*note that I use MacVim, so if you’re using a different version of Vim, things might be different.*

The 4 modes you need to know

There’re actually 4 modes in Vim: Normal, Insert, Visual and Command Line mode. There are more modes, but ignore those for a start.

  • Insert Mode – is the usual mode that we can type text into it like Notepad, TextEdit ,Gedit or etc. Press i from Normal Mode to enter this mode.
  • Visual Mode – is used for copy and paste. Press v from Normal Mode to enter this mode.
  • Normal Mode – is the common mode of Vim, when you first enter Vim, you will be in this mode. Press ‘esc’ button to go to this mode from other mode.
  • Command Line Mode – is a mode where you can type command, for example, to find a file, to search a text. I will talk about how to use it on later section.

So when you first open Vim, you usually want to go into Insert Mode by pressing ‘i’ from Normal Mode.

The Insert Mode 

Nothing much to learn for now, just use up, down, left, right, and type into it and use backspace to cancel stuff.

 The Normal Mode

In this mode, we can navigate around and manipulate the text. Remember, in this mode, whatever we typed, will not appear in Vim as we expect it to be like in Insert Mode or Notepad. In this mode, every single alphabet is a Command. The few things to remember in this mode:

  • Undo and redo – u and Ctrl+R
  • Up, Down, Left, Right – use your arrow key or (Optional:K, J, H, L)

More on navigating:

  • Move by one word – w and b
  • Deleting a word – dw or db
  • Deleting a line – dd
  • Delete a character – x

Combo-action: you can multiply an action my placing a number in front, try:

  • Up for 5 times – ‘5 <arrow-key-up>’
  • Delete 3 characters – 3x

Optional to learn for now:

  • Go to Line 13 – 13G
  • Place cursor front or back of a line – 0 or $, note that it’s a zero
  • Go to next ‘a’ found in the same line – fa, a can be any character
  • Go to previous ‘a’ found in the same line – Fa, a can be any character

The Visual Mode

If you’re using a graphical Vim, like MacVim, you can use your mouse and do a command+c or paste with command+p. Then you can forget about visual mode for now and go to the next section, if you’re interested to find out how to do it the Vim way in Visual Mode, read on.

I only use this mode for copy and paste at the moment. Remember, in this mode, your keyboard will not function like in Insert Mode or Notepad mod as well. It will function very similar to Normal Mode, except that it will highlight your text as you navigate around.

To perform a copy-paste: First, move your cursor to the place you want to copy in Normal Mode, then press ‘v’ to enter Visual Mode, then move your cursor to wherever you want to highlight, then press ‘y’. To paste, go back to Normal Mode, and press ‘p’.

Don’t forget that u can use things you learned in normal mode to navigate the highlighting! For example, start at Line 1, enter Visual Mode, and press ‘5G’, it will highlight all the way from Line one to Line 5.

So, that’s it.

Command Mode

The command mode is where you can type in the Vim Command Line. Remember, in this mode, what you type will appear under the bottom most of Vim. I use this mode to save, save and quit, to search for words and files.

Save – ‘:w’

Quit – ‘:q’

Save and Quit – ‘:wq’

Quit without saving – ‘:q!’ , this is dangerous, as you might lost content of your current file, so you need a ! behind.

Searching for a word in a file – go to Normal mode, then press ‘ / ‘, followed by ‘anyword’, that you’re looking for, then hit the Enter key, then press n to go to next matching word, and N to previous matching word.

Below is optional for now:

Searching a word in your current directory :Ack -a anyword . 

Take note of the ‘:’ and ‘.’ when you type ‘:’ you will enter the command mode, then type in ‘Ack -a anyword .’ means calling the command ‘ack’ to search for ‘anyword’ in the current directory ‘.’ with an argument ‘-a’ meaning searching for all file type.

Take a little while to learn the bare minimum, then use them until you’re very comfortable with it. When you can do it without even paying much attention, then you are probably good enough and prepared to learn something new with Vim.