Articles

Shame Driven Development

By on

Several days ago, I saw a code challenge on CodeIQ.

It challenges users to write a ruby program that mimics basic functionalities of the UNIX cal command. Users are encouraged to not rely on Date, Time, Datetime or other libraries. Expected time of writing this program is 15 minutes.

$ cal 12 2012
   December 2012
Su Mo Tu We Th Fr Sa
                   1
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31

That should be an easy exercise. Almost, if not every, programmer has written a cal or two in their early days of programming. I should have written one in C in my first year of college. But, could I write a simple cal now, say, in 15 minutes? Without relying on any libraries?

I pondered. Then a question flashed into my mind: how do I know if a year is a leap year or not? In elementary school, I was taught that there is a leap year every 4 years. Is it really as simple as that?

As usual, Wikipedia has the answer. And there is some some psuedo code kindly listed:

if year modulo 400 is 0 then
   is_leap_year
else if year modulo 100 is 0 then
   not_leap_year
else if year modulo 4 is 0 then
   is_leap_year
else
   not_leap_year

Now I know that the year of 1900 (and 1800, 1700, …) was not a leap year:

$ cal 2 1900
   February 1900
Su Mo Tu We Th Fr Sa
             1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28

Furthermore, with some quick search on the command cal, I found a more surprising fact. In the year 1752, there were no such days as September 3, 4, … till 13. At least the command told me so:

$ cal 9 1752
   September 1752
Su Mo Tu We Th Fr Sa
       1  2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

(You can read more about the history here.)

Now, back to the title of this post.

Actually, I have wrote a stupid cal. (Not in 15 minutes, sorry.) It takes month and year as the arguments, and outputs a calender similiar to cal. It does not take care of the years before 1970, and has no any other fancy features.

Why do I bother putting a stupid program online? Because I am so shameful about it. And I feel that I have to accept it and do something to force me grow.

By attacking problems continiously, I will learn and hopefully be able to write less shameful code.

Equality of Active Record Objects

By on

There was once a caching problem in a project I am working on.

The hash of some posts are used as cache keys. According to the document, I expect Object#hash will return different numbers if any attribute changes. But the cache just won’t refresh.

To figure out that problem, let’s start with two posts (in rails console):

[1] pry(main)> p1 = Post.first
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" LIMIT 1
=> #<Post id: 4, title: "Hello", content: "World.", created_at: "2012-05-20 08:38:46", updated_at: "2012-05-20 08:38:46">
[2] pry(main)> p2 = Post.first
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" LIMIT 1
=> #<Post id: 4, title: "Hello", content: "World.", created_at: "2012-05-20 08:38:46", updated_at: "2012-05-20 08:38:46">

They are the same post:

[3] pry(main)> p1 == p2
=> true

If we change an attribute of p1:

[4] pry(main)> p1.title = "hi"
=> "hi"

Then p1 still equals to p2:

[5] pry(main)> p1 == p2
=> true

They also have the same hash:

[6] pry(main)> p1.hash == p2.hash
=> true

But, why?

Actually, the hash of p1 is the hash of p1.id:

[7] pry(main)> p1.hash
=> -2154204912980276923
[8] pry(main)> p1.id.hash
=> -2154204912980276923

We can confirm that from activerecord/lib/active_record/core.rb:

def ==(comparison_object)
  super ||
    comparison_object.instance_of?(self.class) &&
    id.present? &&
    comparison_object.id == id
end
alias :eql? :==

def hash
  id.hash
end

That is, when we compare two Active Record objects, we are comparing their ids.

For a cache key, you may consider using cache_key method:

[9] pry(main)> p1.cache_key
=> "posts/5-20120523014730"

It returns a string, which contains the model name, id, and updated_at timestamp of the record.

A new design

By on

Yesterday I was kind of fed up with the upleasant design of my blog, and decided to do something about that.

An attractive solution is migrating to Octopress. But that way I could no longer rely on Github to build and host the pages for me.

Then I found Jekyll-Bootstrap, a simple yet powerful framework. Since it do not include any plugins, pages can still be built and hosted on Github. I was so excited and definitely tried it, but was not fully satisfied with its DOM structure.

Of course I can customize JB to fit my needs, but suddenly I realized what I really need is just a new design. Although I am not a designer, I can utilize my newly learned knowledge of CSS and make it look better. And this is the result.

Please feel free to give me any feedback or suggestions of this site. I’d be glad to hear your thoughts!

Version Control by Example

By on

This morning after I woke up, my dad told me that my book has arrived.

“I opened the envelope because it was somewhat damp.” he explains.

Damn postal service. But what book?

The envelope from Chicaco almost answered my question. Yes, the book lying next to the envelope is Eric Sink’s Version Control by Example.

I requested a free copy of the book, and totally forgot about that. I didn’t expect such a nice book would be mailed overseas to my house, for free. But now the book is on my desk.

Thank you, Eric!

Blogging like a hacker

By on

This is the very first post.

Ever since reading ”Blogging Like a Hacker” long ago, I’ve been wanting to own a similar site. No worries on database things. Writing articles in plain text feels me good.

I also considered nanoc, since it sounds so powerful. But I chose to learn the simpler Jekyll first.

After setting up this site, I found the existence of Octopress, a helpful framework based on Jekyll. It features a semantic HTML5 template, Disqus Comments support, beautiful syntax highlightings, and many more. Using it would surely make the building process easier. I wish I could know this earlier, but I also learned a lot through building the site from the scratch.

There’s still a lot more to do, but right now I’d like to call it a day.