Tuesday, May 31, 2011

PHP empty() function only checks variable

I want to blog this funny issue for a long time but always forgot:PHP's empty() function only works on variables, not on expression, not on the value returned by magic method __get

So let's see how funny empty() works.

class EmptyTest
{    
    public function getCategory() {
        return 'human';
    }
}

$test = new EmptyTest();
//expect to get false, but,,
var_dump(empty($test->getCategory()));

We will actually get "Fatal error: Can't use method return value in write context...". So to fix this issue, we have to do:

$category = $obj->getCategory();
//that will work as expected
var_dump(empty($category));

If that is the whole story, fine. At least we get fatal error and know what is wrong. Unfortunately, that is not the worst part of empty() yet. Let's check this:

class EmptyTest
{
    private $properties = array();
    
    public function __get($key) {
        return isset($this->properties[$key]) ? $this->properties[$key] : null;
    }
    
    public function __set($key, $value) {
        $this->properties[$key] = $value;
    }
}
$test = new EmptyTest();
$test->name = 'henry';
//expect to get false, but,,,
//we will get true!
var_dump(empty($test->name));

As you will see, we get true!!! For me, nothing could be worse than that. PHP just works as usual, doesn't complain anything, but simply gives us an unexpected result. It is like a logic bomb is placed in your application. Still, the easy solution is: 
$name = $test->name;
var_dump(empty($test->name));

Let's dig deepr about empty() and magic __get. Why it doesn't work as expected? Change our code:
class EmptyTest
{
    private $properties = array();
    
    public function __get($key) {
        echo '__get is invoked<br>';
        return isset($this->properties[$key]) ? $this->properties[$key] : null;
    }
    
    public function __set($key, $value) {
        $this->properties[$key] = $value;
    }
}
$test = new EmptyTest();
$test->name = 'henry';
var_dump(empty($test->name));

It turns out that the __get method is not even invoked! Change our code again:
class EmptyTest
{
    private $properties = array();
    
    public function __get($key) {
        echo '__get is invoked<br>';
        return isset($this->properties[$key]) ? $this->properties[$key] : null;
    }

    public function __isset($name) {
        echo '__isset is invoked<br>';
        return true;
    }
    
    public function __set($key, $value) {
        $this->properties[$key] = $value;
    }
}
$test = new EmptyTest();
$test->name = 'henry';
var_dump(empty($test->name)); 

Woho! This time, we get exactly what we expect! And we find that empty() invokes __isset method first. It tries to check if the method it is calling has been set or not! if it is set, it continues to invoke __get method.

Why empty() function works in such a funny manner? I have no idea. Even if I went to check its C source code, I'm afraid I still cannot understand why it is designed and implemented in this way.

bad coding practice: variable assignment inside if

I've seen some programmers like to put variable assignment inside an if conditional statement:

if ($record = $someObject->getRecord()) {
//do something with $record
}
//maybe do something with $record after the if block

To me, this is a very bad practice. I cannot figure out any benefits of putting variable assignment inside an if conditional statement. Probably the only thing is you can save one line of code? But look at the code below:

$record = $someObject->getRecord();
if ($record){
//do something with $record
}
//maybe do something with $record after the if block

Which one is easier to read? Which one is easier to understand? Which one will NOT bring any possible confusion? How about we just TRY to do one task per line of code?

The idea of trying to write less code(and then do less work) is absolutely correct. But this has a prerequisite: we should firstly ensure we do the work properly. If one more line of code can make the logic clearer and eliminate confusion, then we should just write one more line.

I truly believe this statement: "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". I think this statement comes from Martin Fowler's well known book "Refactoring: Improving the Design of Existing Code"? I believe this is a book that every programmer should keep reading often, particularly for those who work with languages that are very very flexible, like PHP.

Sunday, May 29, 2011

Cache configuration file

Today i read an article about caching of zend framework application configuration file:http://devzone.zend.com/article/14893-Caching-of-Zend-Framework-application-configuration-file

To me, the way how to implement this caching doesn't matter. We can always find a way to cache the config file that fits our own situation.

What really matters is the idea about caching configuration. I reckon i never thought of this before, partly because i think saving data in a file is already sort of caching compared with saving data in database.

So will the effort of caching configuration get paid off? I didn't do any serious test on it. But as i said, the thing that really matters to me is the idea, not its implementation or result. The idea reminds me that sometimes if we really think hard, and think out of box, not just satisfying with following the tradition that 'that is how we always do it', we probably can find something that could possibly imporve our application.

Friday, May 27, 2011

Server side javascript, when will you dominate

Back to 2008, when one of my friend told me that he believes one day javascript can take the place of PHP, I just laughed and didn't take it seriously. 

The world of web development has been changed so much that today we can't ignore javascript. The painful part that causes many developers don't like javascript programming, DOM manipulation inconsistency in variant browsers, will become more and more painless as browser vendors start to make their latest browsers become standard following, and people start to use these browsers. Also we already have many excellent javascript libraries that help to reduce the pain of crossing browser issue. No matter what, javascript dominates frontend development, and i believe it will keep dominating. And frontend is taking more and more business logics and becoming more important than ever.

But why only limit to frontend? As a programming language, is there any specific feature that cause it only suitable for frontend programming? I don't see any. I believe javascript is a plasticine language. It is so flexible that it can mimic OOP language, procedure language, functional language, or whatever. It is up to you that you like its flexibility or not, but that shouldn't be the reason that javascript can only survive in frontend, in browsers.

Actually, netscape did implement the first server side javascript in livewire. But somehow, server side javascript is not wildly supported and javascript turns to be a frontend specific programming language for people to create annoying popup windows. 

However, let's imagine that we can use javascript at both frontend and backend. How wonderful it could be! Developers don't have to spend time learning backend language and frontend languages and become more productive. Employers don't have to worry about looking for frontend developers and backend developers. Web will become a better place. 


I wish this day can come faster, the day that server side javascript become wildly supported. It doesn't have to be replace PHP or other backend languages, but it can be as popular as them and offer one more option for developers and development. 

I have to say, i still like PHP. But I just so believe that if javascript can work at both frontend and backend, the world of web will become much much better and more wonderful.

javascript programming is not that painful

Before the occurrence of ajax, many developers think javascript is just a toy programming language that can do nothing but only create those annoying popup windows and fancy stuff for a website. I was one of these developers.

The occurrence of ajax and the concept of RIA significantly change developer's mind to javascript. Now they start to accept the fact that javascript is something that you can't offer without having it in web application development. However, most of backend developers still don't like javascript and frontend programming. I was one of these developers.

Actually, the statement that 'backend developers don't like javascript programming' is not accurate. They don't like javascript, but it is NOT javascript's fault. To be more precisely, what they don't like is DOM manipulation. DOM manipulation is painful because it is not consistent on different browsers! It is a consistence issue, an issue about standard. Browsers don't follow same standard. I think that is why some javascript libraries like jQuery become so popular, because they try to make DOM manipulation easier when crossing browsers.

I still don't like DOM manipulation. But, javascript programming without DOM manipulation is just like backend programming that could be very enjoyable, assuming you love programming. I gain this experience by recently developing a game on HTML5 canvas, which i don't have to worry about browsers, as long as they support canvas, the game can run. Again, it is about consistence and standard. Fortunately, this time, browsers follow same standard.

If your frontend application logic is complex(like a game), you will find that all your skills about backend programming and software engineering are useful. OOA/OOP, design patterns, separation of concerns, refactoring, testing, domain modeling, conventions, they all apply.

Thursday, May 26, 2011

javascript design patterns - Factory

Factory pattern is used to create objects. The most normal implementation is a static method of a class(object in javascript). 

When to use Factory Pattern?
When you need to create objects that implement same interface, and you don't know(you don't need to know, and you shouldn't know) the specific class type/object type at compile time, factory pattern is the solution for you.

Suppose you have a Car interface:
//code below is not a correct interface implementation in javascript, 
//but just suppose it is an interface
var Car = function(){};
Car.prototype.run = function(){};

//suppose we have an extend() method doing the inheritance 
var Mazda = function(){};
extend(Mazda, Car);

var Ford = function(){};
extend(Ford, Car);

//Now, we need a factory method to make cars for clients.
Car.factory = function(name) {
    //here is the condition to check which car should be made.
    //usually is a switch/case, but here i simply use if else
    if (name === 'ford') {
        return new Ford();
    }
    if (name === 'mazda') {
        return new Mazda();
    }   
}

//i want a car!
var myCar = Car.factory('mazda');
//run!!!!
myCar.run();

data, information and knowledge

What is data? What is not data?
Data is NOT information. Data is NOT knowledge.

Data is a word in a book you are reading. Data is a number of interest rate that you learn from news. Data is the price of something that you try to buy or sell.

Data can be unstructured, like the words in a text. Data can be structured, like your selling data in database.

Data is out of context. That means, it has no meaningful relation to anything else. 4.75% is a piece of data. Does it mean anything to you? You may associate it with something. You may think it is interest rate. You may think it is inflation rate.

We can collect hugh amount of data. They may already exist in your database? They may be out there, somewhere, on the internet, in books, in articles, in TV news, in peoples' brain. When you are selling something, you are generating data. When you are doing a survey, you are collecting data.

We need data. But data alone doesn't mean anything. Sweeter, male, 20, they are data. But they have no meaning without context. On top of data, we need to find 'information'.

What is information?
Information is NOT knowledge.
nformation is quite simply an understanding of the relationships between pieces of data, or between pieces of data and other information.
Information relates to description, definition, or perspective (what, who, when, where)

4.75% is data. It tells you nothing. But interest rate 4.75% tells you something. What will you know when you see a single word 'rising'? What will you know when you see the words 'water price is rising'?

Sweeter, male, 20 are data. They are collected in a survey. They tell you nothing. But "males at 20 age like sweeter coca cola" does tell you something.

While information is an understanding of the relations between data, it doesn't tell you why the data is what it is, nor an indication as to how the data is likely to change over time. Information has a tendency to be relatively static in time and linear in nature. Information is a relationship between data and, quite simply, is what it is, with great dependence on context for its meaning and with little implication for the future.

You know interest rate is 4.75%. So what? How is it gonna affect your life? Is it high? Or is it low? Is it gonna rise, is it gonna stay there, or is it gonna come down? In a survey, Jack reckons he is 20, male, and he wishes coca cola could be a little sweeter. What does it mean to coca cola corp?

On top of information, we need knowledge
What is knowledge?
Knowledge tells you how. Knowledge comprises strategy, practice, method, or approach(how).
Knowledge is a pattern that you can understand and provides reliability or predictability as to how the pattern will evolve over time.

interest rate is 4.75%. This is the information. You know if you deposit 100$ in a bank, the bank will pay 4.75% interest yearly, and at the end of one year you will have 104.75$ in your bank account. You know the pattern, your money will keep growing in this way. If you withdraw, you will earn less interest. That is your knowledge.

Wednesday, May 25, 2011

blog based knowledge management

i've been writting blogs so more frequently this year than ever, because i start to think blog is a good tool for personal knowledge management.

Before i start to work in my current company, which provides a knowledge management software, the concept of knowledge management never explicitly exists in my mind, although i used to collect some good articles, and write down some problem solutions and save them in online google doc. In company, i like to share my findings with email, and i always suggest if we can put our findings on company wiki, that may help other developers save their time. But, i never know that these practices are actully kindof knowledge management.

So, what kind of blog can serve well as a personal knowledge management tool? Or, what is a good blog based knowledge management system? I will try to generate a list later, and if you can think of any, please do let me know.

javascript design patterns - observer

Design patterns are not OOP language specific. Javascript is a plasticine language, it can mimic OOP, so design patterns apply too.

Observer pattern is probably the most wildly used design pattern in frontend javascript programming. All those events and listeners, they are some sort of observer pattern implementation(Is there something called backend javascript programming? There is! And i believe one day it will dominate. Check http://nodejs.org if you are interested. Why do we have to use PHP at the backend and javascript at the frontend? Isn't it amazing we can use one langauge at both frontend and backend?)

Here is a very simple observer example:

function Observable() {
    this.observers = [];
}
Observable.prototype.addObserver = function(observer) {
    this.observers.push(observer);
};

Observable.prototype.notifyObservers = function() {
    for (var i=0; i<this.observers.length; i++) {
        this.observers[i].update();
    }
};

function Observer(id) {
this.id = id;
}
Observer.prototype.update = function() {
console.log(this.id + ' get updated');
}

var campaign = new Observable();
var userOne  = new Observer('one');
var userTwo  = new Observer('two');

campaign.addObserver(userOne);
campaign.addObserver(userTwo);

//console log:
//'one get updated' 
//'two get updated'
campaign.notifyObservers();

Observer is a great pattern for loose coupling. Instead of Observable object calling the Observer object's method, the Observer object is attached/added to the Observable object and gets notified. This concept is wildly used in event driven development. An event is triggered, and it is broadcasted to all the event's listeners

javascript design patterns - singleton

Design patterns are not language specific(Or i should say not OOP language specific). They apply to all OOP languages.

Javascript is a plasticine language, it can mimic OOP, and design patterns apply too.

When we use the object literal to create an object, we are actually getting a singleton.

//get a connection instance, a singleton
var connection = {
    type : 'sqlite',
    db: 'test',
    user: 'user',
    pwd : 'pwd'
};

In JavaScript, objects are never equal unless they are the same object, so even if you create an identical object with the exact same members, it won't be the same as the first one:

var conn = {
    type : 'sqlite',
    db: 'test',
    user: 'user',
    pwd : 'pwd'
};
//false
console.log(conn === connection);
//false
console.log(conn == connection);

Well, but that seems not that kindof singleton we are familiar with when programming with PHP or Java, doesn't it?

Singleton means we should have only one instance of a specific resource anytime, anywhere in the application scope. Database connection is a typical example of singleton. In PHP, you probably can only get a db resource in this way: DB::getInstance(). You cannot use 'new' operator to get an instance, and you can't clone this instance either. If you assign the instance to multiple variables, the variables are actually pointing to the same instance, for example:

//$one and $two point to the same instance!
//if somehow you change the status of $one, $two get affected too
$one = DB::getInstance();
$two = DB::getInstance();

Back to our javascript singleton examples. Although both connection and conn are singletons, we actually can have two instances of same resource. I don't think that is the singleton we want to have.

In javascript, we can use object literal to create an object, also we can use 'new' operator(constructor function) to create an object. So probably in a javascript project, we should set the convention that a singleton resource could only be created through 'new' operator, and we ensure the constructor function returns same instance:

//that is what we want to achieve
var connection = new Connection();
var conn       = new Connection();
//should be true
console.log(connection === conn);

So let's see how can we do it in the easiest and simplest way: using function property

var Connection = function() {

    if (typeof Connection.instance === "object") {
        return Connection.instance;
    }
    this.type = 'sqlite';
    this.db   = 'test';
    this.user = 'user';
    this.pwd  = 'pwd';

    Connection.instance = this;
}
var connection = new Connection();
var conn       = new Connection();
//should be true
console.log(connection === conn);

It is clean and easy. But the only drawback is Connection.instance is publicly accessible, so other codes might accidently change it.

To fix the drawback, we can use javascript's self-defining function

var Connection = function() {

    // the cached instance
    var instance = this;

    this.type = 'sqlite';
    this.db   = 'test';
    this.user = 'user';
    this.pwd  = 'pwd';

    // rewrite the constructor
    Connection = function () {
        return instance;
    };
}

This should serve well enough. But, you probably know that there is a drawback by using self-defining function, although that could rarely happen in practice. 

The third solution: using self-invoking function
var Connection;
(function () {
    var instance;
    //constructor
    Connection = function() {
        if (instance) {
            return instance;
        }
        instance = this;
        // all the functionality
        this.type = 'sqlite';
        this.db   = 'test';
        this.user = 'user';
        this.pwd  = 'pwd';
    };
}());

var connection = new Connection();
var conn       = new Connection();

javascript apply function (function application)

In javascript, when a function is called/invoked, it is actually applied. Calling a function is actually applying a set of arguments to a function. This concept exists in some purely functional programming languages as well.(Now who is saying javascript is an OOP language?)

function sayHiTo(who) {
   console.log('Hi, ' + who);
}

//you will have same result
sayHi('henry');
sayHi.apply(null, ['henry']);

apply() takes two parameters: the first one is an object to bind to "this" inside of
the function, the second is an array or parameters. If the first parameter is null, then "this"
points to the global object. 

So, let's do some interesting test

function sayHelloTo() {
    this.name = this.name || 'world';
    console.log('Hello, ' + this.name);
}

//console log 'Hello world'
sayHelloTo();

//define a global name variable
var name = 'henry';

//bind the global object to "this" of the sayHello function,
//so console log 'Hello henry'
sayHelloTo.apply();

//define a person object with name property
var person = {
   name : 'stranger'
}
//bind person object to "this" of the sayHello function
//so console log 'Hello stranger'
sayHelloTo.apply(person);

In addition to apply(), javascript function also has a call() method. call() is doing the same thing as apply() with only one difference: the second parameter of apply() should be an array of arguments, while call() takes arguments separated by comma. For example:

//both do the same job
func.apply(object, [var1, var2]);
func.call(object, var1, var2); 


javascript function property

Javascript functions are objects, so they can have properties and methods. Actually, they do. When you create a function, the function has a length property that indicates the number of arguments the function expects. A very simple example:

var getUserById = function(id) {
     var user = {id : id};
     //do other tasks
     return user;
}
//show 1
console.log(getUserById.length);

Another usage of function property is we can cache the result of a function, so we don't have to repeat the same computation again & again.

var calculation = function(seed) {
    if (!calculation.cache[seed]) {
        //do some expensive calculation based on seed
        var result = (seed * seed * 3 + 15) / 3.14;
        calculation.cache[seed] = result;
        console.log('calculation is done for ' + seed);
    }
    return calculation.cache[seed];
};

calculation.cache = {};

//you can see console log 'calculation is done for 3'
var testOne = calculation(3);
//you won't see console log because the result is return directly from cache.
var testTwo = calculation(3);

Tuesday, May 24, 2011

Funny tips to save your money

1. When it is raining, collect the water with your bucket. You can use it to water your flowers or even flush your toilet

2. When you are taking shower in winter, you probably have to wait until the shower water becomes warm. Don't waste those cold water, collect it with your bucket. You still can use it to water your flowers or flush your toilet.

3. If you are living with your partner, everytime one of you needs to use the toilet, ask the other one if he/she wants to use it too. Flush the toilet after you both have finished using it. So you don't have to flush the toilet twice.

4. Try to hand wash your clothes instead of using a washing machine. If you want to use washing machine, try to use it within off-peak time so the electricity cost you less. Also, try to take shower within off-peak time.

5. Try to bring left over to your company for lunch. Anyway, just try to minimize the frequency you eat outsite.

6. Don't watch TV too much, go to bed early.

7. If you can, bicycle to your office.

Monday, May 23, 2011

cron on linux quick reference

how to start a cron service?
sudo /usr/bin/service cron start

how to stop a cron service?
sudo /usr/bin/service cron stop

how to restart a cron service?
sudo /usr/bin/service cron restart

how to reload cron settings
sudo /usr/bin/service cron reload

how to list cron service
cron -l

how to edit cron service
cron -e

how to check the last time a crontab get modified?
go to /var/spool/cron, check the user's file's modfied datetime

cron format:
m h dom mon dow   command
* * * * * cmd

first * is minute0-59, second * is hour(0-23), third * is day of month(1-31), forth * is month(1-12), the last * is day of week(0-6,0 is Sunday)

*/5 * * * * cmd: / means every, so the first */5 mean every 5 minutes, and this cron means every 5 minutes, run the cmd command

If a crontab cannot run as you expect, please ensure the command PATH is correct before you spend your time checking other issues

run javascript after page load

why should we run javascript after a page loaded?

1. If we run javascript immediately after we place it in the HTML page, it will start loading and halt the rest of the HTML page from being loaded unit the javascript finished its job.
2. If a javascript runs before HTML elements are completely loaded, it might not be able to access some of the elements because those elements are not loaded yet.

How to run javascript after a page loaded?

1. The simplest and easiest way: using window.onload
window.onload = function() {
       //run your javascript
}
This way is very easy and simple. window.onload will NOT get invoked until a HTML page has finished loading everything.
However, it does have issues. It won't run until everything of a page has been loaded. That means, it will wait until large images, videos, music, if your page contains any of them, have been loaded completely. We just want to run our javascript after the browser is aware of the content, but we don't have to wait until the content is actually loaded onto our screen.

2. To fix the issues with window.onload, we can use a javascript library.
Take one of the most popular javascript library, jQuery, for example. We can simply do:
$(document).ready(function(){
   //run your javascript
});

jQuery is a fabulous javascript library that worth your time to learn.  Other javascript libraries also provide similar mechanism. For example, extjs method: Ext.onReady()

3. What if we don't want to use any 3rd party javascript library and just want to use native javascript?
In this situation, I personally would suggest simply using window.onload. To fix its issues with native javascript (and DOM) is tedious. I reckon no one will do that in their projects.  3rd party library like jQuery has beautifully wrap the tedious process for us so we can simply call $(document).ready().

Sunday, May 22, 2011

force extjs.data.store to use POST(or GET) only

By default extjs.data.store will use 'POST' when you pass any parameters, otherwise, it will use 'GET'. For example:
//use 'GET'
{
xtype : 'jsonstore',
url     :  'list.php'
}

//use 'POST'
{
xtype : 'jsonstore',
url     : 'getArticle.php',
params : {user_id : 1}
}

In case we want to always use one method without worrying about parameters, we have to specify the proxy:
//always use 'POST'
{
xtype : 'jsonstore',
proxy : new Ext.data.HttpProxy({url:'list.php', method:'POST'})
}

To use 'GET' only, just change the method to 'GET'.

extjs extend jsonstore

The problem: in an extjs application, we may have multiple jsonstores with same settings, and we don't want to repeat all these settings everytime we create a new jsonstore instance. For example, in my extjs application, all jsonstores have the following settings:

messageProperty : 'message',
successProperty   : 'result',
root                      : 'data'

And we want these settings to be default so we don't have to repeat them.

We actually can have two solutions to this problem.
Solution one: We can create a function that generate a jsonstore instance:

var getJsonStore = function(config) {
                return new Ext.data.JsonStore(Ext.apply({
                                messageProperty : 'message',
                                successProperty : 'result',
                                root : 'data'
                }, config));
}

With this solution, everytime you need a jsonstore, you call getJsonStore(customisedConfig);

What if we want to do lazy instantiation? For example, we want to do this:
{
xtype : 'jsonstore'
}

This comes to the second solution: extending jsonstore
Solution two: Extending jsonstore using Ext.extend
But extending jsonstore is a little different from extending other extjs components, because some properties like 'root', 'messageProperty' are actually NOT the config options of jsonstore. They are the config options of a jsonreader inside jsonstore. So you can't simply use Ext.extend. The following code will NOT work:

MyJsonStore = Ext.extend(Ext.data.JsonStore, {
    messageProperty : 'message',
    successProperty : 'result',
    root            :  'data',
    initComponent : function() {
        MyJsonStore.superclass.initComponent.call(this);
    }
});
Ext.reg('myjsonstore',MyJsonStore);

Instead, we have to do it in this way:

MyJsonStore = Ext.extend(Ext.data.JsonStore, {
            constructor : function(config) {
                        var baseConfig = {
                                    messageProperty : 'message',
                                    successProperty : 'result',
                                    root : 'data'
                        };

                        MyJsonStore.superclass.constructor.call(this, Ext.apply(baseConfig, config));
            }
});

Ext.reg('myjsonstore', MyJsonStore);

And now, we can do lazy instantiation:
{
xtype:'myjsonstore'
}

Thursday, May 19, 2011

blog mining

This blog mining thing pop up in my mind when i was writing my blogs and thinking why i'm writing blogs.

I see writing blogs as a way of personal knowledge management. We can have many other ways to manage personal knowledge, using Google Docs, for example.

And then i think, there are countless blogs out there, on the internet. And they are like a huge knowledge mine. At least, they provide huge amount of raw data, and information. That means blog mining can help us acquire valuable knowledge!

So i google 'blog mining'. Surprisingly, it is not very popular, unlike data mining and text mining, although they are related.

No matter what, i still believe blog mining has much potentials. I found two(only two) articles about this topic:




Wednesday, May 18, 2011

javascript merge two arrays/objects

I just want to simulate PHP's array_merge function in javascript.

So how to merge two normal arrays in javascript? The answer is Array.concat method. Check this code:
var o1 = [1, 2], o2 = ['a','b'];
//we will have an array [1,2,'a','b']
console.log(o1.concat(o2));

How about objects? Javascript object is actually the concept of associative array in PHP:
var o1 = {category:'living', name:'unknown'};
var o2 = {name:'henry', gender:'m'}

Well, we have to copy each property of the objects into a new object. So, finally, the general function to merge two arrays/objects in javascript:

var mergeObjects = function(objOne, objTwo) {
        if (objOne instanceof Array) {
            return objOne.concat(objTwo);
        }
        var merge = {};
        var property;
        for (property in objOne) {
            merge[property] = objOne[property];
        }
        for (property in objTwo) {
            merge[property] = objTwo[property];
        }
        return merge;
}

That is it. It is easy to be modified to be more generic and robust.

Tuesday, May 17, 2011

javascript dynamically call function by name

dynamically calling a function by name is easy in PHP:

class Person
{
    private $_category = 'human';
    public function getCategory() {
        return $this->_category;
    }
}

$p = new Person();
$method = 'getCategory';
echo $p->$method();

So how to dynamically call a function in javascript? let's see the code:

Person = {
    category : 'human',
    getCategory : function() {
        return this.category;
    }
};

var method = 'getCategory';
Person[method].apply(Person);

That is it! actually, it is the same question as how to access an object's property and method dynamically in javascript. As to the apply method, check my last blog : http://hengrui-li.blogspot.com/2011/05/javascript-callback-function-scope.html

Well, the example shows how to dynamically call an object's method by name in javascript. So how to dynamically call a global function by name in javascript? Easy as well. Remember that everything in javascript is actually a property of the global object? Check this code:

callMe = function() {
    alert('call me');
};

var method = 'callMe';

//in browser enviroment, window is the global object
window[method].apply();

javascript callback function scope

Let's check a simplified normal callback example:(to make things simple, i ignore all necessary type checks or validations before calling callback)

callbackTest = function(callback) {
    //do some tasks
    //and then callback
    callback();
};

callMe = function() {
   alert('henry');
};

//this will alert 'henry'
callbackTest(callMe);


The example works fine.  But what if the callback function is a method of an object? Let's modify the example a little bit:

callbackTest = function(callback) {
    //do some tasks
    //and then callback
    callback();
};

person = {
    name : 'henry',

    callMe : function() {
        alert(this.name);
    }
};

//we try to pass person.callMe as a callback function
callbackTest(person.callMe);

If you run the example, you will find the result is not as you expected. The reason is, the callback method uses 'this' to refer to the object it belongs to and it will cause unexpected behavior.
When we use callback to invoke person.callMe in callbackTest function, this.name is actually not defined, so this will refer to the global object. As you can imagine, if we define this.name in callbackTest function, the callback will actually alert the name defined in callbackTest instead of the person object.

So how to fix this issue? The solution is we need to pass the callback function and the object the callback belongs to. Check this code:

function callbackTest(callback, object)
{
     callback.call(object);
};

person = {
    name : 'henry',

    callMe : function() {
        alert(this.name);
    }
};
callbackTest(person.callMe, person);


Using callback.call, we can specify what scope the callback function should refer to. We can use callback.apply as well. call and apply perform exactly the same, except one difference:
call accepts the object to resolve scope to, and then parameters, like callback.call(object, val1, val2); apply accepts the object to resolve to, and then an array of parameters, like callback.apply(object,[val1,val2,val3]);

cd -, a bash command that takes you back to the previous directory

cd -, a very handy bash command that takes you back to the previous directory.

For example, i am in /var/www/. i first cd drupal/, then cd ../joomla. Now, i want to go back to /var/www/drupal, i can simply type cd -, and if i want to go back to /var/www/joomla again, i can input cd - again and it will take me back to joomla folder.

We can use this command to quickly switch back and forth between two directories.

Well but what happen when you just login the system and enter cd -? Well the possibility is you will see some information like OLDPWD is not set. So let's do an interesting test, if we change OLDPWD manually:
export OLDPWD='/home/henry'
and then we type cd -, and as expected, we are now in /home/henry folder.

Monday, May 16, 2011

save a file in vim without root permission

it is easy:

:w !sudo tee %

that is it!

I don't know others. But when i use vim to edit a file, i alway forget that i may not have the needed permission to save it.

So quite often that after i did all my changes and found i can't save them, i have to exit vim and use 'sudo vim' to do it again.

This command really come in handy. But, what is tee?

tee is a command that displays or pipes the output of a command and copies it into a file or a variable. It is primarily used in conjunction with pipes and filters.

To know more about tee, check this:

mysql event scheduler

Since Mysql 5.1.6, it supports a feature: event. Using this feature, we can make mysql run schedule tasks that we used to do in cron.

First, we activate the the event_scheduler

SET GLOBAL event_scheduler = 1;

Now, we can create an event

use test;

create table event_test (value datetime);

create event update_event on schedule every 1 second 
do
insert into event_test values(now());

Let 's wait for seconds and check the result:


select * from event_test;

+---------------------+
| value               |
+---------------------+
| 2011-05-17 11:56:14 |
| 2011-05-17 11:56:15 |
| 2011-05-17 11:56:16 |
| 2011-05-17 11:56:17 |
| 2011-05-17 11:56:18 |
| 2011-05-17 11:56:19 |
| 2011-05-17 11:56:20 |
+---------------------+

three handy mysql table operation

1. replicate a table & its data

create table new_table as select * from old_table

However, keep in mind that the new_table is myisam! So if your old_table is innodb, the new_table won't contain the key constraints

2. copy a table structure only (without its data)

create table new_table like old_table

3.rename a table

rename table old_table to new_table

PHP run command as ROOT


This post is for fun only.

In PHP, If we want to run any command as ROOT, like chown, chmod, how can we do that? In shell, we can use 'su' to run a command with ROOT privilege. For example, to change the mode of a file created by other users, we must have root privilege:

su --login root --command 'chmod 644 /absolute path/changeme.txt'

You will be asked to enter the ROOT password.

So, how can we complete the whole process in PHP code? In PHP manual, there is a function called 'popen'. According to the manual, popen opens a pipe to a process executed by forking the command given by command. It returns a file pointer identical to that returned by fopen() and this pointer may be used with fgets(), fgetss(), and fwrite().

This means, we can do read/write operation on the returned value by popen, same as what we do with the fopen. So, the way to let PHP run a command with ROOT privilege:

$su = "su --login root --command 'chmod 644 /absolute path/changeme.txt'";
$rootPassword = "password";
$fp = @popen($su, "w");
  
//now, we must give the password
@fputs($fp, $rootPassword);
@pclose($fp);

That is it! have fun!

Saturday, May 14, 2011

extjs 'events' is null or not an object error in IE (Internet Explorer 7, 8)

I have been working on this extjs application for a while. It works fine in firework, chrome and IE 9. But when i change to IE 7, i got this error message "'events' is null or not an object".  As usual, IE's error message doesn't make much sense, and it shows me the error occurs somewhere in extjs library. I know it couldn't be extjs causing this issue because i've seen much more complicated extjs applications and they work fine in IE 7. It must be my code.

Actually, i can almost guess what causes the problem: It must be some extra commas (And it turned out i was right at this). Check this code:

//work in firefox/chrome/IE9, but not in IE7,8
var me = {
      name : henry,
      gender: m,   //IE7 doesn't allow this last extra comma
}

//work in firefox/chrome/IE9, but not in IE7,8
var language = [
  'php',
 'java',  //IE7 doesn't allow this last extra comma
]

if we remove the last comman in the me object and language array, the code will work in IE7 as well.

I am so used to putting comma at the last item of an array or object because that is what i usually do in PHP array. PHP array also allows you to put extra comma at the last item:

$config = array(
        'db' => 'mysql',
        'username' => 'username', 
);

In the above code, the last comma brings so much convenience. If i need to add more config options, i simply add them at the bottom without worrying breaking anything.

Although I know what the reason is, but the problem is, how to find it? My IDE, Zend Studio almost helps me nothing in finding javascript coding problems. It can only remind you to put semicolon. So i turned out to netbean 7. In supporting javascript coding, netbean 7 is much better than Zend Studio(and Eclipse). At least it can warn you last extra comma in object is not supported by IE. But the funny thing is, it won't warn you that last extra comma in array is not supported by IE either!

No matter what, based on my experience so far, there are two headaches when working on big javascript projects. 1.We don't have a good IDE especially for javascript(At least i haven't found out yet). 2.Debugging. Debugging javascript is quite painful due to those misleading error messages.

Friday, May 13, 2011

generate combinations of elements from multiple arrays

Problem: we have multiple arrays, and we must find all combinations of the elements of these arrays. For example, if we have two array:

$option1 = array('apple', 'orange', 'pear');
$option2 = array('rice', 'noodle');

And we must find all combinations(there are 6 of them in this example) of these two array elements:

'apple', 'rice',
'apple', 'noodle',
'orange', 'rice',
'orange', 'noodle',
'pear', 'rice',
'pear', 'noodle'

First, let's see how to implement the algorithm in PHP:

//$allOptionsArray is an array containing all options array
//$final is a stdClass
function getCombinations($allOptionsArray, $final) {
    if(count($allOptionsArray)) {
        for($i=0; $i < count($allOptionsArray[0]); $i++) {
            $tmp = $allOptionsArray;
            $final->codes[$final->pos] = $allOptionsArray[0][$i];
            array_shift($tmp);
            $final->pos++;
            getCombinations($tmp, $final);
        }
    } else {
        $final->result[] = $final->codes;
    }
    $final->pos--;
}
//let's see how to use the function:
$option1 = array('apple', 'orange', 'pear');
$option2 = array('rice', 'noodle');
$allOptionsArray = array($option1, $option2);
$final = new stdClass();
$final->result = array();
$final->codes  = array();
$final->pos    = 0;
getCombinations($allOptionsArray, $final);
//$final->result is an array containing all possible combinations
var_dump($final->result);

We can easily implement same algorithm in javascript:

var getCombinations = function(allOptionsArray, combination) {
    if(allOptionsArray.length > 0) {
        for(var i=0; i < allOptionsArray[0].length; i++) {
            var tmp = allOptionsArray.slice(0);
            combination.codes[combination.counter] = allOptionsArray[0][i];
            tmp.shift();
            combination.counter++;
            getCombinations(tmp, combination);
        }
    } else {
        var combi = combination.codes.slice(0);
        combination.result.push(combi);
    }
    combination.counter--;
}

//use it:
var a = ["01", "02", "03", "04"];
var b = ["white", "green", "blue", "red"];
var c = ["one", "two", "three", "four"];
var d = ["a", "b", "c", "d"];

var allOptionsArray = [a, b, c, d];
var combination = {codes : [], result : [], counter : 0};

getCombinations(allOptionsArray, combination);

for(var i=0; i < combination.result.length; i++) {
    console.log(combination.result[i]);
}

Thursday, May 12, 2011

use jslint.com to check your javascript code quality (and prepare to get feeling hurt)

PHP developers may know that we can use php CodeSniffer (phpcs) to check php code quality. JSLint.com to javascript is exactly same as phpcs to php. The only issue is, you have to copy and paste your code through JSLint.com. Besides that, it is a pretty cool tool to help you find out your javascript coding issues. Try hard to ensure all your javascript code can pass through its test without any error. In my last blog, i said i need to find where my code causes the problem in IE and my IDE doesn't help me a lot, i use this jslint.com to find out finally.

Since you have to copy and paste your code to the website, it is better after we finish coding in one javascript file, we immediately check this file to ensure our code is in good coding quality. Otherwise, in a big javascript project, after you already created a lot of javascript files, and then come back to check them one by one, that is gonna be painful, and that is exactly what i've been feeling.


Wednesday, May 11, 2011

javascript function practices that hardly used in other language

Function in javascript is nothing but object. That means we can create functions dynamically, assign them to other variables, pass them as parameters of other functions. Function's role in javascript is quite special. And some practices are never seen in other programming languages.

1. Functions that Return Functions

function func() {
   alert('A!');

   //return a function!
   //well, we can just think we return an object
   return function(){
      alert('B!');
   };
}

//alert A
var b = func();
//alert B
b();



In the example, the outside function func() wraps a returned function, so it creates a closure, and we can use this closure to store private data, which is accessible by the returned function but not to the outside code. Let's see another example:

var setup = function () {
    //we have a counter, when setup is called,
    //the counter is set to 0
    var counter = 0;
    //the return function can access counter, 
//but outside code cannot see it.
    return function () {
       return (counter += 1);
    };
};
// usage
var next = setup();
next(); // returns 1
next();  //returns 2
next();  //returns 3

This example is a counter that gives you an incremented value every time you call it.


2. Self-Defining Functions(Functions rewrite themself!)

var itIsWeird = function() {
      alert('javascript function is weird');
      //rewrite itself now!!!!
      itIsWeird = function() {
           alert('it is not that weird');
      };
}
//first time call the function, 
//it shows javascript function is weird
itIsWeird();

//call the function again, 
//it shows it is not that weird
itIsWeird();


Self-Defining functions could be useful when your function has some initial preparatory work to do and it needs to do it only once(maybe some init job?). Because there’s no reason to do repeating work when it can be avoided, a portion of the function may no longer be required. In such cases, the self defining function can update its own implementation. It can obviously help with the performance of your application, because your redefined function simply does less work.

These practices are hardly seen in other languages. Well, but it doesn't mean they are good practices. Take self-defining functions as example. Yes they may be useful in some cases. But a function changes its own behavior by itself? One thing i always stress is we should try to minimize things that could possibly bring confusions in software engineering, and i think self-defining function is one the things we should try to avoid. And its benefits, well, i believe we can achieve in other ways that are more readable and easier to understand.

Tuesday, May 10, 2011

copy arrays & objects in javascript

In javascript, when we assign an array or object to a variable, we are actually making a reference to the objects(array is object too). check this code:

var a = ['henry'];
//b is a reference to a
var b = a;
b[0]   = ['li'];
//we can see a[0] is changed to 'li' as well
console.log(a[0]);



In some situations, however, we may just want a copy of the object, instead of a reference.

Let's see how to deal with array first. Copying an array in javascript is surprisingly easy, thanks to the array.slice(start, end) method. The slice() method selects a part of an array, and returns the new array. It accepts two parameters: start, end. If we set start to 0, and omit the end, the method will actually return a copy of the whole array. Check this code snippet:

var a = ['henry'];
//b is a copy of a
var b = a.slice(0);
b[0]   = ['li'];
//we can see a[0] is still 'henry'
console.log(a[0]);


When it comes to an object, things are not that easy. javascript doesn't have any method for us to copy an object(one of the things i can't believe).  Fortunately, we can create a prototype method to achieve this goal.

//first, we must know that all javascript objects(function, array, custom objects) are instances of Object.
//and we just create an Object prototype clone method  
Object.prototype.clone = function() {
  //first, it check if this is an array or object
  var cloneObject = (this instanceof Array) ? [] : {};
 //now look through the object's all properties
  for (i in this) {
    //if it is clone, then contiune
    if (i == 'clone') {
        continue;
    }
    //if the property is also a type of object, recursively call the clone method
    if (this[i] && typeof this[i] == "object") {
        cloneObject[i] = this[i].clone();
    } else {
        //if it is not object type, simply copy it
        cloneObject [i] = this[i]
    }
  }
  return cloneObject;
};




It is done! Now all javascript objects will have this clone method. Let's see how to use it:



//we create a constructor function

var Person = function (){
    this.name = 'henry';
    this.getName = function(){
        return this.name;
    }
}
//get a person object
var one = new Person();
//clone this object to two
var two = one.clone();
//now let's change two's name
two.name = 'henry li';
//we can see one's name remain unchanged.
console.log(one.getName());
console.log(two.getName());


Saturday, May 7, 2011

javascript object oriented programming 5 - private members 2(object literal)

My last blog shows how to achieve privacy for objects using function constructors. How about object literals?

Check the code:

//this is the object
var newCar;

//now, let js's anonymous immediate function do the trick
(function() {
//private members
var model = 'mazda 3';

//public implementation
//don't put 'var' before the newCar!
newCar = {
     getModel : function(){return model;}
};
}());

//now, let's call the getModel method, 
//you will get 'mazda 3'
newCar.getModel();


The way it works is easy to understand as long as we know, javascript object and function can provide local scope. So we just need a function to wrap the private data. In object literals, we can use the closure created by an additional anonymous immediate function.

But do we really want to create object privacy in this way? For me, this kind of code cannot be counted elegant. My last blog suggests we can simply use naming convention to achieve object privacy. It sounds not professional, but i believe that is the easiest way: easy to implement, easy to read, easy to understand, easy to modify.

Let's accept this truth: javascript is NOT especially designed as an object oriented programming language, it is  NOT  especially designed for OOP, even though it provides with the power/magic/flexibility that you can make it an OOP language or achieve all OOP language features.

I still believe the best word to describe javascript is plasticine. You can shape it and make it look like different things.

I have to declare that I am not against using javascript to do OOP. Actually, i believe we should apply OOA/OOP to any complicated and large javascript project, a web game, for example. But i don't think it is necessary that we twist javascript to prove that it is a fully OOP language.

Thursday, May 5, 2011

javascript object oriented programming 4 - private members

Let's check the code:
Car = {
   model : 'mazda 3',
   getModel : function() {return this.model},
}
//we can access the model property directly
console.log(Car.model);
//how about we use function constructor?
var Car = function() {
    this.model = 'mazda 3';
}
var newCar = new Car;
//we still can access the model property directly.
console.log(newCar.model);


In the above examples, we can't hide object's properties from being exposed. What if we want to have private properties and private methods/functions that can be accessed only in the object, just like what we do in java and php 5?

Same as we use object scope to achieve namespace, we can also create private members for our object.
var Car = function() {
    //the model variable is only visible within the Car object now!
   //so it becomes a private property of Car
    var model = 'mazda 3';
    //since function, which is object in js, can be assigned to a variable,
    //we can have private function too!
   // this upgrade function is only visible in Car scope!
    var upgrade = function(newModel) {
        model = newModel;
    };
    //a public method.
    this.getModel = function() {
        upgrade('mazda 6');
        return model;
    }
}
var newCar = new Car();
//will get undefined
console.log(newCar.model);
//will get error
newCar.upgrade('toyota');
//will get mazda 6
newCar.getModel();


Some people say javascript is a functional programming language, some argue it is object based language because almost everything is object in javascript, while others prove that javascript can have full OOP features just like other modern object oriented programming languages like java. 

I would say, javascript is a plasticine programming language! You can shape it as whatever you want !

Actually, i think we don't even need to bother about implementing those private member stuff. If we really want to have private, we can simply use naming convention: private members must be prefixed with underscore, for example:
var Car = function() {
    this._model = '3';
    this._upgrade = function(newModel) {
        this._model = newModel;
    };
    this.getModel = function() {
        this._upgrade('mazda 6');
        return this._model;
    }
}

And then, just tell your team members to follow this coding convention: when you see something prefixed with _, you know you shall not directly access it or change its status.