Thursday, March 31, 2011

Implementing toString() in C++

In Java, every class inherits from java.lang.Object, which as toString() method. Hence, all classes can have the flexibility to override the toString() method. Unfortunately, for C++ things aren't so straightforward. Although we can easily override the bitwise left shift operator <<, we can do this in a more elegant manner such as below.
Printable.h
#ifndef PRINTABLE_H_
#define PRINTABLE_H_

#include <string>
#include <iostream>
using namespace std;

template <class T>
class Printable {
public:
    virtual string toString() = 0;
    friend ostream& operator<<(ostream& os, T t) {
        os << t.toString();
        os.flush();
        return os;
    }
};

#endif /* PRINTABLE_H_ */

Hello.h
#ifndef HELLO_H_
#define HELLO_H_

#include "Printable.h"

class Hello : public Printable<Hello> {
public:
    Hello();
    Hello(string message);
    virtual ~Hello();
    string toString();
private:
    string message;
};

#endif /* HELLO_H_ */

Hello.cpp
#include <string>
#include "Hello.h"
using namespace std;

Hello::Hello() : message("Hello World!") {
}

Hello::Hello(string message) : message(message) {
}

Hello::~Hello() {
}

string Hello::toString() {
    return "[Hello] message=" + this->message;
}

Main.cpp
#include <iostream>
#include "Hello.h"
using namespace std;

int main() {   
    Hello hello;
    cout << hello << endl;

    Hello anotherHello("Hi World!");
    cout << anotherHello << endl;

    return 0;
}

Wednesday, March 30, 2011

Understanding C++ Pimpl Idiom

In C++, whenever a header file changes, any files that include that header file will need to be recompiled. To avoid such an issue, we can use pimpl (pointer to implementation) idiom.

Hello.h
#ifndef HELLO_H_
#define HELLO_H_

#include <boost/shared_ptr.hpp>

class HelloImpl; // forward declare this

class Hello {
public:
    Hello();
    virtual ~Hello();
    void sayHello() const;
private:
    boost::shared_ptr<HelloImpl> impl;
};

#endif /* HELLO_H_ */

Hello.cpp
#include "Hello.h"
#include <iostream>
using namespace std;

class HelloImpl {
public:
    void sayHello() const {
        cout << "Hello World" << endl;
    }
};

Hello::Hello() : impl(new HelloImpl) {
}

Hello::~Hello() {
}

void Hello::sayHello() const {
    impl->sayHello();
}

In this example, the use of smart pointer, such as Boost shared_ptr is recommended to avoid the hassle of writing the copy constructor, assignment operator, and destructor. With this approach, whenever the implementation changes, the client is insulated from the changes.

Tuesday, March 8, 2011

Getting Started with Gradle

As a build tool, Gradle has a pretty steep learning curve. The official documentation is a good place to start.

build.gradle
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'eclipse'

version = '1.0'

repositories {
    mavenCentral()   
    flatDir name: 'localRepository', dirs: 'lib'
}

dependencies {
    runtime group: 'log4j', name: 'log4j', version: '1.2.+'  
    compile ':junit:4.0'
}

task hello << {
    println System.properties['msg']
    ant.echo('Hello')
}

compileJava.dependsOn(hello)

gradle.properties
systemProp.http.proxyHost=myhost
systemProp.http.proxyPort=8080
systemProp.http.proxyUser=userid
systemProp.http.proxyPassword=password
systemProp.msg

Project structure
gradle-project/src/main/java/MyJava.java 
               src/main/resources/
               src/main/groovy/MyGroovy.groovy
               src/test/java/MyJavaTest.java
               src/test/groovy/MyGroovy.grovy
               src/test/resources/
               build.gradle
               gradle.properties   
              /lib/junit-4.0.jar               

Here, we use Java, Groovy, and Eclipse plugins. With Java plugin, the conventional project structure is defined as below.
src/main/java
src/main/resources
src/test/java
src/test/resources

With Groovy plugin, the conventional project structure is defined as below.
src/main/groovy
src/main/resources
src/test/groovy
src/test/resources
As you can see here, it's very easy to mix between Java and Groovy projects. Gradle also supports another language such as Scala.

To generate Eclipse project:
gradle eclipse
To clean the generated Eclipse project
gradle cleanEclipse

To build the project:
gradle build
This will compile Java and Groovy files.

To clean the project:
gradle clean

As we can see here, it's pretty easy create a custom hello task and make it as a dependency of an existing compileJavaTask as shown in the example above. Because Gradle is based on Groovy, we can leverage on Groovy programming language and Groovy out of the box supports Ant.

To execute the individual task:
gradle hello

To view the list of available tasks:
gradle tasks

With Gradle, it's easy to mix dependency management between Maven and local repository as shown in the example above.

There are still so many things that Gradle can provide, but hopefully this simple tutorial is sufficient to get started with Gradle.

Tuesday, March 1, 2011

How to Remove Trailing Spaces in Python

Although most text editors provide this feature, just for fun, below is a Python script to do that :) This script preserves the newlines.

#!/usr/bin/env python

import sys, os

def del_trailing_spaces(path):
    if not os.path.exists(path): _error(path + "doesn't exist")
    f = open(path, "rb")
    lines = f.readlines()
    f.close()

    f = open(path, "wb")
    for line in lines:
        if line[len(line)-2] == '\r' and line[len(line)-1] == '\n':
            f.write(line[:len(line)-2].rstrip() + line[len(line)-2] +
                    line[len(line)-1]) 
        elif line[len(line)-1] == '\n' or line[len(line)-1] == '\r':
            f.write(line[:len(line)-1].rstrip() + line[len(line)-1])
        else:
            f.write(line.rstrip())
    f.close()                                    

def _error(msg):
    print "Error:", msg
    sys.exit(1)
    
if __name__ == "__main__":
    if len(sys.argv) != 2: _error("invalid argument")
    del_trailing_spaces(sys.argv[1])