Friday, June 29, 2007

Easy verification of API behavior via irb

Learning programming language is not just learning language syntax, programmers including myself spend lot of time learning various API. Irb is wonderful tool for learning Ruby API, when I do program in Ruby, I always have Irb open, and I try to run a method of API including core lib, that I am not sure how it works. Comparing to Java, it is much faster and have better productivity.

Open classes

When I want to change or add new behavior to existing class, static typed language give me only two options create new class that either extend existing class or delegate to existing class (in Java world some peoples do aspect oriented programming AOP, but it is little bit complicated and is external to the language).
Ruby give me an ability to modify existing class directly. A cross concern or aspect then can be added easily by modifying existing class.

ADDING NEW FEATURE TO EXISTING CLASS
class Object
   def blank?
      return true if nil?
      return true if respond_to?(:empty?) && empty?
      return false
   end
end
nil.blank? #=> true
''.blank?  #=>true
[].blank?  #=>true
{}.blank?  #=>true
'hello'.blank? #false
[:a].blank? #false
{:a=>1}.blank? #false
The above code define method blank? in class Object, which is root of all Ruby classes. This will result in well behaving instances of NilClass, String, Array, Hash.

DECORATION A METHOD OF EXISTING CLASS
To decorate a method of existing class is just easy as adding new one e.g.
require 'active_support'
class Hash
    alias original_symbolize_keys! symbolize_keys!

    def symbolize_keys!
        each_value do |value|
             value.symbolize_keys! if value.is_a?(Hash)
        end
        original_symbolize_keys!
    end
end
Rails ActiveSupport add method symbolize_keys!, above code decorate it to convert keys to symbol for a hash value if it is also hash.
When modifying an existing class, we shall make sure that the class is already loaded, otherwise we may get a strange behavior. This is specially important in rails, when classes are loaded dynamically using const_missing method. About how to handle this problem, there is good tip reopen with class/module eval on practical ruby blog. Other way to decorate method without using alias is available on replacing methods.

Wednesday, June 27, 2007

Using of keyword based parameter

I plan to have presentation of Ruby Language in enterprise application development for developers of the company I worked for and I am thinking about which message should I pass to them. Instead of trying to give many reasons that others already talked about huge benefit of using Ruby, I decide to give my own very personal reasons why I love Ruby based on my one and half year working with this language.
In early day, when I programed in PL/SQL, I know that PL/SQL support keyword based parameter in procedure/function but I never used this feature, simply I have not recognized the benefit of using it that time.
Ruby does not support keyword based parameter but Ruby programmers fake it easily using hash in combination with symbol. Using this style is very popular in Ruby core lib and Rails. The following example illustrates it, suppose we want to create method create_user that create database user, in traditional position based parameter, we will do like that
def create_user(username,password,ignore_error,force,verbose)
   #.. implementation detail is ignored
end
#calling it
create_user('scott','tiger',false,true,true)
on keyword based version, the method has simply one parameter params
def create_user(params)
   username = params[:username]
   password = params[:password]
   ignore_error = params[:ignore_error]
   verbose = params[:verbose]
   force= params[:force]
   #.. implementation detail is ignore
end
#calling it
create_user(:username=>'scott',:password=>'tiger',:ignore_error=>false,
  :verbose=>true, :force=>true)
The keyword based version is obviously more verbose, requires more typing, but offers several benefits.

MORE EXPRESSIVE AND LESS ERROR
The keyword based version is more expressive, just by looking at how the method is called, we know what is the intention, there is no need to look at the implementation file to figure out what it does. The position based version suffers what Joshua Bloch mentioned in his How to Design a Good API and Why it Matters "Long lists of identically typed params harmful"

GOOD DEFAULT
In the position based version, we can only assign default value for those parameters that are at the end of parameter list.
def create_user(username,password=username,ignore_error=false,force=false,verbose=false)
   #.. implementation detail is ignored
end
#calling it
create_user('scott')
This will not give a flexibility of using default value just for few last one. In the keyword based version, we can archive it easily as follow
def create_user(params)
   username = params[:username]
   password = params[:password] || username
   ignore_error = params[:ignore_error] 
   verbose = params[:verbose]
   force= params[:force]
   
   #implementation detail is ignored
   
   #note that Ruby consider nil as false in condition expression, so we should design 
   #boolean value keyword in such way that its default value is false
end

#calling it
create_user(:username=>'scott',:verbose=>true)
create_user(:username=>'scott',:force=>true)
create_user(:username=>'scott',:ignore_error=>true)
I also see people using Hash::merge to shorten assignment of default values and adding some assertion of accepted keywords e.g
#borrow from ActiveSupport
class Hash
  def assert_valid_keys(*valid_keys)
    unknown_keys = keys - [valid_keys].flatten
    raise(ArgumentError,
    "Unknown key(s): #{unknown_keys.join(", ")}\nValid key(s): #{valid_keys.join(',')}")   
      unless unknown_keys.empty?
  end    
end

class DatabaseSchemaBuilder
  
  attr_accessor :ignore_error,:verbose,:force

  def default_options
    {:ignore_error=>@ignore_error,:verbose=>@verbose,:force=>@force}
  end

  def create_user(params)
    params.assert_valid_keys(:ignore_error,:verbose,:force)
    params = default_options.merge(params)
   
    username = params[:username]
    password = params[:password] 
    ignore_error = params[:ignore_error]
    verbose = params[:verbose]
    force= params[:force]

   #implementation detail is ignored
  end
end
EASY TO CHANGE
When we need lets say adding new parameter to the method. In position based version, we end up with changing contract of the method, which may result in looking at every line of code that use this method and make change unless you put at the end of parameter list with default value.
In keyword based version, it is obvious less painful, just adding one more keyword, setting a default value, anyway change only the method itself, e.g. we want to add parameter :noop, meaning no operation, just for testing.
def default_options
   {:ignore_error=>false,:verbose=>false,:force=>false,:noop=>false}
end

def create_user(params)
   params.assert_valid_keys(:ignore_error,:verbose,:force,:noop)
   params = default_options.merge(params)
   
   username = params[:username]
   password = params[:password] || username
   ignore_error = params[:ignore_error]
   verbose = params[:verbose]
   force= params[:force]
   noop=params[:noop]

   #implementation detail is ignored
end
HIDING DESIGN DECISION
Using position based parameter with little bit long parameter list, I have to decide if put one parameter before other or not. I do not have this problem when using keyword based parameter, so it help me do program faster.

Tuesday, June 19, 2007

Ant depend task

I am writing ruby helper class that will be used in Rakefile to build complex java application. Everything seem to be quite simple, I just copied what has been done by Matt Foemmel in his JRake. The ruby helper class has a method that check if java class is upto date by comparing access time of the class file and the java source file. I believe that Ant javac task does the same.
Using the ruby helper file, my java application most of time get build correctly but sometime, few class files are not upto date. It take me a while to figure out what is going wrong.
The problem is when a java class depends on other, if other class changes then the java file shall be recompiled even though it is not modified. Looking at Ant documentation, I found that Ant solve this problem using depend task.
In order to solve this problem in ruby, I have to do the same as Ant depend task does, read our class file, extract all class references verify if these class references are changed.

Format of Date/Time when using ActiveRecord with Oracle Database

I found no place in ActiveRecord Documentation, that describes how to enter Date/Time into Oracle Database. By looking at source code of OracleAdapter in ActiveRecord, I recognized that ActiveRecord uses Oracle alter session command to specify date format
ActiveRecord::Base.connection.execute "alter session set NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'"
As implication we shall use this format (e.g '2007-06-30' and '2007-06-30 23:01:45' String are accepted) when entering data (e.g in fixture file) to Date Field.

Monday, June 18, 2007

My resume - SUMMARY OF SKILLS


Business Analysis & Leadership

  • Able to attract, retain and lead people. Led team up to 25 developers, responsible for task planning, technical direction, risk management, code inspections, quality control, performance reviews, staff development. Understood how to create working environment to keep people happy, motivated, creative and productive.
  • Solid presentation skill, proven in communication with customers, understanding problems, capturing domain knowledge and turning it into high level requirements in suitable form for development team and other stakeholders.

Domain Knowledge

  • Financial industry: retail and investment banking, automated trading systems, communication protocols including SWIFT, ISO8583 and FIX. Involved in proposal preparation, conceptual definition and prototyping automated trading system for brokerages based on Marketcetera platform.
  • Communication industry: Business processes, practices and standards in communication industry including eTom, SID, OSSJ, Mobile Network Architecture, IN, and TAP3. Hands-on experience in ERP implementation including Billing, Fulfillment, and Accounting.
  • Government sector: Hand-on experience in government sector including law enforcement, criminal justice, immigration. Good knowledge in biometrics technology (face and fingerprint) and it's application in government's projects including national ID Cards, and Immigration.

Software Development

  • More than 15 years experience in developing software products with deep knowledge of architecture / design of multi-tiered client-server systems based on middleware including Tuxedo, J2EE (WebSphere, WebLogic) and other emerging Web framework as Ruby on Rails.
  • Skillful in many programming languages including C/C++, JAVA, SQL, PL/SQL, RUBY. Passionate for the simple and easy to understand software with rich domain model. Well versed in OOP, design patterns (Design Patterns - GoF, Pattern for Enterprise Application Architecture - PEAA, Domain Driven Design).
  • Strong knowledge of algorithms and data structures and their applications in writing a high performance, time critical system for complex business domain.
  • Extensive experience with state of art software development practices such as pair programming, Test Driven Development (TDD), refactoring, continuous integration.

System Integration Using Messaging System

  • More then 7 years in design and implementation of software systems that communicate with each other using asynchronous messages. Understand message creation and processing patterns (Enterprise Integration Patterns) and their applications in real world systems.
  • Engaged as system architect in many projects that use Event-driven Architecture (EDA) and Service Oriented Architecture (SOA) integration style.

Infrastructure's Design, Implementation & Administration

  • More than 10 years experience in design, implementation and ongoing maintenance of complex IT infrastructure, that includes J2EE middleware (WebSphere AS, WebLogic), messaging system (MQ), database (Oracle), Unix servers, clustering system, IBM SAN DS series, IBM Tape libraries TS series, Tivoli Storage Manager, CISCO router, PIX firewall and VMWARE virtual technology.
  • Proven in writing script (SHELL, RUBY, PYTHON) to automate repetitive administrative activities including monitoring, deployment, configuration change, etc.

Wednesday, June 13, 2007

My resume - EMPLOYMENT HISTORY


ING Direct Spain, Jul. 2009 - Present

Infrastructure's Software Engineer

  • Administer softwware infrastructure of WebSphere Application Server, JBOSS AS for direct banking system

ING Direct Japan, Sep. 2008 - Apr. 2009

Technical Analyst WebSphere

  • Maintain middleware infrastructure of WebSphere Application Server and WebSphere MQ for core banking system
  • Plan, install, configure and troubleshoot large scale WebSphere Application Server ND and MQ in AIX environment
  • Perform application software deployment, update, performance tuning and other house keeping activities
  • Provide assistant for application development team in problem identification and solving
  • Middleware Monitoring System: directly involved in design, develop and implement monitoring system for middleware infrastructure including exception, performance, capacity monitoring
  • Application Software Deployment Automation: directly involved in design and implementation system for automatic application software update that ensure fast, reliable, error free deployment with no downtime

Centre of Software Engineering - Vietnam, Dec. 1998 - Jul. 2008

Technical Director

  • Managed software development process and quality
  • Prepared technical proposal and system architecture
  • Provided training/mentoring on software design, pattern, refactoring, testing
  • Participated in various development/implementation projects by rotating between different roles according to the need at each project phase (team leader, project manager, business analyst, software developer)
  • Border Control System: managed the project to design, develop a J2EE application for immigration department and deploy under BEA WebLogic in major international airports across the country, integrate it with existing backend system using messaging middleware and perform data migration. Responsible for all technical aspects including overall architecture, software development, performance, quality control, server installation and production support.
  • Data cleansing for law enforcement agency: led a team to perform cleansing of a massive database of hundreds of million of records. Directly involved in design and development algorithm, data structure and rule engine in C/C++.
  • Utilities Billing - Hanoi Water Work Company: Led a team that implemented a distributed billing and customer management system based on ORACLE and JAVA. In charge of overall system design (including custom developed system, IT infrastructure component selection, data migration strategy) and development of data synchronization module using JMS.
  • Telecom Billing and Order Fulfillment System: Responsible for implementation of high performance (up to 20,000 event per second), nearly real time event rating engine using C/C++, Tuxedo and database in memory technology.
  • Personnel Management Information System - Ministry of Home Affair: Managed the development and implementation the Personnel Management Information System for public sector fund by Swedish Agency for Development Cooperation. The system was developed mainly using ORACLE PL/SQL and ORACLE Database.
  • Electronic Library - Institute of Mathematics - Vietnam: Participated in concept definition, architecture and technology selection (ORACLE and PERL).

Centre of Software Engineering - Vietnam, Jul. 1997 - Nov. 1998

Software Developer, Database Administrator, Team Leader

  • Performed installation, maintenance, support ORACLE Database System
  • Designed, developed and implemented framework/library for data synchronization
  • Utilities Billing - Hochiminh Cities Water Supply Company: managed a final phase of the project to implement of billing and customer's care for Hochiminh Cities Water Supply Company using ORACLE PL/SQL and ORACLE Database. Directly involved in development of module for data synchronization between branches and head quarter
  • Document management system: Installed, maintained, provided support ORACLE Database System ,Ministry of Science and Technology .

Notia Information System - Czech Republic, Apr. 1994 - May 1997

Software developer, Team leader

  • Performed installation, maintenance, support ORACLE Database System
  • Participated in various software development projects under different roles team leader, software developer, database administrator, technical support personnel
  • Custom developed ERP - Altron Czech Republic: Led development team in the project to develop and implement of ERP for a distribution and retail company in Czech Republic using ORACLE database design and GUI development in Borland Delphi.
  • Fixed Asset Management - Eurotel Prague: Participated in design a fixed asset management software for a mobile phone company based in Prague.
  • ERP Package Software: Responsible for development and support of C++ part A/R, A/P of ERP package software, that have been deployed to hundreds of customer in Czech Republic.

Metasoft - Czech Republic, Jun. 1993 - Jan. 1994

Software Developer

  • Developed, customized software, provided technical support
  • Implemented software supporting activities of an accommodation agency

irb and TAB autocompletion

To enable autocompletion on irb, run
irb
require 'irb/completion'
Note to hit double TAB on your keyboard not single one. One of most comprehensive description can be found here

Tuesday, June 12, 2007

My resume - TRAINING AND CERTIFICATION


Oracle E*Business Suite Training (one week at IBM Singapore) - 2005

BEA Tuxedo 8 Administration Training (one week at BEA in Malaysia) - 2002

Project Management Training (3 weeks at Asia Institute of Technology (AIT) Thailand) - 2000

Software Engineering Conference (CASE University of Technology &Thomson CSF) - 1999

AIX 4.3 System Administration Certification (IBM Certified) - 1999

Oracle Certified Professional on Oracle8 DBA - 1999

RS/6000 Solution Sales Certification (IBM Certified) - 1999

Switch Off Convert line breaks

I have problem when try to post some html stuff on my blog. The posted html contains simple table. However Blogger incorrectly displays it, alignment doesn't work, a lot of strange space. I finally recognized that, this is due to enabling "Convert line breaks" feature of Blogger, that encloses line break into html break tag, I switch it off, and everything work well.

My resume - PROGRAMMING LANGUAGE AND TOOLS


Operating Systems

  • AIX 4.3/5L, HACMP 4.3, Solaris 7/8, SCO Unix, Windows NT/2000/XP, Linux (Redhat Debian, Ubuntu)

Middleware

  • Websphere ND 6, WebLogic Server 8.1, Websphere MQ 6, Tuxedo 8.0, Tomcat, Ruby on Rails

Database

  • Oracle8i/9i/10g, Oracle Real Application Cluster, MySQL, Microsoft SQL Server 6.5, Microsoft Access

Programming Languages

  • JAVA, C/C++, Ruby, Oracle PL/SQL, Visual Basic, PASCAL, PROLOG

Tools

  • IDEA IntelliJ, Microsoft Visual C++, Rational Rose, Oracle Designer/Developer, Borland Delphi, Toplink, iBATIS, Subversion,Git, Svn, Ant, Maven, Cruisecontrol , JIRA, Mingle, Microsoft Project & Office Suite

Sunday, June 10, 2007

The secret behind Rails Integration Test

Find what is behind Rails Integration Test on good blog's post named HeadlessApp
$ script/console
Loading development environment.

>> app.class
=> ActionController::Integration::Session

>> app.get "/home"
=> 302

>> app.controller.params
=> {"action"=>"home", "controller"=>"accounts"}

>> app.response.redirect_url
=> "http://www.example.com/login"

Saturday, June 9, 2007

gem's environment

When playing with gem on my Ubuntu machine, I found an useful command
huy@huy-desktop:~/.gem$ gem environment 
Rubygems Environment:
  - VERSION: 0.9.0 (0.9.0)
  - INSTALLATION DIRECTORY: /var/lib/gems/1.8
  - GEM PATH:
     - /var/lib/gems/1.8
  - REMOTE SOURCES:
     - http://gems.rubyforge.org
that shows default gem's environment. By setting the GEM_PATH environment variable to one desire directory, we can share single gem repository across many ruby installations (e.g C ruby and JRuby). The full descriptive information of all gem environments variables can be found in Gem Command References

Thursday, June 7, 2007

Naming Exception Corba Comm Failure

Java RMI, Corba, J2EE are sometime still nightmare for developers including these with more than 2 years working experiences with these technologies like myself. I have encountered a "Naming ExceptionCorba Comm Failure" when remote client try to create InitialContext to my Weblogic server. I did check all small details, everything seem to be OK. My Weblogic server is configured to listen on single host interface named "app-svr" that represents a valid IP address 192.168.2.79. My remote client is configured connect to exact same address 192.168.2.79. However it does not work. At some moment, I changed address that Weblogic server is listening from "app-svr" directly to IP address 192.168.2.79, and suddenly it starts work. It also works when I change back listening IP address of Weblogic server to "app-svr" and at the same time put "app-svr 192.168.2.79" in to hosts file of my remote client. Such behavior of the JVM RMI implementation can cause big trouble most JAVA developers including myself.

Friday, June 1, 2007

Cruisecontrol.rb is too slow

I encountered a problem with Cruisecontrol.rb, the method link_to_code(log) is too slow to process a certain output log, sometime it takes 10 seconds making Cruisecontrol not workable. So for the time being, as workaround, I just comment out this code .
#file: app/helpers/builds_helper.rb
  def link_to_code(log)
    log
=begin    
    @work_path ||= File.expand_path(@project.path + '/work')

    log.gsub(/((\#\{RAILS_ROOT\}\/)?([\w\.-]*\/[ \w\/\.-]+)\:(\d+))/) do
      path, line = File.expand_path($3, @work_path), $4
      
      if path.index(@work_path) == 0
        path = path[@work_path.size..-1]
        link_to ".#{path}:#{line}", "/projects/code/#{@project.name}#{path}?line=#{line}##{line}"
      else
        $1
      end
    end
=end
  end