Saturday, November 24, 2007

Saturday, October 13, 2007

Useful unix tricks

link touseful unix tricks from Paul Gross
part 1
part 2

Tuesday, October 2, 2007

Sea Fish

This picture named 'Sea Fish' is from Le Ngoc Mai, my 8 year old daughter.

Tuesday, September 11, 2007

Friday, September 7, 2007

Calling Java from JRuby

Current JRuby is lack of detail documentation with regard to Java integration, so in certain cases it take me and my colleague a while to figure out how to do.
String to/from Java byte's array
In our recent application, we need to pass image from Ruby to image processing method written in Java. The Java method accept byte array and has result as byte array also. So we need convert Ruby String to Java byte[] and back.
The require 'java' add two methods to Ruby String class
String#to_java_bytes # instance method return Java byte[] 
String::from_java_bytes # class method return Ruby string from Java byte[]
The below code snippet demonstrate it.
require 'java'
include_class 'net.csetech.sq.image.ImageHelper'

File.open('duongpl.jpg') do |f|
  f.binmode
  @original = f.read
end

@reduced_j = ImageHelper.reduce_to_fix_size(@original.to_java_bytes,15000)
@reduced_r = String.from_java_bytes(@reduced_j)

File.open('duongpl-15k.jpg','w') do |f|
  f.binmode
  f.write(@reduced_r)
end
Ruby Array to Java Array
Other example, that we may need is to convert Ruby Array to Java Array. The require 'java' add method Array::to_java(Symbol), that convert Ruby Array to Java Array, where Symbol represent Java Class of the Array's elements. If it is omitted, the result is Java Object[].
['a','b'].to_array(:String) # return Java String[]
['a','b'].to_array # return java Object[]
More about method to_array is on JRuby Cookbook

Saturday, September 1, 2007

API design

Link to API: Design Matters
Link to How to Design a Good API & Why it Matters

ActiveRecord-JDBC 0.5 can not insert object with pre-assigned Id into Oracle Database

If you encountered problem when try to insert object with pre-assigned Id into Oracle Database in JRuby 1.0.1 with ActiveRecord-JDBC 0.5, here is quick fix
module ::JdbcSpec
  module Oracle
     def insert(sql, name = nil, pk = nil, id_value =nil, sequence_name = nil) #:nodoc:
      if pk.nil? || id_value
        execute sql, name
      else # Assume the sql contains a bind-variable for the id
        id_value = select_one(
        "select #{sequence_name}.nextval id from dual")['id'].to_i 
        log(sql, name) {
          @connection.execute_id_insert(sql,id_value)
        }
      end
      id_value
    end
  end
end
The problem is on compatibility of Oracle JDBC driver and execute_insert method of java class JdbcAdapterInternalService. The fix simply remove the usage of execute_insert method. Verification code is below
require 'rubygems'
gem 'ActiveRecord-JDBC','0.5'
require 'jdbc_adapter'
require 'active_record'

ActiveRecord::Base.establish_connection(
 :adapter  => 'jdbc',
 :driver   => 'oracle.jdbc.driver.OracleDriver', 
 :url      => 'jdbc:oracle:thin:@localhost:1521:DEV',
 :username => "scott",
 :password => "tiger",
)

class Emp < ActiveRecord::Base
  set_table_name 'emp'
  set_primary_key 'empno'
end

emp = Emp.new
emp.id = 9999
emp.save

Sunday, August 19, 2007

Ruby require idiom

Ruby Kernel#require(filename) read and execute the specified file only once regardless how many time we call it as opposite to Kernel#load(filename) which reload the file each time. With application having many files, each depend on others without this behavior of Kernel#require(filename), a single file will be read executed multi time, which may not desired from functional and performance's perspective. The Kernel#require(filename) however has an issue, after loading it puts path of a file required in global array $" and does not know if we refer to the same file using different path. e.g.
#file : lib/foo.rb
puts "loading #{__FILE__}"

#file : lib/bar.rb
require File.dirname(__FILE__) + '/foo'
puts "loading #{__FILE__}"

#file : app/runme.rb

require File.dirname(__FILE__) +'/../lib/foo'
require File.dirname(__FILE__) +'/../lib/bar'
puts $"
Then run
ruby app/runme.rb

loading ./app/../lib/foo.rb
loading ./app/../lib/foo.rb
loading ./app/../lib/bar.rb
["app/../lib/foo.rb", "./app/../lib/foo.rb", "app/../lib/bar.rb"]
There are basically few well known techniques to deal with this problem
1. Using absolute path
2. Modifying $LOAD_PATH
3. Using defined?

USING ABSOLUTE PATH
In this variant we always call Kernel#require with a absolute path, the File::expand_path will be used to remove '..' symbol representing parent directory e.g
#file : lib/bar.rb
require File.expand_path(File.dirname(__FILE__)) + '/foo'
puts "loading #{__FILE__}"

#file : app/runme.rb
require File.expand_path(File.dirname(__FILE__)+'/../lib')+'/foo'
require File.expand_path(File.dirname(__FILE__)+'/../lib')+'/bar'
puts $"
run
ruby app/runme.rb

loading D:/huy/rubyapp/require_1/lib/foo.rb
loading D:/huy/rubyapp/require_1/lib/bar.rb
["D:/huy/rubyapp/require_1/lib/foo.rb", "D:/huy/rubyapp/require_1/lib/bar.rb"]
This method is described in post ruby require idiom

MODIFYING $LOAD_PATH
The second quite popular technique is to modify $LOAD_PATH directly e.g.
#file : lib/bar.rb

libpath=File.expand_path(File.dirname(__FILE__)+'/lib')
$LOAD_PATH.unshift(libpath) unless $LOAD_PATH.first==libpath

require 'foo'
puts "loading #{__FILE__}"

#file : app/runme.rb

libpath=File.expand_path(File.dirname(__FILE__)+'/lib')
$LOAD_PATH.unshift(libpath) unless $LOAD_PATH.first==libpath

require 'foo'
require 'bar'
puts $"
In the previous mentioned techniques, the File#expand_path method is used to get absolute path of either file or directory, the same file or directory is kept only once in a relevant global variable.

USING defined?
This technique is very old and frequently used by C programmers to guard header file to include multiple e.g.
#file foo.h

#ifdef __FOO_H

#define __FOO_H

...

#endif
In Ruby, I have seen this technique being applied using Kernel#defined? e.g.

#file : lib/foo.rb
unless defined?(FooDefined)
   FooDefined=true
   puts "loading #{__FILE__}"
end

#file : lib/bar.rb
unless defined?(BarDefined)
  BarDefined=true
  require File.dirname(__FILE__) + '/foo'
  puts "loading #{__FILE__}"
end

#file : app/runme.rb

require File.dirname(__FILE__)+'/../lib/foo'
require File.dirname(__FILE__)+'/../lib/bar'
puts $"
UPDATE on 26-12-2007
The new Kernel#require in Ruby 1.9 store full path in $" make this article obsolete.

Saturday, July 28, 2007

Turn off color in output of ls command

Output of ls command in color mode sometime causes a problem to my eyes. Turn it off is simple, just put
unalias ls
in .bash_profile or .bashrc (in case of Ubuntu Feisty)