2016-02-01

Open Source my iOS game: Mission999

iOS Game  Mission999

itunes:   https://itunes.apple.com/au/app/mission-999/id1036686316?mt=8
code :    https://github.com/whunmr/Mission999
map editor code:  https://github.com/whunmr/Method-Draw-Game-Map-Editor



The map is in edited by Method-Draw in SVG format,  after edit the map can be send through by WebSocket directly into iOS app, to achieve a short edit-->try-->re-edit loop feedback.

















Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text
Alt text


2016-01-29

Internal DSL or External DSL?

DSL:
A domain-specific language (DSL) is a programming language that mimics the terms, idioms, and expressions used among experts in the targeted domain.


DSL优势:

Encapsulation

A DSL hides implementation details and exposes only those abstractions relevant to the domain.
Productivity
Because implementation details are encapsulated, a DSL optimizes the effort re quired to write or modify code for application features.

Communication
A DSL helps developers understand the domain and domain experts to verify that the implementation meets the requirements. A domain expert with little experience in programming can read, understand, and validate this code




DSL劣势:

DSLs are difficult to create
Although writing a DSL is “cool,” the effort shouldn’t be underestimated. First, the implementation techniques can be nontrivial (see the following example). Second, good DSLs are harder to design than traditional APIs.

DSLs are hard to maintain
DSLs can require more maintenance over the long term as the domain changes, because of the nontrivial implementation techniques used.  Implementation simplicity is often sacrificed for a better user experience.






Internal DSLs:
From Programming Scala


If the DSL is “close-enough” that it can be implemented internally with reasonable effort and ro bustness, the user experience will generally be better. It’s clearly the best choice for the test libraries mentioned earlier.


External DSLs:

 

The external DSL is simpler, but the user must embed the DSL in strings. Hence, code completion, refactoring, color coding, and other IDE features aren’t available.
If the DSL is too far removed from Scala syntax, perhaps because it’s a well-known language, like SQL, using an external DSL with quoted strings is probably best.




As a starting point for the discussion let’s take this definition from Martin Fowler “An internal DSL is just a particular idiom of writing code in the host language. So a Ruby internal DSL is Ruby code, just written in particular style which gives a more language-like feel. As such they are often called Fluent Interfaces or Embedded DSLs. An external DSL is a completely separate language that is parsed into data that the host language can understand”.

Erik started the controversy with this highly provocative statement:
I fully ascribe to Hudak-style embedded DSL, which really just are well-designed APIs. External DSLs on the other hand are like puppies, they all start out cute and happy, but without exception turn into vicious beasts as they grow up1 (make, XSLT, regular expressions, …).
and from there, all hell broke loose, with supporters of external DSLs claiming that better tool support in the shape of language workbenches made the statement untrue or at least made the cost of creating those DSLs acceptable
external DSLs are ugly: I think they are, but so are death and taxes
while internal DSLs fans discredited the tool support argument by saying that this was only a small part of the problem.

External DSLs … have no mother language to depend upon, and so they must reinvent much general purpose behavior.



使用内部还是外部DSL?

if ( 领域概念清晰 and  领域概念数目可控  ) {  //可尝试采用DSL
      if ( 目标DSL的代码量大 and 表达复杂度高 ) {
            //建议采用内部DSL            
            //1.  可借助编程语言本身的 图灵可计算性 来提升DSL能力            
            //2.  写DSL表达业务时,可借助编译器对语法正确与否的判断提示
            //3.  重构DSL时,可借助IDE的重构功能, 因为内部DSL本身就是正常的代码
          
     else  if ( 想突破编程语言语法限制,使用更符合领域的表达 ) {
            //采用外部DSL     
      }

else {
      //领域经常变化,会加大DSL维护成本
}



参考书箱 Programming Scala

2014-11-29

draw msgflow in reactive app





cpp_idioms.org



usually we got log like following:
[sys1] ---->   [sys2] 00001  MSG_0  0x00010002 0x00030004
[sys2] ---->   [sys3] 00002  MSG_1  0x00010002 0x00030004
[sys3] ---->   [sys1] 00003  MSG_2  0x00010002 0x00030004

but a diagram like following is more readable:
sys1   sys2   sys3   
  |----->|      |     MSG_0   [0x00010002 0x00030004]
  |      |----->|     MSG_1   [0x00010002 0x00030004]
  |<------------|     MSG_2   [0x00010002 0x00030004]

I implemented a simple app to draw this diagram: https://github.com/whunmr/msgflow

more complicated diagram generated from log:
ss3   kk3   zz1   qq1   qq2   kk1   bb1   aa1   ss1   
 |     |     |     |     |     |     |     |     *     MSG_0   [1] [0x00010002 0x00030004]
 |     |     |     |     |     |     |     |<----|     MSG_1   [2] [0x00010002 0x00030004]
 |     |     |     |     |     |     |     |---->|     MSG_2   [3] [0x00010002 0x00030004]
 |     |     |     |     |     |<----|     |     |     MSG_3   [4] [0x00010002 0x00030004]
 |     |     |     |     |     |---------------->|     MSG_4   [5] [0x00010002 0x00030004]
 |     |     |     |     |     |<----------------|     MSG_5   [6] [0x00010002 0x00030004]
 |     |     |     |     |     |     |     |<----|     MSG_6   [7] [0x00010002 0x00030004]
 |     |     |     |     |<----------------------|     MSG_7   [8] [0x00010002 0x00030004]
 |     |     |<----|     |     |     |     |     |     MSG_8   [9] [0x00010002 0x00030004]
 |     |     |---------------------------->|     |     MSG_9   [10] [0x00010002 0x00030004]
 |     |     |     |     |     |     |     |---->|     MSG_2   [11] [0x00010002 0x00030004]
 |     |<----------------------------|     |     |     MSG_3   [12] [0x00010002 0x00030004]
 |     |     |     |     |     |---------------->|     MSG_4   [13] [0x00010002 0x00030004]
 |     |<----------------------------------------|     MSG_5   [14] [0x00010002 0x00030004]
 |---------------------------------------->|     |     MSG_6   [15] [0x00010002 0x00030004]
 |---------------->|     |     |     |     |     |     MSG_7   [16] [0x00010002 0x00030004]
 |     |     |<----------------------------------|     MSG_8   [17] [0x00010002 0x00030004]
 |     |     |---------------------------------->|     MSG_9   [18] [0x00010002 0x00030004]

 


DSL for reactive application implementation in C++





cpp_idioms.org



def_mi(Basic_mi_x) {
                                         step(sync_call_1);
                                         step(sync_call_2);
        sysd<----------------------------async_step(async_call_1) {
                sysd-------------------->ack(msg_ack_1, on_msg_ack_1);
                sysd-------------------->ack(msg_ack_2, on_msg_ack_2);
                
                sysd-------------------->ack_ex(msg_ack_4)
                {
                                         step(sync_call_nested_1);
                        sysx<------------async_step(nested_async_call_1)
                        {
                                sysx---->ack(nested_msg_ack_1, on_nested_msg_ack_1);
                                sysx---->ack(nested_msg_ack_2, on_nested_msg_ack_2);
                                sysx---->ack(msg_ack_1, on_nested_msg_ack_3);            
                        } async_step_end;
                } on_msg_ack_ex_end;
        }async_step_end;
} def_mi_end;


https://github.com/whunmr/reactive_cpp



2014-05-09

Generate dynamic examples for cucumber Scenario outline






In following scenario outline, examples will be generated by `generate_example_data_func`:



Feature: test feature
  Scenario Outline: testing
    * test_tool __________________* "<foo>"
    * test_tool *__________________ "<bar>"
  Examples: 
    | foo                             | bar |
    | `generate_example_data_func`    |     |


implementation of `generate_example_data_func`, and steps:



Given(/^test_tool __________________\* "(.*?)"$/) do |arg1|
end

Given(/^test_tool \*__________________ "(.*?)"$/) do |arg1|
end

def generate_example_data_func table
  table <<  ["xxx", "yyy"]
  table <<  ["aaa", "bbb"]

  table
end

running result:
$ cucumber –expand



Feature: test feature

  Scenario Outline: testing                 # features/reading_report/test.feature:2
    * test_tool __________________* "<foo>" # features/step_definitions/new_step.rb:1
    * test_tool *__________________ "<bar>" # features/step_definitions/new_step.rb:4

    Examples: 

      Scenario: | xxx | yyy |                 # features/reading_report/test.feature:-1
        * test_tool __________________* "xxx"   # features/step_definitions/new_step.rb:1
        * test_tool *__________________ "yyy"   # features/step_definitions/new_step.rb:4

      Scenario: | aaa | bbb |                 # features/reading_report/test.feature:-1
        * test_tool __________________* "aaa"   # features/step_definitions/new_step.rb:1
        * test_tool *__________________ "bbb"   # features/step_definitions/new_step.rb:4

2 scenarios (2 passed)
4 steps (4 passed)
0m0.028s


To support dynamic generate example data, we need change the scenario_outline.rb`:



def create_examples_table(example_section_and_gherkin_examples)
  example_section = example_section_and_gherkin_examples[0]
  gherkin_examples = example_section_and_gherkin_examples[1]

  examples_location    = example_section[0]
  examples_comment     = example_section[1]
  examples_keyword     = example_section[2]
  examples_title       = example_section[3]
  examples_description = example_section[4]
  examples_matrix      = example_section[5]

  #CHANGE BEGIN#####################################################
  #~/.rvm/gems/ruby-1.9.3-p392/gems/cucumber-1.3.14/lib/cucumber/ast/scenario_outline.rb
  if examples_matrix.length > 1 && examples_matrix[1].length > 1
      using_function_to_generate_examples = !(examples_matrix[1][0] =~ /^`.*`$/).nil?

      

      if using_function_to_generate_examples
        function_str = examples_matrix[1][0].gsub!(/`(.*)`/, '\1') + "([" + examples_matrix[0].to_s  + "])"
        examples_matrix = eval(function_str)
      end
  end
  #CHANGE END#####################################################

  examples_table = OutlineTable.new(examples_matrix, self)
  ex = Examples.new(examples_location, examples_comment, examples_keyword, examples_title, examples_description, examples_table)
  ex.gherkin_statement(gherkin_examples)
  ex
end





2013-11-01

Make message interaction more readable, by using c++ local class





main (1).cpp



Make message interaction more readable, by using c++ local class::::

c++ local class:
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr062.htm


/////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <map>

using namespace std;

#define MESSAGE_SEND       3
#define MESSAGE_TIME_OUT   4
#define MESSAGE_RESPONSE   5

/////////////////////////////////////////////////////////////////////////////
struct Worker {
    virtual void operator()() = 0;
};

/////////////////////////////////////////////////////////////////////////////
struct HandlerPool {
    void addMsg(int msg, Worker& a) {
        maps[msg] = &a;
    }

    void run(int msg) {
        if (maps.find(msg) != maps.end()) {
            (*maps[msg])();
        } else {
            cout << "no handler" << endl;
        }
    }

    map<int, Worker*> maps;
};

HandlerPool g_handlePool;
/////////////////////////////////////////////////////////////////////////////
#define if_on_msg(msg) IF_ON_MSG(onMsg_##msg)

#define IF_ON_MSG(msg_handler_class)        \
static struct msg_handler_class : Worker {  \
    void operator()()

#define end_if_on_msg(msg) END_IF_ON_MSG(msg, onMsg_##msg##_handler)

#define END_IF_ON_MSG(msg, handler_instance_name) \
} handler_instance_name;                          \
g_handlePool.addMsg(msg, handler_instance_name)

/////////////////////////////////////////////////////////////////////////////
struct Worker_Before_refactor : Worker {
    void processMsg(/*const Message& msg*/) {

        //`people can not see which message came first, which is the last one`
        //`so can not know the message_interaction by reading code`

        switch (msg) {
            case MESSAGE_TIME_OUT: 
              ....
            case MESSAGE_RESPONSE: 
              .... 
            case MESSAGE_XXXX: 
              ....
            case MESSAGE_YYYY: 
              ....
        }
    }
};

/////////////////////////////////////////////////////////////////////////////
struct WorkerAfterRefactor : Worker {
    void operator()() {
        sender------->receiver(MessageBody);

        if_on_msg(sender<------------receiver(MESSAGE_TIME_OUT)) {

            sender------->receiver(MessageBody);
            if_on_msg(sender<------------receiver(MESSAGE_TIME_OUT)) {
                cout << "retry still got timeout..." << endl;
            } end_if_on_msg(MESSAGE_TIME_OUT);

        } end_if_on_msg(MESSAGE_TIME_OUT);

        if_on_msg(sender<-----receiver(MESSAGE_RESPONSE)) {
            cout << "succeeded got ack" << endl;
        } end_if_on_msg(MESSAGE_RESPONSE);
    }
};

/////////////////////////////////////////////////////////////////////////////
int main(int argc, const char * argv[])
{
    WorkerAfterRefactor a;

    g_handlePool.addMsg(MESSAGE_SEND, a);

    g_handlePool.run(MESSAGE_SEND);
    g_handlePool.run(MESSAGE_TIME_OUT);
    g_handlePool.run(MESSAGE_TIME_OUT);
    g_handlePool.run(MESSAGE_RESPONSE);

    return 0;
}
/////////////////////////////////////////////////////////////////////////////
//output:
//------>send sca config to slave board
//<----timeout...
//----->retry send sca config to slave board
//<-----retry still got timeout...
//<----succeeded got ack
//
//Process finished with exit code 0


2013-10-25

USING operator overload to make your C++ functional test more readable





tricks-cpp-operator-for-sendmsg.org



* usually we need test message communication between sub-systems, so the ft maybe looks like following: 

before refactor:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
struct HeartBeatAckTest : testing::Test {
  protected: 
    SubSystemA aaa;
    SubSystemB bbb;
    Request request;
};

TEST_F(HeartBeatAckTest, should_able_to_reply_heart_beat_ack) {
    MOCKER(shouldReceiveMsg)     //using mockcpp
        .expects(exactly(1))
        .with( eq(MSG_HEART_BEAT_ACK)
             , any()
             , eq(bbb.address())
             , eq(aaa.address()));

    Msg::send(aaa, bbb, MSG_HEART_BEAT, &request);
}

//By using operator overload we can make send and receive more easy to read
//we can set MOCKER by operator<, --, () and send msg by operator>, --, ()

after refactor:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#define expects_msg if(true)

TEST_F(AckTest, aaa_should_able_to_reply_heart_beat_ack) {
    expects_msg {
        aaa<-----bbb(MSG_HEART_BEAT_ACK);    
    }

    aaa---->bbb(MSG_HEART_BEAT, &request);
}

TEST_F(AckTest, bbb_should_reply_heart_beat_ack___AND___forward_heart_beat_to_ccc) {
    expects_msg {
        aaa<-----bbb(MSG_HEART_BEAT_ACK);
        ccc<-----bbb(MSG_HEART_BEAT);
    }

    aaa---->bbb(MSG_HEART_BEAT, &request);
}

more thoughts::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// the <----- is used to set MOCKER before ----->, can we? put the <---- after -----> ,
// to make the message interaction more easy to comprehensive.

// similar to `RAII`, actually we can defer the send message operation of -----> to the end of scope expects_msg.

struct SendAllBufferedMessageAtEndOfScope {
    SendAllBufferedMessageAtEndOfScope(int i) { }  //make it can init from dummy int 
    
    ~SendAllBufferedMessageAtEndOfScope() {
        send_all_buffered_message_in_sequence();
    }

    operator bool() { return true; }
};


#define expects_msg_interaction if (SendAllBufferedMessageAtEndOfScope sendMsgAtEnd = 1)


TEST_F(AckTest, should_able_to_reply_heart_beat_ack) {
    expects_msg_interaction {
        aaa ----> bbb (MSG_HEART_BEAT, &request);     //buffer the messge
        aaa <---- bbb (MSG_HEART_BEAT_ACK);           //set the MOCKER specification
                                                      //invisible destructor code of sendMsgAtEnd
    }
}

TEST_F(AckTest, bbb_should_reply_heart_beat_ack___AND___forward_heart_beat_to_ccc) {
    expects_msg_interaction {
        aaa ----> bbb (MSG_HEART_BEAT, &request);
        aaa <---- bbb (MSG_HEART_BEAT_ACK);
        ccc <---- bbb (MSG_HEART_BEAT);
    }

}

example code::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
struct SubSystemB {
    SubSystemB& operator--(int) {
        return *this;
    }

    template<typename T>
    bool operator >(const T& target) {
        target.receiveMsg();
        return true;
    }
};

struct SubSystemA {
    const SubSystemA& operator()(int msgId, int* p) {
        msgId_ = msgId;
        return *this;
    }

    void receiveMsg() const {
        std::cout << "cc got message: " << msgId_ << std::endl;
    }

    int msgId_;
};

int main(int argc, const char * argv[])
{
    SubSystemB bbb;
    SubSystemA aaa;

    int param = 0;
    bbb---->aaa(1, &param);

    return 0;
}


//another example:
TEST_F(AckTest, bbb_should_reply_heart_beat_ack___AND___forward_heart_beat_to_ccc) {
    expects_msg_interaction(
        op1 ----------------> xx (MSG_HEART_BEAT, &request);
        op1 <---------------- xx (MSG_HEART_BEAT_ACK);

            op2 ------------> xx (MSG_HEART_BEAT, &request);

                op3 --------> xx (MSG_HEART_BEAT, &request);
                op3 <-------- xx (MSG_HEART_BEAT_ACK);

                    op4 ----> xx (MSG_HEART_BEAT, &request);
                    op4 <---- xx (MSG_HEART_BEAT_ACK);

        op1 ----------------> xx (MSG_HEART_BEAT, &request);
        op1 <---------------- xx (MSG_HEART_BEAT_ACK);

            op2 ------------> xx (MSG_HEART_BEAT, &request);

                op3 --------> xx (MSG_HEART_BEAT, &request);
                op3 <-------- xx (MSG_HEART_BEAT_ACK);

                    op4 ----> xx (MSG_HEART_BEAT, &request);
                    op4 <---- xx (MSG_HEART_BEAT_ACK);
    );
}



2013-06-19

using emacs to manage temporary files during debugging





a.lisp



We always need some temporary files to do editing work.
for example, we got 10000+ line logs to trace bug in it, first thing to do is create a tmp file.

1. To create a tmp file we'd like to
- quick open the files in a directory without naming collision, with short-key `C-; t`
- store the tmp files for future search/grep

;;code
    (defun create-and-open-tmp-file ()
      (interactive)
      (find-file (s-concat
              "~/Documents/hongmin.wang/Google Drive/notes/tmp"
              (format-time-string "%Y%m%d___%H_%M_%S")
              (uuid-string)
              ".temp")))
    (global-set-key (kbd "C-; t") 'create-and-open-tmp-file)

2. To manage versions of tmp file, we like to put it in a git direcotry
   and `C-x v i` to register the tmp file to git
   and `C-x v v` to commit new version of the tmp file to git.

3. sometime, you think the tmp file is no longer an tmp file,
   do a "Save As..." by `C-x C-w`


2013-06-06

record and mock http interactions of third-party server

* Can not setup env in home. so i can not debug my application at home remotely

I am debugging and web application, but I need an ESP fast server to
always return XML data for my search, then I can debug things.

but i can not access the fast server at home, so i can not work remotely at home.

I want have an application to monitor my web application's interactions with
fast server, and recording the interacting data(including delays),
and can replay/mock the services at home.

* python -m SimpleHTTPServer 9000
* http://localhost:9000/null_main.c
* sudo justniffer -i lo0 -r -p "port 9000"
GET /null_main.c HTTP/1.1
Host: localhost:9000
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
If-Modified-Since: Sat, 20 Oct 2012 09:17:23 GMT

HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.1
Date: Thu, 06 Jun 2013 13:27:41 GMT
Content-type: text/plain
Content-Length: 46
Last-Modified: Sat, 20 Oct 2012 09:17:23 GMT

/* null_main.c */

int main() {
  return 0;
}

* TODO need running the mock server according the recorded http data

-->

2013-04-20

daily debugging tips and toolbox





debugging.org



* debugging tips
strace::
http://www.thegeekstuff.com/2011/11/strace-examples/

where is the log files of specified process (e.g. nginx)?
@firstly, find your process's pid
ubuntu@ip:~ $ ps -ef | grep nginx
root     13622     1  0 Mar03 ?        00:00:00 nginx: master process /usr/sbin/nginx
www-data 13623 13622  0 Mar03 ?        00:03:19 nginx: worker process
www-data 13624 13622  0 Mar03 ?        00:00:00 nginx: worker process
www-data 13625 13622  0 Mar03 ?        00:03:19 nginx: worker process
www-data 13626 13622  0 Mar03 ?        00:03:19 nginx: worker process
ubuntu   19058 18961  0 10:31 pts/0    00:00:00 grep --color=auto nginx
@secondly, using lsof to find all handle of that "pid", then grep it
ubuntu@ip:~ $ sudo lsof -f -p 13622 | grep log
nginx   13622 root    2w   REG              202,1        0 145222 /var/log/nginx/error.log
nginx   13622 root    5w   REG              202,1        0 135398 /var/log/nginx/access.log
nginx   13622 root    6w   REG              202,1        0 145222 /var/log/nginx/error.log

which process is listen on port 80?
ubuntu@ip:~ $ sudo lsof -i:80
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   13622     root    7u  IPv4  27232      0t0  TCP *:http (LISTEN)
nginx   13623 www-data    7u  IPv4  27232      0t0  TCP *:http (LISTEN)
nginx   13624 www-data    7u  IPv4  27232      0t0  TCP *:http (LISTEN)
nginx   13625 www-data    7u  IPv4  27232      0t0  TCP *:http (LISTEN)
nginx   13626 www-data    7u  IPv4  27232      0t0  TCP *:http (LISTEN)

what's my process's environemnt variables?
[vagrant@vagrant-centos-6-64 ~] $ ps -ef | grep apache
apache    2136  1382  0 10:11 ?        00:00:00 /usr/sbin/httpd
[vagrant@vagrant-centos-6-64 ~] $ sudo cat /proc/1382/environ
TERM=linuxPATH=/sbin:/usr/sbin:/bin:/usr/binrunlevel=3RUNLEVEL=3LANGSH_SOURCED=1PWD=/LANG=Cprevious=NPREVLEVEL=NCONSOLETYPE=vtSHLVL=3UPSTART_INSTANCE=UPSTART_EVENTS=runlevelUPSTART_JOB=rc_=/usr/sbin/httpd

let mysql log the queries?
@execute following command in mysql console
SET GLOBAL log_output = 'FILE'; Set GLOBAL general_log_file = '/tmp/mysql.log'; SET GLOBAL general_log = 'ON';
@ or directly in bash
 $ mysql -uroot -pYOUR-PASSWORD -e "SET GLOBAL log_output = 'FILE'; Set GLOBAL general_log_file = '/tmp/mysql.log'; SET GLOBAL general_log = 'ON';"
@ then tail /tmp/mysql.log, see the quries against mysql
 $ tail -f /tmp/mysql.log

how to monitor http request/response of this machine?
@install justniffer on mac
 $ brew install boost
 $ brew install justniffer
@ Capture all tcp traffic
 $ sudo justniffer -i eth0 -r
        GET /null_main.c HTTP/1.1
        Host: localhost:9000
        Connection: keep-alive
        Cache-Control: max-age=0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
        Accept-Encoding: gzip,deflate,sdch
        Accept-Language: en-US,en;q=0.8
        If-Modified-Since: Sat, 20 Oct 2012 09:17:23 GMT
        
        HTTP/1.0 200 OK
        Server: SimpleHTTP/0.6 Python/2.7.1
        Date: Thu, 06 Jun 2013 13:27:41 GMT
        Content-type: text/plain
        Content-Length: 46
        Last-Modified: Sat, 20 Oct 2012 09:17:23 GMT
        
        /* null_main.c */
        
        int main() {
          return 0;
        }
@ Capture only http traffic
 $ sudo justniffer -i eth0 -r -p "port 80 or port 8080"
 
@Capture smtp traffic (usually using tcp port 25)
 $ sudo justniffer -i eth0 -r -p "port 25"
        220 plecno.com ESMTP Postfix (Ubuntu)
        
        EHLO unknown.localnet
        250-plecno.com       
        250-PIPELINING       
        250-SIZE             
        250-VRFY             
        250-ETRN             
        250-STARTTLS         
        250-ENHANCEDSTATUSCODES
        250-8BITMIME           
        250 DSN
        ...
        --Boundary-00=_ZI47J3FTNXn+25g
        Content-Type: text/html;
        charset="us-ascii"
        Content-Transfer-Encoding: 7bit
        
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
        "http://www.w3.org/TR/REC-html40/strict.dtd">
        <html>
        <head>
        ...

How to monitor changes in directory?
@run following command, and try to touch/rm files. the results of `watch` will changing.
 $ watch -d -n 0.1 "ls"


How to start a HTTP server on port 3000 for files in directory ~?
 $ cd ~
 $ python -m SimpleHTTPServer 3000

        

TO BE CONTINUE::::


2013-04-06

express-IOC

https://github.com/whunmr/express-ioc
https://github.com/johnelf/express-mvc
https://github.com/whunmr/express-orm



Framework design:
  • less intrusiveness
  • simple to use
  • Flent API: User.find_all().includes(Article.class);
  • Convention over configuration

DEMO CODE
git@github.com:whunmr/express-orm.git


IMPLEMENTATION of Lazy List


  • allOf
  • anyOf
  • both
  • either
  • describedAs
  • everyItem
  • is
  • anything
  • hasItem
  • hasItems
  • equalTo
  • instanceOf
  • any
  • not
  • nullValue
  • notNullValue
  • sameInstance
  • containsString
  • endsWith
  • startsWith
  • hasProperty
  • samePropertyValuesAs
  • array
  • hasItemInArray
  • arrayContainingInAnyOrder
  • arrayContaining
  • arrayWithSize
  • emptyArray
  • hasSize
  • empty
  • emptyIterable
  • isIn
  • isOneOf
  • containsInAnyOrder
  • contains
  • iterableWithSize
  • hasEntry
  • hasKey
  • hasValue
  • closeTo
  • comparesEqualTo
  • greaterThan
  • greaterThanOrEqualTo
  • lessThan
  • lessThanOrEqualTo
  • hasToString
  • typeCompatibleWith
  • eventFrom
  • isEmptyString
  • isEmptyOrNullString
  • equalToIgnoringCase
  • equalToIgnoringWhiteSpace
  • stringContainsInOrder
  • hasXPath
  • matcher1
  • matcher2
  • matcher3
  • firstMethod
  • secondMethod
  • notStatic
  • notPublic
  • goodMethod
  • anotherGoodMethod
  • wrongReturnType
  • generifiedType
  • noGenerifiedType
  • crazyType
  • withParam
  • withArray
  • withVarArgs
  • withGenerifiedParam
  • withExceptions
  • documented
  • subclassMethod
GUAVA
moco:

cglib introduction:

dynamic-proxy:
git@github.com:whunmr/java-demos.git

intelliJ IDEA
foreach:
  • iter (for each..in)
  • itin (for..in)
  • itli Iterate List itar Iterate array
  • ritar reverse order

WORKSHOP about dynamic-proxy/cglib/javassist
a. how to using instrument lib
  1. gradle clean idea
  2. in instrument folder, execute gradle jar
  3. setup configuration so we can using the instrument agent jar, when running junit test. In IntelliJ IDEA, Run-->Edit Configurations…-->Defaults-->JUnit: set "VM Options:" to -javaagent:./instrument/build/libs/instrument.jar


b. get the task from here https://github.com/whunmr/java-demos

c. find //TASK1 //TASK2 //TASK3, and finish the //TODOs in the task.


FUTHER READING:
Inside the Java Virtual Machine