Friday, August 24, 2007

'I Follow' Movement

As I've just recently found out, there's a small but growing number of bloggers who are turning off 'rel=nofollow' in their comments, which has been originally proposed by Google as a means of curbing comment spam.

However, the tag has largely fallen short of it's intended effect in deterring spammers, the job taken over largely by Captchas and spam detection software these days, while leaving legitimate users less inclined to comment, after not being to benefit from the increased link count that is important for search engines in spidering your site.

Randa Clay started the 'I Follow' Movement in countering the usage of the 'nofollow' tag used in the comment links. As a fellow supporter being more open, I think it is a great idea, besides the fact it will be great motivator for others to leave a comment on my page as well.

Everybody benefits, I'll get more exposure, while you get rewarded with a link whenever you leave a comment. I've turned off my 'nofollow' link now, and if I've managed to convince you that it is a good idea, be a part of this and join the movement!

Related Post:
Thursday, August 23, 2007

(No) Life Working for a Startup

People like to think that startups are those 'cool' little things that I do, just because it is the hottest in to be in these days, with all the fad about Web 2.0 as the 'next big thing'. Besides the fact that I'm not doing web-based startups, working in a startup feels more like nerve-wrecking enterprise that you constantly spend your time on, running on the fear that things are teetering on the brink of collapse all the time. It is a severe strain on your social life, if you have one to start with, because after working 7 days a week and long hours all day, you'll definitely have none left. So why do it? Because I relish it. Working for a startup IS my life.

Then again, maybe having a social life is underrated. I see friends who work through the week, anticipating for the weekend to come, but when it arrives, scramble to look for something to fill up that void. And then the week starts again. And repeat. Feels like a broken CD player, looping over and over again. Sure, watching a movie and having a couple of drinks with friends is great, but even that gets dull after a while too, especially after the show ends and when the drinks run dry.

It is great to have a fixed job. You have that peace of mind in knowing that your constant monthly paycheck is going to buy you the latest iPhone, your next new car, some fancy dinners, and still have enough left to pay for the mortgage.

I'd like to have job security too, but how secure is it, really? Perhaps we have been so lulled into an illusion of complacency with our supposed 'job security'. There is only security when there is an economy to back it up. And when it tanks, whatever only security will only be left for the highest pecking order on the corporate ladder. When was the last time you've heard that the CEO was the first to be laid off when a company is going through troubled times? Two, One or None? It's counter-intuitive and unfair, but that's how life is.

By trading off security, at least I get to choose what I do. I get to make decisions, ones that probably will affect everybody in it in big ways. That is both a good and a bad thing. Good when it is the right choice, and bad when I've used up a lot of time, only to reach a dead end. Time is wasted, but at least I've learnt something. I've found new things that didn't work.

Making wrong choices still isn't as bad as having the mental block. To have a problem you can't seem to solve is when the real stress kicks in. Panic sets in, and you fear that whatever you've developed is going down the drain because of an obstacle you didn't anticipate. Self doubt creeps in, your confidence plunges and so goes your motivation.

But you persevere.

Some days, work becomes humdrum, irrespective of whatever 'cool' things you're doing. A software developer's job is to make software work. And that means fixing bugs. There are always bugs to fix, only that some are more interesting than others. Certain bugs are consuming, but rewarding, and you'll get a sense of gratification when you find it. Others are the ones that you'd wish you're able to it sweep under the carpet. But they have to be fixed, nonetheless.

That's why perseverance matters.

And on other days, it feels just plain awful. You feel that it may have been better if you had a perfectly normal job like everybody else, write or maintain some already established software like everybody else, have a wife and kids to go home and grumble to like everybody else. Escapism kicks in, and you'd wish that you didn't have to deal with the problems that feels like a piece of the big blue sky.

There is always the temptation of throwing in the towel, especially when you feel like little progress is being made. But it is equally hard to give it up, not at least without giving it a good fight. You live for those fights, the fights that you pick with yourself, because that is when you feel that you are working for what is truly yours.
Wednesday, August 22, 2007

Vim Tips for Java #6: Auto-Bracketing Within Vim

One of the things that I've learnt that Netbeans is able to do, was the ability to perform auto-bracket completion. For a while, I was missing that nifty little feature when I reverted back to using vim, and I tried tweaking around with vim to provide the same feature, only with limited success. Only after writing my tip on tab-completion had I realised that I have already a complete solution in providing for auto-brackets.

The following script I have will allow me to detect whether if I really wanted a closing bracket/brace or whether if has already been inserted previously by the auto-bracketing script, and hence I should skip it, by checking what the current character on the cursor right is. So here's what's needed to be added to your .vimrc in order for it to work:

autocmd Filetype java imap ( ()<left>
function! My_BracketComplete()
let char = strpart(getline('.'), col('.')-1, 1)
if (char == ")")
return "\<Right>"
return ")"
autocmd FileType java inoremap ) <C-R>=My_BracketComplete()<CR>

autocmd Filetype java imap { {}<left><cr><cr><up><tab>
function! My_BraceComplete()
let char = strpart(getline('.'), col('.')-1, 1)
if (char == ")")
return "\<Right>"
return "}"
autocmd FileType java inoremap } <C-R>=My_BraceComplete()<CR>

While it is neither the cleanest nor the most elegant way, but it replicates faithfully with what Netbeans does. Unfortunately, this solution will still not work for quotes and double-quotes because of the nature of the 'imap' command, which will make vim go into a non-terminating loop. So if some of you have thought of a better way to do this, do share it with me by posting your solution on my blog.

If you like reading this, you may also enjoy:
Tuesday, August 21, 2007

Response to the New Blogger's Challenge

First of all, I'll like to thank all my readers for showing interest in my article regarding the state of the Singaporean blogsphere. To be honest, I have only written it because I felt that there is some truth in Mr. Wang's commentary, that there is a still a need for balanced, yet critical voices in order to establish a credible counterweight to the mainstream press.

Having said that, based on my anecdotal observation of the vast number posts that has mushroomed in the last couple of days responding to the Prime Minister's National Day Rally speech, it has proven to a certain extent that people will be willing to talk about the things that matter to them, when it is the time to do so. Therefore, the waxing and waning of social-political participation should not seen to be as alarming as it is made out to be. I hope that should at least put Mr. Wang's mind at ease for now.

Also, while it would have been nice to be able to have participated to Mr. Wang's new blogger's challenge, there are a number of reasons why I will not be doing so. Firstly, being away from Singapore, I have no access to the transcript of what has being said. Secondly, the contents of the rally, while interesting, will probably not affect me much materially, making it hard for me to be emotive about. Thirdly, there will be plenty of people who will have expressed more articulately what I've wanted to say. Lastly, my perspectives of the world are not confined to this 48-by-24 km island anymore, after spending so many years overseas. Politics that interests me may not be immediately relevant to the Singaporean audience.

However, I do want to take this opportunity to thank everybody for the readership that I have received for the last couple of days, however my thoughts on computing will remain as the mainstay of this blog, even though I will chip in my 2 cents worth whenever it is called for.
Saturday, August 18, 2007

On the 'dire' state of the Singaporean blogsphere

I was thinking about writing another issue of 'famous nerds' in my blog, but
decided to write about something else instead. Mr Wang, one of the most respected bloggers in Singapore has recently wrote about his 'national service' in blogging. I am writing in response to his 'call to arms', given that he believes that the rest of the Singaporeans have not be putting their weight into blogging about the things that matters, and paints a depressing picture that if active sociopolitical bloggers like him were to depart, the Singaporean sociopolitical blogsphere will probably simply implode into nothingness.

Perhaps it may be a little be to simplistic to think that the entire blogsphere will vanish overnight even if this 'impossible' scenario were to occur. While the popularity of these key bloggers is probably a good measure of success in the blogsphere, it should not be seen as the key metric of how far we have achieved as a collective. Just because that there are a few more prominent bloggers who are more well read by others, and much appreciatively so, because it helps to put across issues to a bigger segment of population, it does not mean that less read opinions are worth any less their weight.

In order to be a good blogger, one needs to have the talent to write expressively in order to capture the interest of the general masses, which cannot possibly be everyone who simply decides to start a blog. It is the main goal for a blog to attain popularity, but if blogging is all about popularity contests, shouldn't Xiaxue be the crowning glory of our blogging success, given that she is (or was?) probably still undisputedly Singapore's most popular blogger?

I do not disagree that it is important for views to be read by others in order for a blogger to be successful, but the functions of content aggregators cannot be outweighed by just a number of star bloggers. Even though at its infancy, we do have some good content aggregators who help to provide for the 'liquidity' in the dissemination of information, be it manually, like The Intelligent Singaporean and Singapore Surf, or technology assisted content aggregation sites, like and They provide focal points for the dissemination of information that keeps the blogsphere alive, to which I think should be attributed more credit for.

Besides that, there are some social interest blogging groups like The Online Citizen, forums like Sammyboy for public discourse, and good political satire cartoonists, like my sketchbook, talented humourists like Mr. Brown and Mrs. Smoot, and many others, which is just about as important in bringing about social diversity and vibrancy to the blogsphere. After all, it will get a little dry and boring if one is to be constantly reading about political seriousness all the time.

It is also a fact that great bloggers in the virtual world of the Internet will come and go with time, with examples of that happening to notable bloggers like Kitana and Gayle Goh, but even when they do not exist in the virtual world, they are still out there in the real world, making a difference.

As I said about myself that I am partisan in my views, I am mindful not to speak much about socio-political issues, especially Singaporean, because largely, what I have to say of the 'big issues' that are happening, are usually covered by people who are usually more articulate than I am, not surprising given the fact that my expertise lies in coding, not writing, not even to mention about the sensitivity of talking politics in Singapore.

Not that I don't have my point of view on how I think things should be right for Singapore, but they probably can be summed up in a single paragraph: I do not support ministerial pay rises, our threshold for the death penalty is overly harsh, ambivalent about the pros or cons of IRs, support having better welfare for the poor, reducing financial strains for public health care and repealing unfair laws against gay people.

But do my views bring about change in the civil society? In all honesty, I hardly think it does. As an individual, I can take action only when I cast my vote at the ballot boxes, but that can only take place when there is a credible opposition to vote for. But even just to talk about opposition for opposition's sake, we hardly even have that as a luxury, due to the grotesque distortion created by our GRC system, placing an artificial barrier of entry for people to contest in, not to mention the side effect of having untested candidates to ride on the coat-tails of established political heavyweights into parliament.

While disappointing, I do see some winds of change blowing, amid periods when individual MPs start to question and debate the policies enacted by the government, and whenever they provide their own perspectives to things which may not be in line with the party's views. Politicians like MNP Siew Kum Hong, and even MPs from the PAP cadre, like Ms. Lily Neo (in terms of her views of raising social safety nets), which is a refreshing breeze of fresh air, even though it will probably be far off in the future to be able to see MPs voting on a piece of legislation with their conscience, rather than having to toe the party line.

Until that day arrives, it will be hard for me to be voting in people with alternative views like her, given that it will still be equivalent in endorsing the political views of the party she stands for. But I do believe that it is more within the power of the politicians than the population who are able to initiate change, and that it is necessary that we only endorse and support the politicians who champion our views, and pressure those who don't to do what we think is right.

The blogsphere from a perspective, has probably taken more credit than it deserves for its role in society than it really has. To me, when it causes a stir, it is nothing more than just a tempest in a teacup: just as with the many other issues that bloggers write about, mine will just be another voice and opinion among the others. In the grand scheme of things, it probably won't account to anything much by itself. And as much as Mr. Wang believes that 'thought affects reality', I believe that reality can only manifest itself when it is backed by real, concrete action.

Action through civil disobedience, such as the case of Dr. Chee Soon Juan, is probably an example of how not to go about bringing change, as I think his brand of American-styled civil movement tends to alienate and rub Singaporeans the wrong way. That said, I still believe that it is in civil participation, rather than firing up the text editor to write a few paragraphs on your views about things that will have much more effect in the way of making a difference.

I believe that true heroes, are the one who are actively on the ground to achieve something, people who are of a certain mettle, like J.B. Jayaratnam, Chee Soon Juan, Alex Au and Marytn See, people who keep pushing the envelope are the ones who are most likely to bring about change. Bloggers like me, are just akin to commentators on a Saturday night game, or the occasional armchair critic, or at best, a conduit of thoughts which may help galvanize people into taking action.

In all fairness, the Singaporean blogsphere does provides the necessary alternative views to what reality really is, even if it currently does not have the reach of the mainstream press. Given sufficient momentum, it will get there. After all, things like the American Civil Rights movement didn't start and end over the course of a single day, but rather, it is the culmination of perpetual struggle. Like everything else in this world, change only takes place in little baby steps, which may not be as perceptible as we may like it to be.

And of course, if you liked what I have to offer in my opinions on how things should be set right, feel free to subscribe to my blog, and I'd love to have few fans of my own to share my place as being a popular blogger. But to count on just my opinions to bring about change to the social-political environment, it will certainly take more than just that, something which must require the will, gumption and engagement of the entire Singaporean population as a nation.
Friday, August 17, 2007

Vim Tips for Java #5: Folding Code Blocks to prevent Visual Blindness

When dealing with large source files, there is a tendency for visual blindness to kick in, where there is just too much code everywhere for you to find things like the start of a method or a particular important segment of code, in a sea of random visual clutter.

With Vim (6.0 onwards I think), there is support for concept of folding, which helps to segregate your code into meaningful chunks visually, expanding and collapsing the folds as you work. There are a number of keystrokes to learn, so if you are new to folding you might want to read a tutorial like
this one (link to

Initially I wanted a way to automatically generate folds for me based on the type of source code I'm working on, and a nice answer I have found is the SimpleFold plugin from Eigenclass, which helps in creating folds automatically for you by matching the source file with certain patterns.

I believe that it does automatic folding for Ruby quite well, but because of the syntax structure of Java, folding using plain regex probably doesn't fully match my requirements (it doesn't handle the treatment of inner classes and methods that well, and mistakes certain variable declarations as methods) so I tend to use manual folding instead, which is done by using the command:

:set foldmethod=manual

While folding by default on vim looks alright, but I find SimpleFold's display with brackets and indentation much better for differentiation between class definitions and methods, so I decided to shamelessly copy the formatting part of SimpleFold's code for my own nefarious use instead (Copy to .vimrc):

function! Num2S(num, len)
let filler = " "
let text = '' . a:num
return strpart(filler, 1, a:len - strlen(text)) . text

function! FoldText()
let sub = substitute(getline(v:foldstart), '/\*\|\*/\|{{{\d\=', '', 'g')
let diff = v:foldend - v:foldstart + 1
return '+' . v:folddashes . '[' . Num2S(diff,3) . ']' . sub

set foldtext=FoldText()

With the change, you'll see a difference between the indentation of the methods within the folds, and the number of lines within square brackets. And now, it looks much better!

If you like reading this, you may also enjoy:
Thursday, August 16, 2007

Some Gripes About Rails

I'm not a web-application developer, so writing Ruby on Rails code is basically just a past-time. In as much as I like Ruby, being a very elegant and expressive language to code in, I can't exactly say the same for Rails (at least not yet).

'Convention over Configuration' is a good idea, but problem is, sometimes you've got to know what conventions you to be looking out for to do something, and not knowing it can make it a rather frustrating experience, especially when you are starting out.

In order to map out all facets of an application access patterns into conventions, it is also inevitable that there will be much to read and make sense of. Probably something to take note of, and not to mistake that Rails will automatically translate to easy!

Catching all non-matching URLs on Rails

One of the early things that I needed to for a web application, was to try to map all unhandled or malformed URLs to be sent to Rails. It's important to do that especially when it's too easy to make a mistake typing on a URL, also because that instead of the typical 404 message people normally see, Rails gives you an unsightly routing error, with a "no route to match" message:

In order to change that and assign a controller to any unhandled URLs, append the following line as the last statement of your config/routes.rb:
map.connect '*anything', :controller => 'controller', :action => 'action'
Replace controller and action with the desired controller and action respectively. This will allow all unhandled URLs to be managed by the controller of your choosing.
Tuesday, August 14, 2007

Vim Tips for Java #4: Use 'Tab' for Syntax Completion

Note: This tip has been updated, please see Tab Completion for Vim (Updated) instead.

If you have used my previous tip for automatic syntax completion, you might find that using the <CTRL-X><CTRL-U> keystrokes to perform omni-completion can sometimes get quite frustrating after a while. To help address this annoyance, I wrote a little vim function to use the <tab> button to perform syntax completion instead.

The nice thing about that, is the function does contextual scanning to see if you actually want a <tab> or omni-completion to be performed by scanning the token at immediately before the cursor when the <tab> button is pressed.

Put these lines into your .vimrc:

function! My_TabComplete()
let substr = strpart(getline('.'), col('.'))
let result = match(substr, '\w\+\(\.\w*\)$')
if (result!=-1)
return "\<C-X>\<C-U>"
return "\<tab>"
autocmd FileType java inoremap <tab> <C-R>=My_TabComplete()<CR>

The specific pattern I'm looking for in this case is 'objectOrClass.' or 'objectOrClass.incompleteMethodName', but do feel free to change to fit your own needs. Also, if you are using the keyword replacement keystroke <CTRL-P> rather than vjde, you should modify the script to return '\<C-P>' instead.

If you like reading this, you may also enjoy:
Monday, August 13, 2007

How I Managed to Fund Myself through University

University had never been a planned stop in my life. Mostly, I had already consigned myself to live the life of just another worker drone in Singapore just like everybody else, after finishing my military conscription. That would be the responsible thing to do, given that my mother had single-handedly supported me through my life till polytechnic for almost 20 years. It was my time to go out and start working for the household.

Comparatively, life wasn't as dire than the more distant past anymore, given that brother had worked for more than a couple of years already. He had also been saving up the remaining of his salary, so that he could fulfil his dream of going to university. Because his grades didn't permit him to enroll locally, he had set himself to go to Australia to pursue his degree.

During the course of his research in deciding which university to go, through sheer luck, he discovered that the university that I would ultimately end up attending had offered a full scholarship to top graduands from polytechnics and technical institutions in both Singapore and Malaysia.

I thought that it wouldn't have hurt to try, at least just for the 'vindication' of being considered to be 'an elite' if I was offered a scholarship. It was something for fun, given that I had a hell of no chance to study there even if I wanted to. I had no money to pay for my living expenses, had no extended family for help [which I'll write about why that's so in the future], and nothing as collateral to take a loan for, given that our apartment was just a 1-bedroom rental.

It was a surprise that I had qualified and was awarded with the scholarship. It would have been quite competitive, given that there were only so many scholarships that were spread between applicants across all the different institutions from Malaysia and Singapore. While it was a pleasant surprise, nonetheless, in itself had posed a real dilemma for me. Should I go, or not?

At least time was probably the one good thing I had when I was in the army: There were plenty to go around in deliberating on my options. Even so, it was still the reassurance from mom that had tipped my decision.

"Go", she said, "I had already supported you for so many years. Another few years of hardship will not have amounted to any much more in comparison. Besides, having brother to go with you will help defray the costs a bit."

That had left securing a loan as the last hurdle I had to cross. My 'uncle' (no blood relations, just a good friend of mum ever since when I was 10) had heard the good news and offered to seek a loan from his 'sister-in-law' (again, no blood relation to him, as it was his brother-in-law's wife from a re-marriage, when his own sister died of cancer sometime before), who were much better off relative to all those we knew, and might have a little more to offer in terms of financial assistance.

So the day came when my uncle made the arrangement for all of us to meet. I still remember vividly that evening where uncle had offered to drive us there in his taxi to meet his 'sister-in-law', which was at their nicely furnished condominium in a district around town. I was rather apprehensive about the meeting, and my head was filled with thoughts on being on my best behaviour, and on how best to convey my situation to them. But my initial fears were quickly dissolved when they turned out to be such great, wonderful people.

Uncle had already briefed them about my financial situation and our family past, and they had only wanted to meet us and chat up in person before writing out the cheque. It was almost surreal to encounter such generosity in my life, been so used to none at all, given that I had lived all my life in a country where 'welfare' is a dirty word.

That night, Auntie Linette and Uncle Riccardo wrote me a cheque for $20,000 (split between my brother and me), without an IOU, with an indefinite period for repayment and without any interest to repay. It had been one of the most touching moments of my life, for that was first time someone had showed such generosity, faith and trust in us, especially so when it came from total strangers I had only met just minutes ago.

With that $10,000 dollars in loan, a week after my disruption from army, I was on a plane to Sydney, travelling for my first time in life to a far-away land. While the next few years though university wasn't easy, and I had to constantly find ways and means to supplement living costs ($10,000 would not even have covered for the first year of expenses for most people) but it was probably the best years that I ever had.

In a number of other fortuitous turns I had during my time in university, I was able to secure a well paying job prior to completing my studies, and to earn enough money to repay them the loan within 6 months after graduation, at a 25% return on interest. However, they declined to take that excess money and opted for a simple meal at a family restaurant instead.

It is remarkable that life can sometimes turn in weird and unexpected ways, where luck can fall on you when you are least expecting it, against whatever odds that may have felt insurmountable. This is probably not the most typical story of finding success in life, but I do wish my story can give hope to those who wants to try, to take heart in believing, and that it can be yours if you work hard for it.
Saturday, August 11, 2007

Vim Tips for Java #3: Use Omni-Completion (or Intellisense) for syntax completion

As much as I like vim, Netbeans trumps it when we talk about automatic syntax completion. Because of the vast amount of API that is present for the Java platform, the ability of having auto-suggestion for syntax is a godsend.

While things like looking up an API call while you are in the thick of coding are irritating, the effects of such distractions are often much more profound. A recent article by the New York Times suggests that such interruptions do not just result in the reduction of your efficiency, but increase the chances of making mistakes as well.

In vim 7.0, there is a facility that allows you to have auto-suggestion capabilities, which comes bundled for a number of languages like Ruby, Python, etc, but however not for Java. If you have followed my tip in using exhuberant-ctags for Java, the modification will allow vim to have primitive syntax completion capabilities, by using <CTRL-P>. In this case, it tries to match a word you've typed with all the keywords found in ctag's tag file.

The problem with this approach, is that it performs 'dumb' keyword completion of previous matching patterns, rather than the 'intelligent' contextual syntax completion. This can lead to mistakes in suggestions, which can be rather frustrating.

For true contextual syntax completion, there are a few plugins out there works for Java. By and large, they aren't as polished as Netbeans, but still, they are quite functional and and usable. I've used a number of them in the past before, and the one that I reccomend for you to install is vjde.

(An Image of Onmi-Completion for Java in Action)

While the plugin is quite usable, the documentation can use some working on. The default instructions requires you to install it in the /etc/vim global directory, something I'm not willing to do in fear of of messing up my default installation's configurations. Fortunately instructions for local installation is pretty straightforward:

1) Download the latest copy of vjde;
2) Uncompress the downloaded .tar archive;
3) Copy the autoload/, compiler/, doc/, plugin/, syntax/ directories to your $HOME/.vim/ directory;

In order to use the completion, use the <CTRL-X><CTRL-U> keystroke, which will provide you with an Intellisense-like syntax completion capability. Have fun with your new syntax-completion capability, and keep on vimming!

If you like reading this, you may also enjoy:
Friday, August 10, 2007

Passing variable length arguments to a Java Method

It is not well known fact that Java can actually handle variable length arguments passed to its method calls. This is achieved by using "..." operator in argument signature of your method declaration, commonly used when certain arguments to the method are optional. Here's a simple code example to illustrate its usage:

/** Testing variable arguments passing. */
public class Varargs {

public static void main(String args[]) {


myMethod("Hello", "again", "world!");

public static void myMethod(Object ... args) {
System.out.println("You have passed in " + args.length + " arguments ");
for (Object o : args) {
As you can see, I've only declared 1 method called 'myMethod', and have passed an arbitary number of arguments to it, which would have in the past generated a compiler error telling me that the method signatures I've used are not present. But in this case (with Java 1.5 and above), it compiles and produces the following output:

You have passed in 1 arguments

You have passed in 3 arguments

The "..." operator does require you must have at least 1 or more arguments, but while you can pass a null to it, the compiler will generate some output to warn you to be explicit in your variable typing.

Internally, the number of arguments is actually statically determined by 'javac' compiler, and converted to an object array for processing, so there are limitations in the sense that it is not truly dynamic, but just a compilation convenience method that can save you from writing multiple method signatures for different permutations of the same method call.

If you like reading this, you may also enjoy:
Wednesday, August 08, 2007

Vim Tips for Java #2: Using exuberant-ctags

ctags is a great tool for programmers. It creates an index to your source code to allow you to trawl through them for cross referencing. While the way it works doesn't look as snazzy as nicely formatted javadoc output like Netbeans, it does its job well enough for you to read up a field or method definition whenever you need it. You'll need to install exuberant-ctags separately, which you can find on its website.

A requirement of using ctags, is that you'll need to have the Java source code available for ctags to parse them into a searchable index file for vim. It's usually located in your Java distribution at $JAVA_HOME/ Unzip the file, and in my case I extract it into the $JAVA_HOME/share directory I've created. Then run exuberant-ctags:

exuberant-ctags -R --language-force=java -f.tags /opt/sun-jdk-

This command generates a '.tags' index file in my home directory. The next thing to do is to allow vim to be able to locate and use the index file. Add the following line into your .vimrc:

autocommand FileType java set tags=~/.tags

This should now allow you to jump to any definition in the Java API, whenever you need to look it up from your code. To test this, create a Java file and put some code in it:

public class TestClass {
String s = new String();

Move your cursor under to the word 'String' and press ctrl-]. Voila, you should now be reading into the source of.. not just yet, it is not java.lang.String! Most probably it is showing you some other classes that has a String object in its field, which is probably not what you are looking for. To cycle through the remaining matches, use the command mode instruction ':ts' to go through the list of matching tags and select the right item you want.

You might also want to be familiarized with the navigation keystrokes, by doing a ':help' on ':ta', ':ts', 'CTRL-L', 'CTRL-]', which may be useful.

A few dissatisfactions that I still have with this method:

1) It doesn't allow me to read the embedded javadocs in code as html. It will be pretty cool if this feature can be linked to lynx and shown in a window within vim, but I'm not certain if it is possible;

2) I don't believe that searching through all the miscellaneous fields of other classes is the best way of using ctags. There may be something that I have not mastered that permits me to fully utilize the power of ctags yet.

I'll be looking further to see if I can learn more tips on using ctags, but in the meantime, if anybody have any suggestions for improvement, I'll appreciate if can leave a suggestion, thanks!

If you like reading this, you may also enjoy:

Famous Nerds In Computer Science: Alan Turing

It isn't too uncommon to find these images of captchas on websites we visit anymore these days, where it is frequently used to identify humans from computer bot spammers. Captcha is actually an acronym for 'Completely Automated Public Turing test to tell Computers and Humans Apart', it's name derived from one of the most prominent computer scientists of our time, Alan Turing.

Alan Turing (1912-1954) is one of the founding fathers of computer science, who devised the Turing Machine, the superset of all computers that we have today, and the Turing Test, an Artificial Intelligence test which remains the ultimate goal of computing research till this day.

In his life, he had played a major part in helping the British crack the encryption ciphers of the Enigma machine used by the Germans in WW2, and was considered as a war hero for his efforts. Amid his achievements in life, it was however cut short by the fact that he was gay, where in those days, private homosexual acts were illegal by law.

Alan was prosecuted and subsequently convicted, and also had his access to his code breaking work rescinded of because of his criminal charges. He was forced to undergo psychiatric treatment in order to avoid jail time, which involved injecting himself with female hormones to control his sexual urges.

At the age of 41, Alan Turing committed suicide, by consuming a poisoned apple laced with cyanide.

13 years after his death, Britain decriminalized the law in 1967.

It is sad to see a great contributor to society come to such an end to his life just because his alternative lifestyle do not conform with society norms. This story is a reminder that being different from us, does not necessarily mean that they are wrong, and that we should not be closed up in terms of our thinking, for every time society snuffs out a brilliant person just because of their differences, we will only take a step backwards in terms of progress as a civilization.

This entry is written in conjunction with Indignation, a gay pride event held in Singapore, and also in response to Nominated Minister of Parliament Siew Kum Hong's article for speaking up against Section 377A of the Penal Code. As a heterosexual individual, I share NMP Siew's views, and supports the repealing of Section 377A.

Also, 9th August is Singapore's National Day, so I wish all Singaporeans a Happy Holiday!

Monday, August 06, 2007

Vim Tips for Java #1: Build Java files with Ant automatically

Ant is a great tool for compiling large projects with a large number of Java files. It is the equivalent of 'make' for C, but is customised specifically for Java. While the support for make works with vim by default, certain changes have to be made for vim in order to make it work properly for Java.

Add the following lines in your .vimrc:

autocmd BufRead *.java set efm=%A\ %#[javac]\ %f:%l:\ %m,%-Z\ %#[javac]\ %p^,%-C%.%#
autocmd BufRead set makeprg=ant\ -find\ build.xml

As long the build.xml file is in the parent directory of where the Java files you are working on is located, vim will be able to locate it, compile the changed files and inform you of where the compilation errors are.

All that's remaining is just to type :make, and you now have automatic compilation from within Vim!

If you like reading this, you may also enjoy:
Saturday, August 04, 2007

My Goals in Life

A friend of mine wrote me an email on my birthday recently. In her mail, she asked if I had achieved my goals in life, and what are they? I think it is a rather interesting and apt question to be asking on a birthday, for I feel that is a great time for me to review and stock take on what I have achieved, as well as what I haven't achieved in life.

It shouldn't be surprising that my answer to the first question is a 'no'. However, what's interesting is probably my answer to the second question: there are a few goals in life that I am working towards, but only a few of them had solidified into something tangible that I am able to have a metric of measurement, one of which being the measure of financial success.

In the past, the idea of being rich has always been a hazy concept I had in my head, even though it has always been a constant goal of mine. The exact definition of what is constitutes as what's being rich differs with different people, but unlike most people's expectations where rich means driving a new Ferrari, having a new sailboat or a new Gulfstream jet (I'm not kidding!), my goals are much more modest.

It is to have a fixed income stream from liquid assets that is sufficient to cover my daily expenses.

The figure? $400,000, which I'm expecting to give me at least 5% returns yearly (that isn't very hard to beat!). The number is nothing magical, but just something I have calculated to allow myself to be modestly independent financially.

I hope nobody gawks at my goal, granted that the returns from $400,000 is probably just be enough to foot for the average yearly rent in Sydney, with a little remaining for the day to day expenses, only if I scrimp. That has been my intention by design, as I am a believer that a person needs the hunger in order to have the motivation to move himself ahead. The money is, and just is, as an insurance to cushion my fall, should life start to get a little rough.

It is also by no coincidence that I that I have chosen a figure because I believe it is something that I should be able to attain. I have been pursuing that goal assiduously for the last couple of years, combining that with prudent investments and a bit of luck, I should be able to get there in the time frame I've had in mind, which is hopefully before I hit 30.

Why the rush in having in trying to amass such a huge sum of cash, given that I'm single, able and largely independent? Unlike most people, I have a mother who has spent more than 25 years of her life, raising and funding both my brother and I through university. It is remarkable, given that she is a single mother with only 4 years of primary school education. Granted that she doesn't have a lot of personal savings, it isn't too surprising that the sum of money accumulated will also be used in preparation for her later years.

As I currently stand, I am only at a quarter of my way there. With 2 years down the road remaining, it is going to be a formidable goal. I know it won't be easy, but I am going to try. Hopefully, all that's remaining is some hard work, prudent fiscal management, a lot of faith and a bit of luck!
Friday, August 03, 2007

Managing Code Fatigue

One thing about being a software developer, is that we have this misguided self-belief that we are 'ironmen', to borrow the phrase from Po Bronson's book, 'The first 20 million is always the hardest'. I find that I have a tendency to spend long hours in front of the screen and taking little breaks, especially when I'm 'in the flow'. The problem is, the toll it has on my body is being rather apparent: I've just turned 28, and already I am suffering from bouts of backaches, eyestrains and mental fatigue on a semi-regular basis. Reality is, unforgivingly stark. If I don't take adequate care now, in a few years, things will get worse. So I'm trying to correct certain habits that some of you may relate to:

Have a comfortable work environment
I'm not suggesting that you bring your bedroom to your workplace, but there are things that you can change to make it better. It may be time to do something about that morning glare through your office window (I have), or the suboptimal lighting conditions you've grown used to, or the polka dot wall panelling that has been giving you a migrane, or any other little niggling things that you have learnt to cope with for too long.

Have a good sitting posture
Out of all the enviromental factors in the workplace, I think sitting posture deserves a mention itself. Because of the amount of time developers spend sitting in front of their desks, back pain is a common, but severe problem. Observe yourself next time you sit down, and check if you are shifting your weight regularly. If you are, the way you sit is probably not good for your back (or your bum). Check if changing to a different chair, or modifying the height of your table helps. Or adjust the placements of your monitor, keyboard or the mouse. Sometimes, it is the little things that make a big difference.

A good exercise routine helps to maintain good posture and body strength to offset the long hours of stagnant activity. It also helps take your mind off the heavy thinking that you have done over the course of the day. I find that exercise helps massively. Jogging and ski machines are great in relieving the mental stress, while crunches and abdominal exercises help maintain strength on my lower back. I do weights for my upper back and shoulders, which is where the majority of my pain is coming from. Thankfully, it has been getting better after maintaining my regular routine to the gym.

Not have coffee
I know this is so controversial that some of you may consider it blasphemous! Coffee is a great stimulant, and works wonders for a dull afternoon with boring coding tasks, but I find that it affects my sleep patterns at night. If you are one those people who are prone to sleeplessness, it may help to know that coffee can be one of causes, and reducing your intake will help.

Have a good night's rest
Even though most agree that having sufficient sleep is necessary for performing well at work, we do have a tendency to flout this piece of well meaning advice rather blantently. Be it rushing a deadline, or just after hours distractions like playing World Of Warcraft and chatting up with friends on MSN, it is difficult not to, especially when it is an entitlement after a long day. The bad news is, not getting enough rest makes you much less alert for the next day, escalating a cycle of increasing coding errors that just is going lengthen the your day further.

Take a break!
If you feel that your brain is like mush, it is a sure sign that you have exceeded your own limits. Granted, you may have tons of work waiting ahead of you, but it is time to get some rest and to recharge yourself. All things being equal, your personal well being is not worth trading for any satisfaction you derive from completing an ardous task, trust me.

That said, it is so easy to lapse back into bad old habits, but the sooner you can identify them, the faster you'll change it and improve the quality of your life. Undeniably, it may be hard for established 'computer potatoes', but keep in mind that it is usually the hardest things that are worth doing. You'll live to appreciate your job better, and last longer, and thank yourself for it.

( Minor Edit: I realised I've misspelt Po Bronson's last name, and so it has been corrected. My apologies! )