acts_as_dictionary Rails plugin digg delicious su

Posted by tiendung
on Friday, September 05
A Rails plug-in created by Jason to treat any ActiveRecord's string field as a dictionary to do word suggesting & spelling checking. I helped to replace buggy hunspell gem with our own Ruby Hunspell binding.

As far as I know, Hunspell is the best open source spelling checking library. It is used by Firefox 3, Google Chrome, and Open Office. I also found Hunspell is easier to use than Aspell.

Get the plug-in at http://github.com/tiendung/acts_as_dictionary/tree/master

ActsAsDictionary
================

ActsAsDictionary creates Hunspell (http://hunspell.sourceforge.net/) dictionaries using data from ActiveRecord models and provides class methods to access these dictionaries.

Pre-requisites
==============

This plugin requires the Hunspell library and RubyInline gem.

To install Hunspell:

curl -O http://nchc.dl.sourceforge.net/sourceforge/hunspell/hunspell-1.2.7.tar.gz
tar -zxvf hunspell-1.2.7.tar.gz
cd hunspell-1.2.7
./configure
make
sudo make install

To install RubyInline:

gem install RubyInline

Setup
=====

Within a model, define the column you want to work with:

class Klass < ActiveRecord::Base
acts_as_dictionary :checks => :name
end

Or, if you want to create dictionaries using two or more columns

class Klass < ActiveRecord::Base
acts_as_dictionary :checks => [:name, :type]
end

Once done, you can proceed to generate basic Hunspell dictionary files with:

rake dict:generate

In the above example, the following files will be generated:

#{Rails.root}/dict/klass_names.aff
#{Rails.root}/dict/klass_names.dic
#{Rails.root}/dict/klass_types.aff
#{Rails.root}/dict/klass_types.dic

Each pair of these files (*.aff and *.dic) are Hunspell dictionary definition files which you can further configure if needed (see http://sourceforge.net/docman/display_doc.php?docid=29374&group_id=143754).

Note that if manually configure the files, running the dict:generate Rake task again will override your manual configurations.

Usage
=====

With this plugin, the following dynamic class methods are available (replace * with a column name you have specified to check):

>> Klass.find_by_*_with_spell_check("Naem")
=> #

>> Klass.suggest_*("Naem")
=> ["Name", "Name2"]

>> Klass.check_*("Name")
=> true


Tien Dung
http://free-and-happy.blogspot.com/

JavaScript open my eyes (1) digg delicious su

Posted by tiendung
on Wednesday, October 10

Don’t be fool by the title, it’s used to attract readers like you. This series is about programming in general. But wait, I’ll talk about JavaScript later because it’s true that JavaScript is cool and it has changed my programming point of view.

Before know JavaScript, I lived in the world of produce and object-oriented language like Pascal, C/C++ and never know what programming is. In high school, I was taught algorithms before programming languages, just used languages as tools to implement algorithms. Fist and second years in university, I was taught a lot of math before knowing that math is the most important foundation of programming. I wondered why I had to learn math, I were there to be a developer (and I forgot math very soon). Two years later, they taught me about software engineering, database, AI … without showing me how programs actually implemented and run in a computer. As time go by, I write more and more programs and still don’t know about programming. May be this the reason why Vietnam do not have talent programmers. Singapore is better. I found some interesting programming courses at NUS like

CS1101S: Programming Methodology (with Scheme)

CS2104: Programming Language Concepts

CS3212: Programming Languages

CS4212: Compiler Design

But most of other courses related to Java and some courses force student using Java (or not encourage using other languages) to do assignments. For most students in NUS, Java is their language of choice. May be I’m lucky that I know only C and little C++ when I came to NUS and I hated Java at the first sight because it dismisses the main() function and force me to write a class, then create an object just to write a pure object-oriented “hello world” program (I used Java once to do assignments).

Then I tried some dynamic programming languages: Python, Ruby (on Rails) and JavaScript. I didn’t plan to learn JavaScript in order to create web apps because I thought I can do sexy Ajax things via RJS in Rails. But everything is not as expected. In my first project, I have to generate DOM elements from data in JSON format and RJS didn’t help much. I had to use JavaScript and started to learn the language. Ok, it’s just another languages, just learn the syntax and done. My first book is Pro JavaScript by John Resig (the creator of jQuery). He taught me how different JavaScript is from traditional object-oriented programming languages and the private and privileged techniques of Crockford to make object-oriented JavaScript more powerful. These techniques looked very strange, I never saw them before. I stopped reading and try to implement it in my first project, I also used jQuery to handle Ajax calls, DOM … (John mentioned jQuery in his book, of course). Then Crockford JavaScript videos keep my eyes opening (wider and wider) ...

Tien Dung

http://free-and-happy.blogspot.com

When you hit a block... digg delicious su

Posted by hongkiat
on Tuesday, September 11
imac transparent

Go redo creative you seen elsewhere.

Finally Launch! digg delicious su

Posted by chardy
on Friday, September 07

Convention over configuration - the smarter choice digg delicious su

Posted by daniel
on Friday, August 31

I was debugging a Java legacy system and found out that the error was due to configuration. Yeah.. I forgot to change the configuration that maps to the database and I cost me 1 day to debug!. I guess I’m too used to rails way of doing things now. Convention over configuration, definitely the smarter choice!

if you're feeling hungry in the office digg delicious su

Posted by jeff
on Wednesday, August 29

just pick up some crackers from out the box just after main door, leave on serviette on hot Macbook (near-left corner is recom ;)), leave to simmer… eat after 5.minutes!!!

a cool new way to use your new Macbook… ;)

I'm not a bird, so I don't twitter digg delicious su

Posted by jeff
on Wednesday, August 22

more (techie humour) at rubbedcode.com...

on salary management digg delicious su

Posted by jeff
on Monday, August 20

"You're the highest paid, but..."

Interesting cycle, isn't it? ;P

Edit: Oh, and btw, this has nothing to do with Spiragram, ok? ;P I just thought to inject some humour into what is ordinarily a rather "dry" and "serious" blog...

To err is human digg delicious su

Posted by tiendung
on Friday, August 17

People always make mistakes. We are all wrong 99% of the time. The winner is the one who realize self-mistakes sooner and fix them faster than others.

So don’t be too proud of yourself, be realistic:

  • admit that you can make mistakes
  • don’t afraid of making mistakes
  • welcome mistakes come soon (through experiments)
  • don’t blame others’ mistakes
  • fix them as soon as possible

Tien Dung.

http://free-and-happy.blogspot.com/

MySQL heads-up!!!: Enterprise source tarballs will no longer be freely available digg delicious su

Posted by jeff
on Monday, August 13

It’s been quite confusing reading all the various reports about the issue – but suffice to say that the Enterprise sources will still be available via BitKeeper! I’m just not too sure how this will work out for the Community Version, though! Seems like (and Colin Charles reads this the same way as me) the Community Version is going to take a step back where bug fixes are concerned, since according to Kaj Arnö (MySQL VP Community Relations), bug fixes are only going to be added to the Community Version of MySQL when the next version gets released (which should be like every 3 months)...

So if you’re using Community, no emergency hot fixes, and no timely bug fixes for you!!! The sources for Enterprise, though, will still continue to be available via BitKeeper (watch the linux.com video interview (although there was a point in time during the interview [05:59ff.], where it seemed like this might not be the case)). This will probably have to be the way to go if you want access to all those hot fixes and bug fixes… That is, until (and if) MySQL AB decides to close off access to that too…

But fear not?!! The GPL does allow for customers to redistribute the source code, and as luck would have it, there seem to be 2 willing providers of that service already (mirror.provenscaling.com, and dorsalsource.org)...

One persistent point raised in the Linux.com video interview bugs me though – is the Community Version (as Zack Urlocker, MySQL VP Marketing, says) not going to be any much different in terms of features from the Enterprise version? My my, but how MySQL AB’s official literature says otherwise... Or does the “experimental features” bit refer only to alpha, beta versions of MySQL Community – and not the GA versions???? Are we looking at a marketing message based off of mysql.com that is designed to push people off into buying into the Enterprise edge?

A Side Note:
Reading Mike Kruckenberg (“well-respected community member”) ’s perspectives on the issue was interesting – although I cringe at the fact that he does not yet get “it” (the stand of the FSF with regards to the meaning of the word “free”). Yes, you can sell free software, dude – the “free” in “free software” is about the liberty, not about the price!!!! The FSF has never been about the free price of the software – it has only really been about the freedom of the software…

To quote from http://www.gnu.org/philosophy/free-sw.html (alternatively) -
Freedom is the issue, the whole issue, and the only issue.

(And Back from the Side Note):
So, what will this mean for Spiragram and its projects/clients? Nothing much really, I guess, above what other users of MySQL will be facing as well with this announcement. The only thing that has changed is, since we now have one PostgreSQL pusher on board (in the form of me), we may yet see more PostgreSQL deployments yet! We shall see… :)

The words are big enough but ... digg delicious su

Posted by shoop
on Monday, August 13

My astigmatism is fine, but there is just no way in hell I can remember the URL, Bausch & Lomb.

fun with JavaScript Chainability digg delicious su

Posted by tiendung
on Friday, August 10

want to show all string properties of an object in JavaScript?


function showAllStringPropertiesOf( object ) {
  for (var property in object) {
    if (typeof object[property] == "string") {
       console.log(property, ":", object[property]);
    }
  }
}

var object1 = {
      name: "Spiragram",
      address: "87 Beach Road",
      vision: "Spiragram will liberate, lead and inspire programmers to realize their full potential ..." 
    },
    object2 = {
      name: "Tien Dung",
      age: 26,
      saySomething: function () { alert("hello from " + this.name); }
     };

showAllStringPropertiesOf(object1);
showAllStringPropertiesOf(object2);

is it nice if we do not have to duplicate the function name? We can write:


forEach([object1, object2], showAllStringPropertiesOf );
 

where forEach is a funtion:


function forEach( a, fn ) {
  var i, l = a.length;
  for (var i = 0; i < l; i++)
    fn(a[i]);
};

is there a better way (because we have only two objects)? The answer is making the function chainable by adding a return itself command to the end of the function.


function showAllStringPropertiesOf ( ... ) {
  ...
  ...
  return arguments.callee;
}

now we can call:

showAllStringPropertiesOf( object1 )( object2 )

still want to make it more readable? Let make more fun with “and” keyword.

showAllStringPropertiesOf( object1 ).and ( object2 );

by adding some code below

function showAllStringPropertiesOf ( ... ) {
  ...
  ...
  return addAndMagicTo(arguments.callee);
}

function addAndMagicTo( fn ) {
  fn.and = fn;
  return fn;
}

Tien Dung

http://free-and-happy.blogspot.com/

Using raspell with your own custom dictionary digg delicious su

Posted by daniel
on Wednesday, August 08

A good search engine should be smart enough to detect spelling errors and provide suggestions. For example if you misspelled a word when using Google search, it will ask Do you mean:.... It will be cool to have such feature for our own search engine. So I started to explore possible solutions what works will rails and came upon this blog post by Evan Weaver. He has implemented a ruby gem raspell to interface with Aspell. That sounds like a good solution and I decided to check it out.

1. Installing Aspell

As mentioned in Evan’s post to install Aspell just type the following command from terminal:


sudo port install aspell aspell-dict-en

This will install both the aspell library and aspell English dictionary.

2. Install raspell

This is straight forward.


sudo gem install raspell -- --with-opt-dir=/opt/local

3. Setting up your own dictionary

For my case I needed aspell to check against my own custom dictionary. I create a text file containing the list of words with each word on a new line save it as wordlist. e.g.


John
Simon
Mae
Tim
Louis

Then run it with the following command.


aspell --lang=en create master ./en_SG-name.rws < wordlist

Note that for the language option I’m using ‘en’ which is the standard code for English. If you are generating a word list in other languages you will have to change lang option accordingly. The name of the output file is important because Aspell only pick up dictionary file in a certain naming format. The dictionary file should start with the language code then follow by a country code which is optional. For my case I have chosen SG because I do not want to override the default en dictionaries from Aspell. The ‘name’ after the ’-’ is actually the jargon. So if you are generating a word list of street names in US you might want to name you dictionary as en_US-street.rws. Once you have generated the dictionary you will have to place it in Aspell default dictionary directory.


sudo mv en_SG-name.rws /opt/local/share/aspell/

Because Aspell will only look for dictionaries with .multi file extension in the default directory. I’ll need to create a en_SG-name.multi file for my new dictionary

sudo vi /opt/local/share/aspell/en_SG-name.multi

and add the following line.


add en_SG-name.rws

You can add multiple dictionary to this file. If you needed the common English dictionary together with your custom one. Just add it accordingly.

4. Using your own dictionary in ruby.

Finally to use the dictionary I have just created.


require 'rubygems'
require 'raspell'

sp = Aspell.new('en_SG', 'name')
sp.suggest('Mea')
=> ["Mae"]

The first parameter is the language part of the file name and the second is the jargon. So if you have named your dictionary as en_US-street.multi then you will need to initialize it with


sp = Aspell.new('en_US', 'street')

My first task at Spiragram digg delicious su

Posted by tiendung
on Tuesday, August 07
T1) Setting a server
T2) Implement a simple feature
T3) Adding data to a website
T4) Reading xxx pages of the Top Secret Methodology Book

Which Tx == true ?
Anybody can guest ?
.
.
.
.
.
The correct answer is:

(T1 || T2 || T3 || T4 == false)

Let me tell you my first task is get used to a brand new MacBook :)))

Actually, my first task (I assign to myself) is to understand and catch up with other team members as soon as possible. Working at Spiragram is like a dream, everyday working with people who share the same vision, read the same books and ... at the same toilet too :) I will try my best to keep this dream last forever.

Tien Dung

It's about the Ride, for Christ's sake. digg delicious su

Posted by shoop
on Tuesday, August 07

From www.shooperman.com:

It's always the same story with you, huh, pal?
You did this one movie a hundred years ago.
From then on, you thought your were better than everybody else.
Why don't you let go?
Move on with your life.
It's not about what happened in the past...
or what you think might happen in the future.
It's about the ride, for Christ's sake.
There's no point going through all this crap...
if you're not gonna enjoy the ride.
And you know what?
When you least expect it, something great might come along
something even better than you ever planned.