With Rails, we can build and launch a prototype application in an extremely short time. On average, we can have something simple in front of the client in less than a couple of days, which is much faster than our previous projects where we used ASP or PHP. And that project isn't usually a throwaway project; we can tweak it and move forward, from prototype to production.
Wednesday, February 17, 2010
Why Rails?
Tuesday, October 14, 2008
I join alonetone.com open source project
Sudara created the site in Jan 2008 as a home for musicians where they can upload their music and freely share it on the Internet. Few month later, alonetone had evolved as a community for musicians who love to write music, talk about music and want to distribute their work freely.
More facts about alonetone:
- 2922 original & legally uploaded mp3s
- around 300 musicians
- 7.5 days of continuous free music
- 11.7 gigabytes of mp3
- 500 avg listens per day
I will do more work on back-end so Sudara have time to improve design, refine the direction of alonetone and to create great songs like this:
Back to the cold, by Sudara
Sudara, can you create a song for our programmers like this song? :D
Wednesday, September 24, 2008
Ruby's Best Feature?
.
.
.
.
.
.
He concluded that:
In my experience, this is the single most important feature of the Ruby language---capturing the domain in a language the entire team can speak. If you believe clear communications is an essential quality of highly effective teams, this feature is something that you should strive to exploit in your own Ruby projects.Do you want to know what do I feel after reading this post?
I want to read Martin Fowler's Domain Specific Languages Book immediately and write DSL's patterns described in the book in Ruby.
Monday, September 22, 2008
Dynamic programming advantage
Original version:
FIELDS = [ 'first', 'last', 'band' ]
DATA = [['Kurt', 'Cobain', 'Nirvana'],
['Jimi', 'Page', 'Led Zeppelin'],
['Noel', 'Gallagher', 'Oasis'],
['Thom', 'Yorke', 'Radiohead']]
def combine_fields_and_data(fields, data)
new_data = []
data.each do |row|
row_hash = {}
row.each_with_index do |column, i|
row_hash[fields[i].to_sym] = column
end
new_data.push(row_hash)
end
return new_data
end

And Adam's refactoring
def combine_fields_and_data(fields, data)
data.map { |row| Hash[*fields.zip(row).flatten] }
end
Adam code utilize Ruby built-in Array and Hash utilities that make his code extremely short.
Read more about Array utilities here.
Saturday, September 20, 2008
Ruby x.kind_of?
module M; end
class A; end
class B < A
include M
end
b = B.new
b.kind_of? A # => true
b.kind_of? B # => true
b.kind_of? M # => true
b.class == A # => true
b.class == B # => false
b.class == M # => false
A === b # => true
B === b # => true
M === b # => true
Reference:
http://refactormycode.com/codes/487-x-kind_of-myclass-or-x-class-myclass
Thursday, September 18, 2008
Phusion daemon_controller gem
Extracted from Phusion blog:
daemon_controller is not a replacement for Monit or God, or for tools like launchd, daemons tools, inittab, etc. Rather, it is a solution to the following problem:
Hongli: hey Ninh, do a ‘git pull’, I just implemented awesome searching features in our application!
Ninh: cool. *pulls from repository*
Ninh: hey Hongli, it doesn’t work.
Hongli: what do you mean, it doesn’t work?
Ninh: it says “connection refused”, or something
Hongli: oh I forgot to mention it, you have to run the Sphinx search daemon before it works. type “rake sphinx:daemon:start” to do that
Ninh: great. but now I get a different error. something about BackgrounDRb.
Hongli: oops, I forgot to mention this too. you need to start the BackgrounDRb server with “rake backgroundrb:start_server”
Ninh: okay, so every time I want to use this app, I have to type “rake sphinx:daemon:start”, “rake backgroundrb:start_server” and “./script/server”?
Hongli: yep
Imagine the above conversation becoming just:
Hongli: hey Ninh, do a ‘git pull’, I just implemented awesome searching features in our application!
Ninh: cool. *pulls from repository*
Ninh: awesome, it works!
Wednesday, September 17, 2008
Active Record new_record? method
model_instant.new_record? # => true: just created
model_instant.new_record? # => false: created sometime ago
I use this method quite often but can't remember the name so I write a post about it with the hope that the method name will be burned in my brain :D
Monday, September 15, 2008
Active Record tips and tricks
http://m.onkey.org/2008/9/15/active-record-tips-and-tricks
One more thought about the use of concerned_with. I prefer to use require_dependency directly. So I don't need to add and load concerns.rb for every new Rails project and get more flexible to organize related files.
For example:
class Listing < ActiveRecord::Base
require_dependency "listing/property_related"
require_dependency "listing/price_related"
require_dependency "listing/contact_related"
require_dependency "listing/address_related"
require_dependency "full_text_search/listing_config"
....
end
When you want to separate full text search config code to another file, remember to inherit the class from ActiveRecord::Base in order to let enable ThinkingSphinx plugin or UltraSphinx plugin methods.
For example:
# full_text_search/listing_config.rb
class Listing < ActiveRecord::Base
define_index do # ThinkingSphinx plugin
...
end
end
Saturday, September 13, 2008
Ruby Paramater's Default Value
def foobar(a, b='b', c)
...
end
foobar(1, 2, 3)
# a => 1
# b => 2
# c => 3
foobar(1, 2)
# a => 1
# b => 'b'
# c => 2
define bar(a, b='b', c='c', d)
bar(1, 2, 3)
# a => 1
# b => 2
# c => 'c'
# d => 3
---
Prefer using default value for parameter from right to left direction
References:
Friday, September 12, 2008
Ruby Equality
a = "a string"
a === "a string" # => true
a === String # => false
String === "xyz" # => true
"xyz".kind_of? String # => true
(1..5) === 3 # => true
(1..5).include? 3 # => true
/\d/ === "123" # => true
# === is used in "case" statement
b = a
a.equal? b # Returns true if the object_id’s are equal.
1 == 1.0 # => true (do type conversion)
1.==(1.0) # underlying of ==
1.eql? 1.0 # => false (don't do type conversion)
References:
Saturday, August 2, 2008
Simplest Hunspell Ruby binding
There are several Hunspell bindings for Ruby:
- http://rubyforge.org/projects/hunspell/
- http://rubyforge.org/projects/ruby-hunspell/
Initially, I use Hunspell gem but after digging in to source code, I found a memory lick problem: the author forgot to free suggestion list after call Hunspell_suggest(pHunspell, &slst, str) function.
I decided to write my own binding with less code using RubyInline. Here is the result:
A simplest Hunspell Ruby Binding within 60 line of codes :)
Check it out at:
http://github.com/tiendung/rhunspell/
Update: Now the binding become a Rubygem, you can install it easily with following command:
"sudo gem install rhunspell"
Tuesday, July 29, 2008
Extend Thinking Sphinx to support SPH_SORT_EXPR mode
Here is my code that extend ThinkingSphinx::Search class to support SPH_SORT_EXPR mode via :sort_expr option.
Feel free to tweak the code at RefactorMyCode.com
module ThinkingSphinx
class Search
class << self
alias_method :original_set_sort_options!, :set_sort_options!
def set_sort_options!(client, options)
expr = options[:sort_expr]
if expr.nil?
original_set_sort_options!(client, options)
else
client.sort_mode = :expr
client.sort_by = expr
end
end
end # class << self
end # Search
end # ThinkingSphinx

Usage: Model.search("search string", :sort_expr => "sort expression")
Find out more about my Thinking Sphinx's bug fixes and extenstions here:
http://github.com/tiendung/thinking-sphinx/wikis
Tuesday, July 22, 2008
Image Processing & Computer Vision for Ruby
Camellia 2.7.0 gem installation fail on Leopard. Then I compiled Camellia 2.7.0 from source code and install camellia-2.5.10 gem follow the guide here. Luckily, they can work together.
HornetsEyes require a lot of libs in order to build (Qt4, Boost, ImageMagick...). I failed to install Boost then I stopped.
When compared example code, I found Camellia is more friendly and easy to use. Let see
Camellia examples and one HornetsEyes example. HornetsEyes follows Class Oriented style (often found in C++/Java) in Ruby cloth.
I voted for Camellia: Smaller and Easier to use
Ruby in the dark ages
"Brian has been programming with Ruby since BR (before-Rails), which means practically since the dark ages. He has worked with several companies doing web development with Rails. In December 2006 he began contributing to Rubinius, launching the effort to write executable specs for Ruby. He is now employed by Engine Yard to work full-time on Rubinius."
Have you practice Ruby in since the dark ages?
Rubinius is an awesome and unique project. I will create a posting about it :)