Paulo Poiati | Blog

@SuppressWarnings(“useless”)

  • Home
  • About
  • Github
  • GMongo
  • SandBox
Twitter Facebook RSS

A not well know and underestimated css property: box-sizing

Posted on 12/05/2012 by Paulo Poiati
No Comments

The box-sizing (introduced in CSS3) is one of the forgotten properties, no one talks about it but can be really useful in some situations.

What it does? In the Mozilla words:

The box-sizing CSS property is used to alter the default CSS box model used to calculate widths and heights of elements. It is possible to use this property to emulate the behavior of browsers that do not correctly support the CSS box model specification.

There are two possible values for this property:

  • content-box (default)
  • boder-box

The content-box is the default value, when it is set, the padding and border properties are put outside the bounds of your element, for example:

div.box { width: 200px; height: 200px; border: 15px solid black; padding: 10px; }
<-- 250px -->

The above box total width and height will be:

200 + (2 * 15) + (2 * 10) = 250px

Now, if we change to border-box:

div.box { 
  box-sizing: border-box; 
  width: 200px; height: 200px; border: 15px solid black; padding: 10px; 
}
<-- 200px -->

The box size stay unchanged. By the way, this behavior in the box model is analogous to Internet Explorer when the document is in Quirks mode.

Share and Enjoy

Categories: CSS | Tags: css, html, web

jQuery Builder: Introduction

Posted on 16/02/2012 by Paulo Poiati
No Comments

Which web developer never built DOM elements programmatically? It’s a mess, don’t is?

Well, it was a lot worse in the past. When the only way to do that was appending strings or with the standard Document Api (Document#createElement, Document#appendChild …). But In the past few years the things got better. Javascript Frameworks emerged and one of the them was the well know jQuery.

jQuery has a smarter API to build DOM elements. The main advantage of using jQuery is the method chaining. But is out there a better approach ? I was seeking for one and I found just a few projects, one of them was jquery.builder from Jeremy Ruppel, a new but promising project. One week later I was helping her to evolve it.

Usage

To start building, use the build method. You can give this build method a block.

$( '#context' ).build( function( )
{
  this.div( 'hello!' );
} );

$( '#context' ).html( ); // =&gt; &lt;div&gt;hello!&lt;/div&gt;

In this block and any child blocks, this refers to the builder instance. The same builder instance will also be passed to the block if you want to name the reference.

$( '#context' ).build( function( b )
{
  b.div( 'hello!' );
} );

The builder object has a method for every common html tag, but you can add your own tag methods easily (more on that later).

For building node hierarchies, you can give any tag method a block and the builder will adjust its scope appropriately:

$( '#context' ).build( function( )
{
  this.div( function( )
  {
    this.div( 'nested' );
  } );

  this.span( function( )
  {
    this.a( 'hierarchy' );
  } );
} );

$( '#context' ).html( ); // =&gt; &lt;div&gt;&lt;div&gt;nested&lt;/div&gt;&lt;/div&gt;&lt;span&gt;&lt;a&gt;hierarchy&lt;/a&gt;&lt;/span&gt;

Scope can be nested as deeply as you want. Go crazy.

You can pass a hash of options to any tag method and those key-value pairs will be added as attributes to the created node.

$( '#context' ).build( function( )
{
  this.a( { href : 'github.com' } );
} );

$( '#context' ).html( ); // =&gt; &lt;a href="github.com"&gt;&lt;/a&gt;

The options hash may also be passed after the node text, like:

$( '#context' ).build( function( )
{
  this.a( 'github rules', { href : 'github.com' } );
} );

$( '#context' ).html( ); // =&gt; &lt;a href="github.com"&gt;github rules&lt;/a&gt;

If you need the reference to the current scope DOM element you can use the $ variable. For Example, to add a mouse click event to an element:

$( '#context' ).build( function( )
{
  this.span(function ( )
  {
    this.text( 'Click Me' );
    this.$.click(function( )
    {
      alert( 'Hello There!' );
    } );
  } );
} );

Custom Tags

If you’re building XML, you’re going to need some custom tags. jquery.builder can be set up to build any tag that isn’t a reserved word. Just pass your tag name to the build method and it will be available on any new builders.

$( '#context' ).build( 'custom' );

$( '#context' ).build( function( )
{
  this.custom( 'sweet' );
} );

$( '#context' ).html( ); // =&gt; &lt;custom&gt;sweet&lt;/custom&gt;

If at any point you need to reset the tag list to the defaults, just pass false to the build method.

Right now, custom tags are shared between all builder instances regardless of their context node.

Expressions Syntax

Expressions is the easiest way to create nested elements. Using it you don’t need to specify a function to every nested object. You can also mix expressions style with the standard builder style.

$( '#context' ).build( function( )
{
  this( 'body div ul', function ( )
  {
    this( 'li', function ( )
    {
      this.a( function ( ) { this.text( 'Hello World' ); }, { class: 'text' } );
    } );
  } );
} );

$( '#context' ).html( ); // &lt;body&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a&gt;Hello World&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/body&gt;

If the tag name is omitted but a class or id is present it will infer a div element, for example:

$( '#context' ).build( function( )
{
  this( '.foo', 'Hello, Foo!!!' );
} );

$( '#context' ).html( ); // &lt;div&gt;Hello, Foo!!!&lt;/div&gt;

The source code and documentation is available: on the Github page. Any question or suggestion are welcome.

Share and Enjoy

Categories: Javascript, jQuery | Tags: builder, html, javascript, jquery

Installing VimRepress in MacVim (OSX Lion)

Posted on 07/02/2012 by Paulo Poiati
3 Comments

Installing VimRepress should be trivial for almost every case but one exception is installing it in MacOSX Lion. If you installed MacVim compiling the source without specifying the architecture it will use the x86_64 (default for Lion) even if you are using homebrew.

The problem is, the python interpreter will not work correctly if you are using the 64 bits version, you need to recompile for the i386 architecture.

If you are not using any package manager you just need to pass the --with-macarchs=i386 to the configure script.

In the case of homebrew you need to change the formula with the command:

$ brew edit macvim

With the formula open search for --with-macarchs and set it to i386 (you will need a little Ruby knowledge).

Uninstall macvim:

$ brew uninstall macvim

And install it again:

It’s important to use the system ruby version when using homebrew (the one that ships with MacOS). If you are using rvm set the current ruby to the system: rvm use system.

$ brew install macvim

If the install was successfully we are ready to install and configure VimRepress.

Share and Enjoy

Categories: OSX, Vim | Tags: brew, osx, python, vim, wordpress

Easyhash: An easy interface to generate md5 and sha1 hash in hexadecimal format

Posted on 31/12/2011 by Paulo Poiati
No Comments

Generate hash in hexadecimal format is a common need for most developers. Generally this is an easy task, but like a lot of stuff it’s complicated to do in Java. You need to use the java.security.MessageDigest API and convert the result from bytes to a hexadecimal string.

Unfortunately, even in Groovy there is no easy path. With that in mind I developed a small library to do the work.

Using Java

First, Put the easyhash jar into the classpath and then:

import static com.lazythought.easyhash.HashGenerator.*;
...
assert "ab07acbb1e496801937adfa772424bf7".equals(md5("foo bar baz"));
assert "c7567e8b39e2428e38bf9c9226ac68de4c67dc39".equals(sha1("foo bar baz"));
...


Using Groovy

With Groovy you can use the @Grab AST:

@Grab('com.lazythought:easyhash:1.0')
import static com.lazythought.easyhash.HashGenerator.*

assert 'ab07acbb1e496801937adfa772424bf7' == md5('foo bar baz')
assert 'c7567e8b39e2428e38bf9c9226ac68de4c67dc39' == sha1('foo bar baz')



There is also the HashCategory option:

@Grab('com.lazythought:easyhash:1.0')
import com.lazythought.easyhash.HashCategory

use(HashCategory) {
    assert 'b071ed8a2de56ecd5958305641a81755' == 'frodo bags'.md5()
    assert 'b6b5ece040fd0c467cb189a284c6e7c752c747f5' == 'frodo bags'.sha1()
}


More info

It’s Available at Maven Central:

<dependency>
    <groupId>com.lazythought</groupId>
    <artifactId>easyhash</artifactId>
    <version>1.0</version>
</dependency>

Source code: https://github.com/poiati/easyhash

Share and Enjoy

Categories: Groovy, Java | Tags: easyhash, groovy, java

Grails / GORM: Changing default id name and type from an entity

Posted on 04/10/2011 by Paulo Poiati
No Comments

While developing a simple application at work I got stuck with a common case in GORM, and I didn’t found the solution in the documentation.

I have a table with a column named myid of type varchar. But the GORM, by default, auto generate an id property for you with the long type. The solution is straight forward, just call the method id in the mapping closure, with the following param(s):

class Foo {

    String myid

    static constraints = {}

    static mapping = {
        id generator: 'assigned', name: 'myid'
    }
}

The generator is the strategy to auto-generate the id, you can use a sequence or something like, since it’s a string the value will be assigned, not generated. The name is the current property to bind the value (myid in this case).

Share and Enjoy

Categories: GORM, Grails, Groovy | Tags: grails gorm groovy

Groovy / GMongo tips and tricks

Posted on 29/01/2011 by Paulo Poiati
1 Comment

Based on some emails I received last days I will show some features of GMongo that not everyone is aware.

Regex based search

In the mongo official Java driver you can do searches using Regular Expression. To do that you just need to pass a java.util.regex.Pattern instance as the search term. In Groovy there is a shortcut to create a Pattern: ~/regex/.

For example:

def pattern = ~/mypattern/
assert pattern.class.is(java.util.regex.Pattern)

Here is a small script demonstrating the usage of regex search:

@Grab('com.gmongo:gmongo:0.6')
import com.gmongo.GMongo

def gmongo = new GMongo('localhost:27017')
def db = gmongo.getDB('tips')

db.so.drop()
db.so << [name: 'Windows XP']
db.so << [name: 'Windows 7']
db.so << [name: 'Windows Vista']
db.so << [name: 'Mac OS X v10.3 "Panther"']
db.so << [name: 'Mac OS X v10.4 "Tiger"']
db.so << [name: 'Mac OS X v10.5 "Leopard"']
db.so << [name: 'Mac OS X v10.6 "Snow Leopard"']
db.so << [name: 'Mac OS X v10.7 "Lion"']

// Mac OS Only
println "\nMac Os Only\n"
db.so.find([name: ~/^Mac/]).each { so ->
    println so
}

// Print: 

// Mac OS Leopard, Snow Leopard
println "\nMac OS Leopard, Snow Leopard\n"
db.so.find([name: ~/Leopard/]).each { so ->
    println so
}

Persisting your POGO

There is an easy way to persist your POGO using GMongo. Suppose we have the class:

class Person {
   def name
   def age
}

In Groovy we can get all properties from a class using the properties property, for example:

def person = new Person(name: 'Paulo', age: 25)
println person.properties

This code outputs:

[
  class:class Person,
  age:25,
  metaClass:org.codehaus.groovy.runtime.HandleMetaClass@450a10011],
  name:Paulo
]

As you can see, not every property means something to us. We doesn’t want to store class and metaClass in our storage, because it isn’t part of the domain. So, we need to ignore them:

println person.properties.findAll { !['class', 'metaClass'].contains(it.key) }

Now, all we need to do is persist this Map in MongoDB. Here is a complete example:

@Grab('com.gmongo:gmongo:0.6')
import com.gmongo.GMongo

class Person {
   def name
   def age
}

def gmongo = new GMongo('localhost:27017')
def db = gmongo.getDB('example')

def person = new Person(name: 'Paulo', age: 25)

db.persons.drop()
db.persons << person.properties.findAll { !['class', 'metaClass'].contains(it.key) }

def personFromMongo = db.persons.findOne()

assert 'Paulo' == personFromMongo.name
assert 25      == personFromMongo.age

BasicDBObject to POGO conversion

The class com.mongodb.BasicDBObjects extends java.util.LinkedHashMap so it’s easy to convert it to POGO, thankfully to Groovy array notation constructor call. Don’t worry, I will explain. Suppose we have the class:

class Person {
   def name
   def age
}

The two statements bellow are equivalent:

Person mike = new Person(name: 'Mike', age: 23)
Person john = [name: 'John', age: 36]

To this work you need to use typed variable. If you use untyped variable definition Groovy can’t infer what constructor to call.

So, taking advantage of this cool Groovy feature you can do things like this:

@Grab('com.gmongo:gmongo:0.6')
import com.gmongo.GMongo

class Person {
   def name
   def age

   def whoIAm() {
       "Hello, I'm $name and I have $age year."
   }
}

def gmongo = new GMongo('localhost:27017')
def db = gmongo.getDB('example')

def person = new Person(name: 'Paulo', age: 25)

db.persons.drop()
db.persons << person.properties.findAll { !['class', 'metaClass'].contains(it.key) }

Person personFromMongo = db.persons.findOne().findAll { it.key != '_id' }

assert "Hello, I'm Paulo and I have 25 year." == personFromMongo.whoIAm()

As you can see, we need to remove the _id property from the Map before instantiate the class Person, that is because Person hasn’t this property. Another alternative is add the _id property to the Person class.

Any feedback is appreciated.

Share and Enjoy

Categories: GMongo, Groovy, Programming | Tags: gmongo, groovy, mongodb

GMongo available at Maven Central

Posted on 03/07/2010 by Paulo Poiati
1 Comment

A maintenance release (0.5.1) of GMongo was launched. It just fixed a bug with com.mongodb.DB#createCollection.

But the good news is the GMongo availability in the Maven Central (http://repo2.maven.org/maven2/).

Maven:

<dependency>
      <groupId>com.gmongo</groupId>
      <artifactId>gmongo</artifactId>
      <version>0.5.1</version>
</dependency>

Ivy:

<dependency org="com.gmongo" name="gmongo" rev="0.5.1"/>

Groovy Grape:

@Grab(group='com.gmongo', module='gmongo', version='0.5.1')

This should compile and run seamlessly in an environment with Groovy 1.7.2 (or later):

@Grab("com.gmongo:gmongo:0.5.1")
import com.gmongo.GMongo

def mongo = new GMongo("127.0.0.1", 27017)
def db = mongo.getDB('myDb')

db.greetings.insert(hello: 'world')

Updated: Version 0.6 is now available as well.

Share and Enjoy

Categories: GMongo, Groovy, NoSQL | Tags: gmongo, groovy, java, mongodb, nosql

GMongo 0.5 Released

Posted on 20/06/2010 by Paulo Poiati
24 Comments

UPDATE: GMongo is in constantly development, for more details check https://github.com/poiati/gmongo.

GMongo is an alternative to de default Java driver for Mongodb. It’s use an easy and less verbose syntax, the grammar is very close to the official mongo shell cliente (javascript).

It’s just a wrapper around the Java driver. So, every single method of the the official driver is available here too.

The main class is the com.gmongo.GMongo. It has the same API of the com.mongodb.Mongo but it’s not a subclass. Instead, the methods calls are delegated. Despite GMongo, all other classes are the same from the Java driver.

To be more practical, here are some examples:

// To download GMongo on the fly and put it at classpath
@Grab(group='com.gmongo', module='gmongo', version='0.5.1')
import com.gmongo.GMongo
// Instantiate a com.gmongo.GMongo object instead of com.mongodb.Mongo
// The same constructors and methods are available here
def mongo = new GMongo("127.0.0.1", 27017)

// Get a db reference in the old fashion way
def db = mongo.getDB("gmongo")

// Collections can be accessed as a db property (like the javascript API)
assert db.myCollection instanceof com.mongodb.DBCollection
// They also can be accessed with array notation
assert db['my.collection'] instanceof com.mongodb.DBCollection

// Insert a document
db.languages.insert([name: 'Groovy'])
// A less verbose way to do it
db.languages.insert(name: 'Ruby')
// Yet another way
db.languages << [name: 'Python']

// Insert a list of documents
db.languages << [[name: 'Javascript', type: 'prototyped'], [name: 'Ioke', type: 'prototyped']]

def statics = ['Java', 'C', 'VB']

statics.each {
	db.languages << [name: it, type: 'static']
}

// Finding the first document
def lang = db.languages.findOne()
assert lang.name == 'Groovy'
// Set a new property
lang.site = 'http://groovy.codehaus.org/'
// Save the new version
db.languages.save lang

assert db.languages.findOne(name: 'Groovy').site == 'http://groovy.codehaus.org/'

// Counting the number of documents in the collection
assert db.languages.find(type: 'static').count() == 3

// Another way to count
assert db.languages.count(type: 'prototyped') == 2

// Updating a document using the '$set' operator
db.languages.update([name: 'Python'], [$set: [paradigms: ['object-oriented', 'functional', 'imperative']]])

assert 3 == db.languages.findOne(name: 'Python').paradigms.size()

// Using upsert
db.languages.update([name: 'Haskel'], [$set: [paradigms: ['functional']]], true)

assert db.languages.findOne(name: 'Haskel')

// Removing some documents
db.languages.remove(type: 'prototyped')
assert 0 == db.languages.count(type: 'prototyped')

// Removing all documents
db.languages.remove([:])
assert 0 == db.languages.count()

// To ensure complete consistency in a session use DB#inRequest
// It is analogous to user DB#requestStarted and DB#requestDone
db.inRequest {
	db.languages.insert(name: 'Objective-C')
	assert 1 == db.languages.count(name: 'Objective-C')
}

And a simple MapReduce:

@Grab(group='com.gmongo', module='gmongo', version='0.5.1')
import com.gmongo.GMongo

// There is some bug using the [Random] word into codesnipt plugin
import java.util.Random as Rand

def mongo = new GMongo("127.0.0.1", 27017)
def db = mongo.getDB("gmongo")

def words = ['foo', 'bar', 'baz']
def rand  = new Rand()		

1000.times {
	db.words << [word: words[rand.nextInt(3)]]
}

assert db.words.count() == 1000

def result = db.words.mapReduce(
	"""
	function map() {
		emit(this.word, {count: 1})
	}
	""",
	"""
	function reduce(key, values) {
		var count = 0
		for (var i = 0; i < values.length; i++)
			count += values[i].count
		return {count: count}
	}
	""",
	"mrresult",
	[:] // No Query
)

assert db.mrresult.count() == 3
assert db.mrresult.find()*.value*.count.sum() == 1000

It’s a stable version and still a work in progress. The only dependency is the mongo Java driver version 2.0 and, of course, Groovy. It’s tested under Groovy 1.7.2 and 1.7.3. It’s opensource and hosted at http://github.com/poiati/gmongo.

The binaries can be found at Maven Central.
Click here for more details.

Any bug, suggestion or issue, please, contact me.

Share and Enjoy

Categories: GMongo, Groovy, NoSQL | Tags: groovy, java, mongodb, nosql, opensource

Forwarding Objective-C Messages

Posted on 05/12/2009 by Paulo Poiati
2 Comments

Unlike Java or plain C, Objective-C work with messages. You don’t invoke a method on an object, instead, you send a message to it (like the Ruby language). This approach let a more dynamic behavior. For instance, suppose that you have this class:

// SomeClass
#import <Cocoa/Cocoa.h>
@interface SomeClass : NSObject {
}
-(void)doSomething
@end
#import "SomeClass.h"
#import "Delegate.h"
@implementation SomeClass
-(void)doSomething {
   NSLog(@"doSomething was called on %@", [self className]);
}
@end

As you can see it has only one instance method definition, called “doSomething”. Thus, it can respond to the “doSomething” message. But, what happens when we send a message that the receiver can’t respond to ? Lets make a try:

The receiver is the object that will receive the message. For example, in the following statement:

Dog *dog = [Dog new];
[dog bark];

dog is the receiver and bark is the message.

Here is our main code:

//MethodMissing
#import <Foundation/Foundation.h>
#import "SomeClass.h"
int main (int argc, const char * argv[]) {
  NSAutoreleasePool *pool = [NSAutoreleasePool new];
  SomeClass *someClass = [SomeClass new];
  [someClass doSomething];
  [someClass doSomethingElse];
  [pool drain];
  return 0;
}

This code compiles with warnings, because the message “doSomethingElse” is not defined in the SomeClass interface. Errors in the Objective-C message dispatch system occurs at runtime. Programmers need to be more careful when dealing with more dynamic languages.

Running the code we got the following result:


MethodMissing[1695:a0f] doSomething was called on SomeClass
MethodMissing[1695:a0f] -[SomeClass doSomethingElse]: unrecognized selector sent to instance 0x10010c6c0
MethodMissing[1695:a0f] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SomeClass doSomethingElse]: unrecognized selector sent to instance 0x10010c6c0'

Not surprisingly the program crashed. First it invoke our declared “doSomething” message and logged the message to the console, all ok until now. But, in line eight we got a NSInvalidArgumentException with the error “-[SomeClass doSomethingElse]: unrecognized selector sent to instance 0x10010c6c0″.

This error message is very readable, the problem is that, there isn’t any message that respond to “doSomethingElse” in the class “SomeClass”, even at runtime.

And we got to the key topic of this post. We can handle unrecognized selectors messages and do a special treatment when it arrive to the receiver. How we do that ?

We need to overwrite two methods from the NSObject class in the receiver class:
-(void)forwardInvocation:(NSInvocation *)invocation
-(NSMethodSignature*)methodSignatureForSelector:(SEL)selector

An NSInvocation is an Objective-C message rendered static, that is, it is an action turned into an object. NSInvocation objects are used to store and forward messages between objects and between applications.

Now our classes looks like this:

// ForwardClass
#import <Cocoa/Cocoa.h>
@interface ForwardClass : NSObject {
}
-(void)doSomethingElse;
@end
#import "ForwardClass.h"
@implementation ForwardClass
-(void)doSomethingElse {
	NSLog(@"doSomething was called on %@", [self className]);
}
@end
// SomeClass
#import <Cocoa/Cocoa.h>
@interface SomeClass : NSObject {
	id forwardClass;
}
-(void)doSomething;
@end
#import "SomeClass.h"
#import "ForwardClass.h"
@implementation SomeClass
-(id)init {
	if (self = [super init]) {
		forwardClass = [ForwardClass new];
	}
	return self;
}
-(void)doSomething {
	NSLog(@"doSomething was called on %@", [self className]);
}
-(void)forwardInvocation:(NSInvocation *)invocation {
	if (! forwardClass) {
		[self doesNotRecognizeSelector: [invocation selector]];
	}
	[invocation invokeWithTarget: forwardClass];
}
-(NSMethodSignature*)methodSignatureForSelector:(SEL)selector {
	NSMethodSignature *signature = [super methodSignatureForSelector:selector];
	if (! signature) {
		signature = [forwardClass methodSignatureForSelector:selector];
	}
	return signature;
}
@end

When an object receive a message it doesn’t recognize, it wraps the invocation in a NSInvocation object and call the -(void)forwardInvocation passing it as parameter. But, first, it call the -(NSMethodSignature*)methodSignatureForSelector to get the method signature for the given selector.

Now, running the same program again we got:


MethodMissing[523:a0f] doSomething was called on SomeClass
MethodMissing[523:a0f] doSomethingElse was called on ForwardClass

And the program finished without any problems.

There are a lot of uses for this technic, some examples are:

  • Wrap one object in a logger object that intercepts and records the invocation of interesting
    messages.

  • Implement “synthetic” messages that are handled by other methods in your class. Imagine creating a generic database record object that catches any property message it receives (i.e., -saleDate, -setSaleDate:) and automatically translates it into a record query. Instead of coding date = [record getDateFieldWithKey:@"SaleDate"], you could simply write date = [record saleDate], without ever writing a -saleDate method. NSManagedObject and CALayer are examples of classes that implement synthetic properties.
  • Create an object that forwards the message to a hierarchy of other objects, like a responder chain. Chapter 20 talks about responder chains. The proxy object would search a collection of other objects looking for one that implements the message

In a future post I will demonstrate one real world application of this.

Share and Enjoy

Categories: Objective-c | Tags: C, Objective-c
  • Recent Posts

    • A not well know and underestimated css property: box-sizing
    • jQuery Builder: Introduction
    • Installing VimRepress in MacVim (OSX Lion)
    • Easyhash: An easy interface to generate md5 and sha1 hash in hexadecimal format
    • Grails / GORM: Changing default id name and type from an entity
  • Categories

    • CSS
    • GMongo
    • GORM
    • Grails
    • Groovy
    • Java
    • Javascript
    • jQuery
    • NoSQL
    • Objective-c
    • OSX
    • Programming
    • Vim
  • Tags

    brew builder C css easyhash gmongo grails gorm groovy groovy html java javascript jquery mongodb nosql Objective-c opensource osx python vim web wordpress
  • Blogroll

    • Rodrigo Lazoti Blog
  • Links

    • Mac Developers
    • Siteapps
  • Recent Comments

    • Trying out VimRepress | Blind, Not Dumb on Installing VimRepress in MacVim (OSX Lion)
    • Paulo Poiati on Installing VimRepress in MacVim (OSX Lion)
    • Chris Patti on Installing VimRepress in MacVim (OSX Lion)
    • rohit on Groovy / GMongo tips and tricks
    • Paulo Poiati on GMongo 0.5 Released
© Paulo Poiati | Blog. Proudly Powered by WordPress | Nest Theme by YChong