Archive

Archive for January, 2012

Javascript OOP design pattern

January 29, 2012 Leave a comment

I’ve been using the following programming pattern whenever I need to write some client-side javascript:

( function() {
    if(!window.Foo) window.Foo={};
    function some_priv_func() {
        // define a private function (not accessible from
        // outside of the enclosure)
        alert('this is a private function');
    }
    function some_pub_func() {
        // calling some_priv_func()
        some_private_func();
    }
    window.Foo.some_pub_func=some_pub_func;
} )();

In the above example I create a Foo object and expose one function some_pub_func, which can be invoked by calling Foo.some_pub_func(). Enclosure is used to avoid name-space conflicts. It’s worth noting that the some_priv_func can not be accessed from outside of the enclosure.

I recently discovered a better way to program the OOP way in Jtavascript through Hands-on Node.js (page 100) and I would like to share with you this technique. Let’s look at code:

( function() {
    if(!window.Foo2) {
        window.Foo2=function(options) {
            // to avoid getting confused when using
            // 'this' in member functions
            var self=this;
            self.options=options;
            function some_priv_func() {
                // define a private function (not accessible from
                // outside of the enclosure)
                alert('this is a private function');
            }
            self.some_pub_func=function() {
                // calling some_priv_func()
                some_priv_func();
            }
        };
        window.Foo2.create=function(options) {
            return new Foo2(options);
        }
    }
} )();

Foo2.create() is made so one can initialise a Foo2 instance without using the “new” keyword. You can use Foo2 in ways like the following:

var f2=new Foo2( { name: 'the new guy' } ); // as if Foo2.create doesn't exist

or

var f2=Foo2.create( { name: 'the new guy' } );

For demonstration purpose I also expose the member options to the public allowing it be accessed and changed. A better way to handle this is to use the jQuery extend function. (Assuming jQuery is being used)

            ...
            var self=this;
            var defaults={
                name: 'no name'
            };
            // merge settings in options to defaults
            $.extend(defaults, options);
            function some_priv_func() {
            ...

So if one initialises Foo2 without any options ( var f2=Foo2.create() ), defaults will have its default value {name: ‘no name’}. Or it can be overwritten by providing a parameter.
The benefit of this is the exposing of member options (using defaults instead, which is not accessible outside of Foo2) is avoided.

Advertisements
Categories: javascript, Programming

Print color in shell terminal

January 25, 2012 Leave a comment

Sometimes you might want to print something with color in a text terminal (by color I mean something other than the default text color). Put the following shell function to your ~/.bash_profile and you are go to good.

cecho() {
    case $2 in
        red) code=31;;
        blue) code=34;;
        green) code=32;;
        cyan) code=36;;
        purple) code=35;;
        brown) code=33;;
        white) code=37;;
        *) code=30;;
    esac
    printf "\e[01;${code}m$1\e[0m\n"
}

Some examples:

cecho hello cyan
cecho "something needs your attention" brown
cecho "there's something terribly wrong, have to abort now" red
cecho "this looks so pale" white
cecho "will purple work too?" purple
cecho goodbye blue

The above commands should output something like this ($TERM setting xterm-256color, tested on both OS X 10.7.2 and Ubuntu 11.10 64bit Server):

Categories: Bash, Programming

Open a new tab (or window) in Mac OSX Terminal and run command

January 25, 2012 1 comment

[ UPDATE ]
After implementing the ruby code by user tig I was like, did I just make things more complicated than they should be? I was surprised that I didn’t first think about using the following applescript instead.

put the following codes in ~/.bash_profile

comm_tw() {
        [ $# -lt 2 ] && return
        osascript -e "
                tell application \"System Events\" to tell process \"Terminal\" to keystroke \"$1\" using command down
                tell application \"Terminal\" to do script \"$2\" in selected tab of the front window
        " > /dev/null 2>&1
}
newt() {
	comm_tw t "$1"
}
neww() {
	comm_tw n "$1"
}

All I need to do then is to run either newt (to open a new tab or neww (to open a new window) and run command(s) in it. For example:

newt "ls -l ~; uptime"
neww "date; who am i"

It’s worth noting that commands separated by semi-colon are allowed.

[ Initial Edit ]
I was looking for a solution to open a new tab (or window) and run a command (ssh for example) as sometimes I need to ssh to a number of hosts at once. I found the answer here. It’s almost what I needed for the tab part. I decided to change the ruby code (by sueruser.com user tig) a bit so I can use an option [ which is -w ] to run command in a new window. I am gonna post the code below. You can also fork me on github.

#!/usr/bin/env ruby
# A ruby script to open a new tab (or a new window) and run command in it on Mac OS X
# Modified based on the answer from tig regarding question posted at
# http://superuser.com/questions/174576/opening-a-new-terminal-from-the-command-line-and-running-a-command-on-mac-os-x
# Expands its feature a bit by allowing -w option top run command in a new window
# Usage Example:
#   ./dt ls -l
#   ./dt -w top
#
# Tested with Ruby 1.8.7

require 'rubygems'
require 'shellwords'
require 'appscript'

class Terminal
  include Appscript
  attr_reader :terminal, :current_window
  def initialize
    @terminal = app('Terminal')
    @current_window = terminal.windows.first
    yield self
  end

  def tab(dir, command = nil, mode = 't')
    app('System Events').application_processes['Terminal.app'].keystroke(mode, :using => :command_down)
    cd_and_run dir, command
  end

  def cd_and_run(dir, command = nil)
    run "clear; cd #{dir.shellescape}"
    run command
  end

  def run(command)
    command = command.shelljoin if command.is_a?(Array)
    if command && !command.empty?
      terminal.do_script(command, :in => current_window.tabs.last)
    end
  end
end

Terminal.new do |t|
  if ARGV.length>=1 && ARGV.first == '-w'
    t.tab(Dir.pwd, ARGV[1, ARGV.length], 'n')
  else
    t.tab(Dir.pwd, ARGV)
  end
end

As a side note, tmux can also be used for this kind of tasks with better scripting support. The only problem I might run into is hot key conflicts between local and remote hosts as most of the hosts I need to access are using tmux.

Categories: mac osx, ruby, Terminal

A real-time app made with node.js, socket.io, express …

January 19, 2012 2 comments

This past weekend I decided to work on a pet project – build a real-time app using node.js.

Modules used: socket.io, express, jade, sqlite3.

Still screenshot:

News Board still image

News Board 3 clients on the left, admin UI on the right

Checkout the source codes at:
https://github.com/midnightcodr/news_board

Video demo is available here (audio-less).

Have fun.

Categories: node.js, socket.io

[Fresh] Install node.js on Ubuntu server 11.10 (x64) via nvm step by step guide

January 8, 2012 2 comments
sudo apt-get -y install build-essential libssl-dev curl git
cd ~
git clone git://github.com/creationix/nvm.git
. ~/nvm/nvm.sh
nvm install v0.6.7     # Current version as of this writing
nvm use v0.6.7
curl http://npmjs.org/install.sh | sh      # Optional to install npm but recommended

Note:

  • It’s better to put the source command (. ~/nvm/nvm.sh) into your ~/.bashrc since the nvm command might get used quite often:
    if [ -f ~/nvm/nvm.sh ]; then
        . ~/nvm/nvm.sh
    fi
    
  • If anything goes wrong during nvm install (for example, complaining certain library is not installed, I found the easiest way to re-start the install process is to install the missing library, followed by the removal of installation directory, ~/nvm/src/node-v0.6.7, for example
  • On my ubuntu vm running off an i3 laptop, it took 7 minutes to install node.js v0.6.7, YMMV
  • If you find yourself stuck inside node console, type command process.exit() to get out, solution found from here
Categories: node.js, nvm, ubuntu

Change git origin

January 7, 2012 Leave a comment

Scenario:
you checkout a remote github repo as read-only:

git clone git://github.com/yourusername/oneofyourrepo

After you work on the local working directory for a while you decide that you would want to be able to push the changes back to github.

The easiest way is to either:
1) run the follow command on the root of the working directory:

git config remote.origin.url git@github.com:yourusername/oneofyourrepo

2) edit .git/config, look for section [remote “origin”] and change the url to
git@github.com:yourusername/oneofyourrepo

If you have already added the ssh public key of the host that you are working on to github.com, you should now be able to push the changes.

Credit goes to: http://stackoverflow.com/questions/3011402/leaving-github-how-to-change-the-origin-of-a-git-repo

Categories: git

Build a simple PHP template with str_replace()

January 5, 2012 Leave a comment

You are given a task to notify a list of customers regarding their pin setting changes through their email address on file. There are many ways to accomplish this in PHP. One way I found quite interesting is through a simple php function str_replace. Let me demo through the following example (only showing how the message body is constructed, the email address part should be easy to take care of):

<?php
        /* main.php */
        function build_key($key) {
                return '{{'.$key.'}}';
        }

        function gen_msg($format_str, $arr) {
                $keys=array_map(build_key, array_keys($arr));
                // $keys can also be generated by using the following code
                // but I found using array_map is more elegant and fun
                // $keys=array();
                // foreach(array_keys($arr) as $k) {
                //      array_push($keys, '{{'.$k.'}}');
                // }

                return str_replace( $keys, array_values($arr), $format_str);
        }

        // here's the template
        $template="Dear {{user}}, your pin number has been changed to {{pin}}.";

        // here's the data, hard-coded in this example but it can be pulled from external sources as well
        $data=array(
                array( 'user'=>'John Smith', 'pin'=>'1234' ),
                array( 'user'=>'Mr. S', 'pin'=>'9999' ),
                array( 'user'=>'Customer', 'pin'=>'****' )
        );

        foreach($data as $d) {
                printf("%s\n", gen_msg($template, $d));
        }

Run the above code through php (cli) will output the following:

Dear John Smith, your pin number has been changed to 1234.
Dear Mr. S, your pin number has been changed to 9999.
Dear Customer, your pin number has been changed to ****.

[ Update ] I also added an OOP implementation of the above code, if you are interested you can checkout my code on github.

Categories: php, Programming