01110000 01100001 01110011 01110011 01101001 01101111 01101110

Laptop Battery Myths

Posted: February 25th, 2010 | Author: Kevin | Filed under: Random, Tips | Tags: | No Comments »

What your friends tell you about battery conditioning probably does not apply to the Lithium-ion-polymer batteries presently used by most computer manufacturers.

This is what you need to know.

  1. It is OK to keep your laptop plugged in all the time.
  2. You run your laptop on battery at least once a month — this should be easy, it’s a laptop right?.
  3. Battery capacity diminishes over time. Expect to lose most of the capacity within 2-3 years after manufacture.

via post by [Laptop battery myths](http://www.marco.org/195827279

Battery technology has unfortunately not caught up with the rest of technology. Laptops with batteries that lasts for days are long overdue.


Relationships & Marriages in the Chinese Culture

Posted: February 18th, 2010 | Author: Kevin | Filed under: Random | Tags: , | No Comments »

I have been spending most of my time in mainland China for my trip, specifically, the Shanwei City (Haifeng county) within the Guangdong Province.

Through living here, I’ve observed a couple interesting facts. One of these is the acceptance of age difference among couples within a relationship; it seems to differ greatly from what we’re used to in the Western culture.

In China, it is perfectly acceptable for a adult male to marry someone twenty years younger; on the other hand, it is generally unappreciated for a male to marry an older women. Such bias is especially prominent in traditional upper-class chinese families where there is a strong emphasis on power and social status.

My opinion is that age is just a number, one that is insignificant when the couple in question are both mature adults (20+) and are at a point where they are responsible and self-sustainable.

At the end, it all comes down to living a happy life.


Dynamic namespaced class instantiation in ruby

Posted: February 12th, 2010 | Author: Kevin | Filed under: Development, Tips | Tags: | No Comments »

Lets assume we have a module called Fruit, within the Fruit module is a bunch of Fruit classes.

module Fruit
   class Apple
   end
   class Orange
   end
   class WaterMelon
   end
end

If the name of the fruit comes from some data or memory store, and we want to instantiate the class dynamically via the fruit name, you might attempt to do something like this:

>> fruit_name = "Apple"
=> "Apple"
>> class_name = "Fruit::#{fruit_name}"
=> "Fruit::Apple"
>> klass = Object.const_get(class_name)
NameError: wrong constant name Fruit::Apple
        from (irb):14:in `const_get'
        from (irb):14

The problem here is #const_get does not support retrieving constants within a nested namespace. In order to combat this, we must first retrieve the module in which the class is in, then get the class.

>> Module.const_get("Fruit").const_get(fruit_name)
=> Fruit::Apple
>>

Here is an example in action:

module Fruit
  class Apple
    def self.color
      "red"
    end
  end
 
  class Orange
    def self.color
      "orange"
    end
  end
 
  class WaterMelon
    def self.color
      "green"
    end
  end
end
 
%w{Apple Orange WaterMelon}.each do |fruit_name|
  klass = Module.const_get("Fruit").const_get(fruit_name)
  puts klass.color
end
 
# output
red
orange
green

Air Canada: customer service, redefined (part 2)

Posted: February 3rd, 2010 | Author: Kevin | Filed under: Random | Tags: , | No Comments »

This is a continuation from my last post titled “Air Canada: customer service, redefined.”

Once I got onto the plane (a Boeing 777-300ER) arranged in 3-3-3 configuration, it was outfitted with their new cabin which provided each seat with a touchscreen inflight entertainment system and AC power.

Unfortunately, the seats themselves are not the type you find on Cathay flights where reclining does not affect the person behind you. This is extremely important to me because it makes using a laptop in flight that much safer and it feels like you really have the space all to yourself.

In inflight entertainment system started off as a disappointment. Within 30 minutes into the flight, the captain announces that the entertainment system crashed and that it needs to be restarted, and that restarting the system would take 30 minutes. The startup process was slowing taking place as I witness the screen around me to life one by one. It took each seat about 30 seconds to start before the one beside it would start.

Nevertheless, once everything is up and running, the touchscreen based UI of their IFE was easy to use and straightforward. I believe the screen size is bigger than the configuration Cathay has on their 777. One downside is throughout the flight, the inflight data/map is unavailable. From what I’ve read online, it has been like this the moment the new cabin was introduced. This is a thumbs down for me as I always like observing the flight data/map to know where I am and which route we took.

The food and overall service was mediocre. Their flight attendants managed to hit my pet-peeve on inflight service: leaving finished food left on my tray for too long (over 30 minutes). When you are in a cramped space, having all that junk there with tray down makes it feel even more cramped.

In conclusion, the $300 in savings was well justified. However, I will most likely still fly Cathay in the future for their more flexible flight changes (free with minimal restrictions) and their Asia Miles program.


Air Canada: customer service, redefined

Posted: January 23rd, 2010 | Author: Kevin | Filed under: Random | Tags: , | No Comments »

I usually fly CX whenever possible since they generally have better food and service than their competitors. This time I decided to give Air Canada a try for my flight to HKG. For over $400 CAD in savings, AC would’ve had to fuck it up pretty hard for me to regret going with them. Now that I am in Hong Kong, did I regret my decision in flying Air Canada? Before takeoff: kind of, after landing: no.

Air Canada

When I arrived at the YVR Air Canada counter at 12:10pm, I was greeted a rude lady with the words “Where to?.” I told her my destination and her words immediately were “You’re late, we’ll put you on the next flight.”

From a business standpoint, shouldn’t it be Air Canada’s best interest to put me on this flight instead of leaving the seat empty? It seems like to me, her best interest was to make sure I didn’t make it on this flight. Mind you, I was not late; according to documentation printed on the itinerary, the boarding gate cut-off times for international flights on AC is 30 minutes. Baggage cut-off time is 60 minutes but that aas irrelevant, I wasn’t going to check my baggage anyway. I also checked-in online prior to arriving at the airport.

The lady never attempted to ask me if I was checked-in or not, not did she ask me if I needed my baggage checked. All she did was try to get me on the next flight. In fact, she didn’t even have my name!

I told her I don’t have checked luggage and I am already checked-in. She finally asks me for my name and passport and gave me my boarding pass. Her way of saying good-bye to me was “You have to run.” At that point, my impression summed up as follows: Hey Air Canada, thanks for giving me the privilege to pay to fly with your airline and be treated like a piece of shit.

To be continued in part 2 where I will document what happened during the flight and my concluding remarks…


The start of a new year

Posted: January 14th, 2010 | Author: Kevin | Filed under: Blogging | No Comments »

At the end of 2009, I challenged Howie and Josh, my fellow co-workers at layerboom to participate in a blogging challenge called Project52. We even convinced Josh to sign up and pay for a domain name, and themed up Howie’s blog. I’ve been extremely busy these couple of weeks and was not able to get a post up for the first week of the challenge. Josh even called me out on it. In a later blog post, I will explain what I’ve been up to these few weeks that prevented me from blogging.

Beginning this week, I will do one post a week for the next 52 weeks. If I fail to do so, I will buy lunch for everyone at Layerboom for a week(1).

Topics I will blog about will include but not limited to:

  • technology and programming (ie. Ruby/Rails, MongoDB)
  • upcoming experience of working from Hong Kong
  • traveling
  • our new office
  • hosting and virtualization (I work for a hosting related company after-all!)
  • and other random stuff.

  1. Some restrictions apply, contact me for details. 


VIM tip of the day: quickly reformat your document

Posted: July 25th, 2009 | Author: Kevin | Filed under: Development, Tips, Tool | Tags: , , | No Comments »

Quickly reformat your document in VIM with:

gg=G
  • gg goes to the beginning of the document
  • = kicks off the indent filter (:help = for more information)
  • G goes to the end of the document

Another way to achieve the same result through visual mode is.

ggvG=
  • gg goes to the beginning of the file
  • v enables visual mode
  • G goes to end of the file
  • = apply indentation

Similarly, if you are on a line that needs formatting, simply use ==, or v=. You can also select a block of code in visual mode and press = to reformat the selection.

Breath this command and make your team happy.

If you find this post useful, please drop a line in the comments.


Using git-svn with non-standard repository layouts

Posted: April 16th, 2009 | Author: Kevin | Filed under: Development | Tags: , | 1 Comment »

Using git to interface with svn repositories is awesome. You get all the advantages of git: local commits, squashing/amending commits, cheap branching, local stash, smart merging, wicked fast operation, etc. However, when you try to have git work properly with a non-standard svn repository layout, things tend to get wonky.

git-svn tries to be smart, it does so by doing what it thinks you want it to do and not exactly what you tell it to do.

First of all, a standard svn layout looks something like this:

- awesome_project
  - trunk
  - branches
    - 1.0.x
    - feature_a
    - feature_b
  - tags 
    - 1.0.0
    - 1.0.1

Getting git to talk to such a repository is easy as pie:

$ git svn clone -s url://to/awesome_project

The -s option tells git to use the standard layout and automatically map your trunk/branches/tags as… master, branches, and tags. You probably want to tell it to fetch a specific revision to speed things up if you have a large repository.

But like everything else in life, things are not always that easy. You may run into times where you need to have git talk to a non-standard repository layout. Maybe something like this:

- awesome_project
  - trunk
  - branches
    - fork_a
      - trunk
      - 1.0.0
      - 1.0.1
    - fork_b
      - trunk
      - 1.0.0

In my case, I happen to work on fork_a almost exclusively, so the most logical thing to do was:

$ git svn clone url://to/awesome_project/branches/fork_a

If you did something like that before, you may find that git svn thinks you meant to use awesome_project as the project root. The reason why it does that is git svn starts from the beginning of the history, and moves up until it finds /branches/fork_a. Unfortunately, when git sees standard svn directories (trunk, branches, and tags) in the project root, it incorrectly corrects your error for you.

Don’t you hate it when the computer does what it thinks you want it to do instead of what you tell it to do?

The solution to this problem is first initialize an empty git repository:

$ git svn init /path/to/awesome_project

Open up .git/config and change your svn-remote section to look something like this:

[svn-remote "svn"]
    url = http://awesome_host/awesome_project
    trunk = branches/fork_a/trunk:refs/remotes/svn/trunk
    branches = branches/fork_a/*:refs/remotes/svn/branches/*

Save the changes and do a fetch on a more current revision.

This will treat each folder under branches/fork_a, including trunk, as git remote branches.

The key here is to not use the full url to the specific fork/branch you want to clone; instead, use the svn project root as the url and specify the path relative to the project root in the trunk/branches/fetch options in .git/config. This configuration setting is identical to using git svn clone/init with the –prefix option.

After doing a fetch (specifying a decently recent revision). Your git branch -r looks something like this:

$ git branch -r
svn/branches/1.0.0
svn/branches/1.0.1
svn/branches/trunk

And you’re done! You can now create feature/working branches from these remote branches and work with git and git svn as you normally would.

Hopefully in a future release, we will be able use regexes in place of globs for matching paths in .git/config. It will no doubt make interfacing with nonstandard svn repository layouts using git much easier.

Hopefully this helps some of your out there. Your repository layout may not be identical to the example I provided above, but this technique should be applicable to any reasonably organized repository layout. Right now my solution does not map the tags from svn (1.0.0, 1.0.1) as git tags. If you happen have a better solution, please share!


Impressions with Netbeans 6.7 M3 for PHP

Posted: April 10th, 2009 | Author: Kevin | Filed under: Development, PHP, Tool | Tags: , , , | 7 Comments »

A recent contract job required me to work on-site, which meant that I had to use my laptop as my primary development rig. In eclipse, my low-end 1st gen Macbook Air crawls to its knees (surprise!) when I load it up with a 5000+ file project (including libraries).

Textmate is normally my tool of choice. But since we use a monster framework, code completion and inline documentation will undoubtedly boost my productivity and increase my familiarity with the existing API + codebase, not to mention the added benefit of a debugger to step through the code to know wtf is going on.

I went on a mission to find a new IDE. I decided to revisit Netbeans for PHP (I use it for Java already) by trying out the prerelease. After using Netbeans 6.7 M2 (and recently M3) for 2 months at work, aside from the occasional bugs, I could not be more impressed by its performance and feature-set. If you do decide to try it out, make sure you use the latest milestone release. That would be 6.7 M3 as of this post.

Lets look at some of the key features that I use on a daily basis.

Read the rest of this entry »