블로그 이미지
Peter Note
Web & LLM FullStacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2013. 1. 24. 21:53 Languages/CoffeeScript

if, switch, for loop 구문등을 사용해 보자 


1) 조건문

  - yes : true, no : false, if not : unless 

  - if not 과 yes no 사용하기 : if2.coffee

machine = 
	running: no
	turnOn: -> this.running = yes
	turnOff: -> this.running = no

###
if not === unless
###
if not machine.running
	machine.turnOn()

machine.turnOne() if not machine.running
console.log machine.running

unless machine.running
	machine.turnOn()
else
	machine.turnOff()

// Generated by CoffeeScript 1.4.0
(function() {
  var machine;
  machine = {
    running: false,
    turnOn: function() {
      return this.running = true;
    },
    turnOff: function() {
      return this.running = false;
    }
  };

  /*
  if not === unless
  */
  if (!machine.running) {
    machine.turnOn();
  }
  if (!machine.running) {
    machine.turnOne();
  }
  console.log(machine.running);

  if (!machine.running) {
    machine.turnOn();
  } else {
    machine.turnOff();
  }
}).call(this);

// 결과 : 9번째 줄과 12번째 줄은 같은 구문이다 

D:\Development\coffeescript>coffee if2

true



  - switch ~ then 구문 사용하기 : switch.coffee

person = 
	name: "dowon"
	job: "programmer"

giveWork = (person) ->	
	switch person.job
	  when "programmer"
	  	console.log "1> Here's your code work, #{person.name}"
	  when "designer"
	  	console.log "1> Here's your design work, #{person.name}"
	  else 
	  	console.log "1> Um, do you work here?"	  	
giveWork person	  	

# or
person.job = "designer"
giveWork2 = (person) ->	
	switch person.job 
	  when "programmer" then console.log "2> Here's your code work, #{person.name}"
	  when "designer" then console.log "2> Here's your design work, #{person.name}"
	  else console.log "2> Um, do you work here?"
giveWork2 person

// Generated by CoffeeScript 1.4.0
var giveWork, giveWork2, person;
person = {
  name: "dowon",
  job: "programmer"
};

giveWork = function(person) {
  switch (person.job) {
    case "programmer":
      return console.log("1> Here's your code work, " + person.name);
    case "designer":
      return console.log("1> Here's your design work, " + person.name);
    default:
      return console.log("1> Um, do you work here?");
  }
};
giveWork(person);

person.job = "designer";
giveWork2 = function(person) {
  switch (person.job) {
    case "programmer":
      return console.log("2> Here's your code work, " + person.name);
    case "designer":
      return console.log("2> Here's your design work, " + person.name);
    default:
      return console.log("2> Um, do you work here?");
  }
};
giveWork2(person);

// 결과 

D:\Development\coffeescript>coffee switch

1> Here's your code work, dowon

2> Here's your design work, dowon



  - if 문 console.log를 앞으로 뽑아내기 : member.coffee

     + 컴파일 내역

     + 결과는 같지만 구문 코드는 틀리다 

     + 2번과 3번 구문이 제일 짧다 

person1 = 
	name: "dowon"
	relationship: "friend"
person2 = 
	name: "youngsik"
	relationship: "boss"

greet = (person) ->
	if person.relationship is "friend"
		console.log "1> hi, #{person.name}!"
	else if person.relationship is "boss"
		console.log "1> hello, papa!"
greet person1
greet person2
# or
greet2 = (person) ->
	msg = if person.relationship is "friend"
		"2> hi, #{person.name}!"
	else if person.relationship is "boss"
		"2> hello, papa!"
	console.log msg
greet2 person1
greet2 person2
# or
greet3 = (person) ->
	console.log if person.relationship is "friend"
		"3> hi, #{person.name}!"
	else if person.relationship is "boss"
		"3> hello, papa!"
greet3 person1
greet3 person2
# or
greet4 = (person) ->
	msg = switch person.relationship 
		when "friend" then "4> hi, #{person.name}!"
		when "boss" then "4> hello, papa!"
	console.log msg
greet4 person1
greet4 person2

// Generated by CoffeeScript 1.4.0
(function() {
  var greet, greet2, greet3, greet4, person1, person2;
  person1 = {
    name: "dowon",
    relationship: "friend"
  };
  person2 = {
    name: "youngsik",
    relationship: "boss"
  };

  greet = function(person) {
    if (person.relationship === "friend") {
      return console.log("1> hi, " + person.name + "!");
    } else if (person.relationship === "boss") {
      return console.log("1> hello, papa!");
    }
  };
  greet(person1);
  greet(person2);

  greet2 = function(person) {
    var msg;
    msg = person.relationship === "friend" ? "2> hi, " + person.name + "!" : person.relationship === "boss" ? "2> hello, papa!" : void 0;
    return console.log(msg);
  };
  greet2(person1);
  greet2(person2);

  greet3 = function(person) {
    return console.log(person.relationship === "friend" ? "3> hi, " + person.name + "!" : person.relationship === "boss" ? "3> hello, papa!" : void 0);
  };
  greet3(person1);
  greet3(person2);

  greet4 = function(person) {
    var msg;
    msg = (function() {
      switch (person.relationship) {
        case "friend":
          return "4> hi, " + person.name + "!";
        case "boss":
          return "4> hello, papa!";
      }
    })();
    return console.log(msg);
  };
  greet4(person1);
  greet4(person2);
}).call(this);

// 결과 : 전부 동일한 결과를 출력한다 

D:\Development\coffeescript>coffee member

1> hi, dowon!

1> hello, papa!

2> hi, dowon!

2> hello, papa!

3> hi, dowon!

3> hello, papa!

4> hi, dowon!

4> hello, papa!



2) for 구문 

  - for 구문을 다양하게 사용하는 방법

  - 5가지 for loop 문 사용방법 : loop.coffee

arr = ["Net", "Aet", "Photo", "Psd", "Cgt"]

obj = 
	name: "dowon"
	topic: "web development"
	editor: "yun"

###
for ( var i = 0; i < arr.length; i++) {
	console.log(arr[i]);
}	
###
console.log "---1---"
for siteName in arr
	console.log siteName

console.log "---2---"
console.log siteName for siteName in arr

console.log "---3---return array---"
console.log (siteName for siteName in arr)	

console.log "---4---"
for siteName, i in arr
	console.log "#{i}: #{siteName}"	

console.log "----5--"
for siteName, i in arr when siteName.indexOf("P") is 0	
	console.log "#{i}: #{siteName}"	

console.log "---6---"
###
by 2 ===  when i % 2 is 0
###
for siteName, i in arr by 2
	console.log "#{i}: #{siteName}"	


// Generated by CoffeeScript 1.4.0
(function() {
  var arr, i, obj, siteName, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _step;
  arr = ["Net", "Aet", "Photo", "Psd", "Cgt"];

  obj = {
    name: "dowon",
    topic: "web development",
    editor: "yun"
  };

  /*
  for ( var i = 0; i < arr.length; i++) {
  	console.log(arr[i]);
  }
  */
  console.log("---1---");
  for (_i = 0, _len = arr.length; _i < _len; _i++) {
    siteName = arr[_i];
    console.log(siteName);
  }

  console.log("---2---");
  for (_j = 0, _len1 = arr.length; _j < _len1; _j++) {
    siteName = arr[_j];
    console.log(siteName);
  }

  console.log("---3---return array---");
  console.log((function() {
    var _k, _len2, _results;
    _results = [];
    for (_k = 0, _len2 = arr.length; _k < _len2; _k++) {
      siteName = arr[_k];
      _results.push(siteName);
    }
    return _results;
  })());

  console.log("---4---");
  for (i = _k = 0, _len2 = arr.length; _k < _len2; i = ++_k) {
    siteName = arr[i];
    console.log("" + i + ": " + siteName);
  }

  console.log("----5--");
  for (i = _l = 0, _len3 = arr.length; _l < _len3; i = ++_l) {
    siteName = arr[i];
    if (siteName.indexOf("P") === 0) {
      console.log("" + i + ": " + siteName);
    }
  }

  console.log("---6---");
  /*
  by 2 ===  when i % 2 is 0
  */
  for (i = _m = 0, _len4 = arr.length, _step = 2; _m < _len4; i = _m += _step) {
    siteName = arr[i];
    console.log("" + i + ": " + siteName);
  }
}).call(this);	

// 결과

D:\Development\coffeescript\2>coffee loop

---1---

Net

Aet

Photo

Psd

Cgt

---2---

Net

Aet

Photo

Psd

Cgt

---3---return array---

[ 'Net', 'Aet', 'Photo', 'Psd', 'Cgt' ]

---4---

0: Net

1: Aet

2: Photo

3: Psd

4: Cgt

----5--

2: Photo

3: Psd

---6---

0: Net

2: Photo

4: Cgt



3) Scope 알아보기 

  - this 에 대한 유효범위(scope)를 보았을 때 object의 method로 사용되지 않는 단순 function 호출의 this는 global object (즉, UI에서는 window객체)를 가르킨다 (참조)

var classroom = {
	students: ["Jonh", "Jane", "Jill", "Joe"],
	print: function() {
		var thiz = this;
		function getName(i) {
			return thiz.students[i];
		}
		for(var i=0; i < this.students.length; i++) {
			console.log(getName(i));
		}
	}
}
classroom.print();


  - 위의 경우를 coffee로 표현하고자 할 경우 다음과 같이 => 사용하면 "var thiz = this;" 를 표현할 수 있다

classroom = 
	students: ["Jonh", "Jane", "Jill", "Joe"]
	print: ->
		getName = (i) =>    // =>를 사용하면 var thiz = this; 동일 효과가 가능하다 
			this.students[i]

		for s,i in this.students
			console.log getName i 

classroom.print()

// Generated by CoffeeScript 1.4.0
(function() {
  var classroom;
  classroom = {
    students: ["Jonh", "Jane", "Jill", "Joe"],
    print: function() {
      var getName, i, s, _i, _len, _ref, _results,
        _this = this;
      getName = function(i) {
        return _this.students[i];
      };
      _ref = this.students;
      _results = [];
      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
        s = _ref[i];
        _results.push(console.log(getName(i)));
      }
      return _results;
    }
  };
  classroom.print();
}).call(this);


* 파일 

coffeescript-2.zip


posted by Peter Note
2013. 1. 24. 21:52 Languages/CoffeeScript

CoffeeScript는 ; { 등을 가급적 배제하고 휴먼리더블하게 작성하게 해준다. 한줄띄기, 스페이스, 탭 등으로 구분하여 작문(코딩)을 한다 


1) 기본적인 작성법

  - 문자, 오브젝트, 범위, 변수

  - 문자 다루기 : #{} 을 통하여 변수 맵핑 : hi.coffee

name = "dowon"
greeting = "hi, #{name}!"
multi = """
this is a greeting:
	#{greeting}

"""
console.log multi

// 결과 : """ 를 사용했을 때 내부의 띄워쓰기 그대로 적용됨 <pre> 태그 유사 

D:\Development\coffeescript>coffee hi


this is a greeting:

        hi, dowon!


D:\Development\coffeescript>



  - 범위 다루기 : ..과 ... 의 차이는 끝수 포함/미포함 : range.coffe

range = [0..10]
console.log range

range = [0...10]
console.log range

range = [15...10]
console.log range

// 결과

D:\Development\coffeescript>coffee range

[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

[ 15, 14, 13, 12, 11 ]


  

  - 오브젝트 다루기 : obj.coffee

obj = name: "dowon", job: "Programmer"
console.log obj
obj = 
	name: "dowon-01" 
	job: "Programmer-01"
console.log obj

name = "dowon-02"
job = "Programmer-02"
obj = name: name, job: job
console.log obj

obj = {name, job}
console.log obj

 - key:value 같은 줄에 쓰면 콤마(,) 구분

 - 한줄 띠기 하면 콤마 필요없음

 - {name} 하면 명칭을 그대로 key 명칭을 활용


// 결과 

D:\Development\coffeescript>coffee obj

{ name: 'dowon', job: 'Programmer' }

{ name: 'dowon-01', job: 'Programmer-01' }

{ name: 'dowon-02', job: 'Programmer-02' }

{ name: 'dowon-02', job: 'Programmer-02' }



  - 변수 다루기 : variable.coffee

[one, two, three] = ["1", "2", "3"]
console.log two
console.log three
name = "dowon"
obj = {name, job:"Programm er", other: {name}}
console.log obj

// Generated by CoffeeScript 1.4.0
(function() {
  var name, obj, one, three, two, _ref;
  _ref = ["1", "2", "3"], one = _ref[0], two = _ref[1], three = _ref[2];

  console.log(two);
  console.log(three);
  name = "dowon";
  obj = {
    name: name,
    job: "Programmer",
    other: {
      name: name
    }
  };
  console.log(obj);
}).call(this);

// 결과 

D:\Development\coffeescript>coffee variable

2

3

{ name: 'dowon', job: 'Programmer', other: { name: 'dowon' } }



2) Function 다루기 

  - 주석, 함수, 아규먼트 배열, Math.random 

  - 주석 : # 무시되는 문장 (컴파일시 주석문도 안남음), ### 주석 /* */ 으로 변환 : comment.coffee

one = 1 # comment
###
comment 2
###
two = 2


  - 함수 만들기 : -> 사용 : greet.coffee

###
function greet (name) {
	console.log("hi" + name +"!");
}
greet = function(name) {
}
###

greet = (name) -> console.log "hi #{name}!"
greet "Greeting" 
greet2 = (name = "friend") -> "hi #{name}"
console.log greet2
console.log greet2()

// 결과

D:\Development\coffeescript>coffee greet

hi Greeting!

[Function]

hi friend       <=== () 를 붙여서 함수 호출한다 



  - 배열 아규먼트 만들기 : ... 사용 : array.coffee

test = (x, y, z...) -> 
	console.log x
	console.log y
	console.log z

test "one", "two", "three"
console.log "---------------------"
test "one", "two", "three", "four", "five"	


test2 = (x..., y, z) -> 
	console.log x
	console.log y
	console.log z

test2 "one", "two", "three"
console.log "---------------------"
test2 "one", "two", "three", "four", "five"	

test3 = (x, y..., z) -> 
	console.log x
	console.log y
	console.log z

test3 "one", "two", "three"
console.log "---------------------"
test3 "one", "two", "three", "four", "five"	

// 결과 

D:\Development\coffeescript>coffee array

one

two

[ 'three' ]   

---------------------

one

two

[ 'three', 'four', 'five' ]


// test2 호출 

[ 'one' ]

two

three

---------------------

[ 'one', 'two', 'three' ]

four

five


// test3 호출 

one

[ 'two' ]

three

---------------------

one

[ 'two', 'three', 'four' ]

five



  - 자동 실행 함수 : do 사용하여 자동 실행토록 만들어준다 : anon.coffee

###
(() -> console.log())()
###

###
automatically invoke function
###
do (message = "hi dowon") ->
	console.log message

// Generated by CoffeeScript 1.4.0
/*
(() -> console.log())()
*/

/*
automatically invoke function
*/

(function() {
  (function(message) {
    return console.log(message);
  })("hi dowon");

}).call(this);

// 결과 : 만일 do를 넣지 않으면 수행되지 않음

D:\Development\coffeescript>coffee anon

hi dowon



  - Math.random 사용하기 : random.coffee

###
Math.random()
###

rand = (max = 10, min = 0) -> Math.floor(Math.random() * (max - min + 1)) + min

console.log rand()
console.log rand 100
console.log rand 60, 50

// 결과 : 수행때 마다 틀린 random값이 지정 범위내에서 출력됨 

D:\Development\coffeescript>coffee random

5

100

53


D:\Development\coffeescript>coffee random

1

32

53



3) 비교연산

  - ===, !== 사용하기 

  - if 문 사용하기 

  - ===, !== 를 사용하는 대신 is, isnt  문장으로 사용하기 : operator.coffee

###
is ===
isnt !==
###
name = "dowon"
if name is "dowon"
	console.log "great"

if name isnt "Dowon"
	console.log "poor"	

### if( !false ) ###
if not false
	console.log "cool"

###
var name = "dowon",
	job = "programmer";

if(name === "dowon" || job === "programmer") {
	console.log("right")
}	
###
name = "dowon"
job = "programmer"

if name is "dowon" and job is "programmer"
	console.log "right"

// 결과

D:\Development\coffeescript>coffee operator

great

poor

cool

right



  - ? 연산자를 통하여 null 체크 하기 : operator2.coffee

name = "dowon"
if name?
	console.log "hi"
person = 
	name: "dowon"
	job: "programmer"

console.log person?.name
name = name || "youngsik"
name ||= "youngsik"
name ?= "youngsik"
console.log name

// Generated by CoffeeScript 1.4.0
(function() {
  var name, person;
  name = "dowon";
  if (name != null) {
    console.log("hi");
  }
  person = {
    name: "dowon",
    job: "programmer"
  };

  console.log(person != null ? person.name : void 0);
  name = name || "youngsik";
  name || (name = "youngsik");
  if (name == null) {
    name = "youngsik";
  }
  console.log(name);
}).call(this);

// 결과

D:\Development\coffeescript>coffee operator2

hi

dowon

dowon



  - if 문을 재구성한다 : if.coffee

# x = 4
# if( x >= 0 && x <= 10) {}
x = 4
if 0 <= x <= 10
	console.log "true"

// Generated by CoffeeScript 1.4.0
(function() {
  var x;
  x = 4;
  if ((0 <= x && x <= 10)) {
    console.log("true");
  }
}).call(this);

// 결과

D:\Development\coffeescript>coffee if

true


* 테스트 파일 다운로드



4) CoffeeScript 문법 & 장/단점

  - if 문을 한줄로 사용할 때 조건 뒤에 then 구문 붙이기 

    예) if name is "dowon" then console.log "right"

posted by Peter Note
2013. 1. 24. 21:51 Languages/CoffeeScript

CoffeeScript를 설치하고 사용해 보자 


1. 설치하기

  - Node.js 설치함

  - NPM(Node Package Manager) 설치함 : npm을 통하여 coffe-script 를 설치한다 

  - 참조 : http://coffeescript.org

D:\Development\javascript>npm install -g coffee-script

npm http GET https://registry.npmjs.org/coffee-script

npm http 200 https://registry.npmjs.org/coffee-script

C:\Documents and Settings\UserXP\Application Data\npm\cake -> C:\Documents and Settings\UserXP\Application Data\npm\node_modules\coffee-script\bin\cake

C:\Documents and Settings\UserXP\Application Data\npm\coffee -> C:\Documents and Settings\UserXP\Application Data\npm\node_modules\coffee-script\bin\coffee

coffee-script@1.4.0 C:\Documents and Settings\UserXP\Application Data\npm\node_m

odules\coffee-script


D:\Development\javascript>coffee -v

CoffeeScript version 1.4.0



2. Coffee 사용하기 

  - 확장자 .coffee 파일을 만든다

  - coffee 명령으로 수행할 수도 있고, js 파일로 컴파일 할 수도 있다


  - 일반적인 js 코딩 : arr.js

function makeArray(dimension) {
        var arr = [], i = 0, j = 0;
	for(; i < dimension; i++) {
		arr[i] = [];
		for( j=0; j < dimension; j++) {
			arr[i][j] = '1111';
		}
	}
	return arr;
}

var myArr = makeArray(4);

console.log(myArr);

// 결과 

D:\coffeescript>node arr

[ [ '1111', '1111', '1111', '1111' ],

  [ '1111', '1111', '1111', '1111' ],

  [ '1111', '1111', '1111', '1111' ],

  [ '1111', '1111', '1111', '1111' ] ]



- CoffeeScript 코딩 방식 : arr.coffee (coffee 확장자)

makeArray = (dimension) ->
	arr = []
	for i in [0...dimension]
		arr[i] = []
		arr[i][j] = '1111' for j in [0...dimension]
	arr
	
myArr = makeArray 4

console.log myArr	

console.log 'dowon hi'

// 결과 

D:\coffeescript>coffee arr.coffee

[ [ '1111', '1111', '1111', '1111' ],

  [ '1111', '1111', '1111', '1111' ],

  [ '1111', '1111', '1111', '1111' ],

  [ '1111', '1111', '1111', '1111' ] ]



- CoffeeScript js를 일반 js 파일로 컴파일 하기 

D:\coffeescript>coffee -c arr.coffee


// 컴파일로 생성된 arr.js 소스 파일 

// Generated by CoffeeScript 1.4.0
(function() {
  var makeArray, myArr;

  makeArray = function(dimension) {
    var arr, i, j, _i, _j;
    arr = [];
    for (i = _i = 0; 0 <= dimension ? _i < dimension : _i > dimension; i = 0 <= dimension ? ++_i : --_i) {
      arr[i] = [];
      for (j = _j = 0; 0 <= dimension ? _j < dimension : _j > dimension; j = 0 <= dimension ? ++_j : --_j) {
        arr[i][j] = '1111';
      }
    }
    return arr;
  };

  myArr = makeArray(4);

  console.log(myArr);

  console.log('dowon hi');

}).call(this);



3. Coffee Watching & REPL(레플) 사용하기

  - coffee 파일이 변경되어 저장되는 시점에 자동으로 컴파일 되도록 한다 : watch

  - w 옵션을 준다 

////////////////////////////////

// watch 옵션 주기

D:\Development\coffeescript>coffee -cw arr.coffee

17:51:59 - compiled arr.coffee

17:52:29 - compiled arr.coffee   <--- arr.coffee 파일 마지막에 새로운 내용을 넣고 저장하면 자동으로 compile 됨


////////////////////////////////

// REPL을 통하여 coffee 수행해 보기

D:\Development\coffeescript>coffee

coffee> 1 + 1

2

coffee> arr = []

[]

coffee> arr[0] = 'dowon'

'dowon'

coffee> arr

[ 'dowon' ]

coffee> arr.push 'hi'

2

coffee> arr

[ 'dowon', 'hi' ]

coffee> arr[1]

'hi'

coffee>



4. Single Page Application (SPA : 스파) 를 만들때 CoffeeScript를 사용하자

  - 코딩을 간결하게 해준다

  - global variable등의 사소한 문법오류를 잡아준다 

  - 그러나 compile된 코드는 좀 긴것 같아서 byte 수의 증가를 초래하는 듯하다

  - BackboneJS와도 잘 어울린다 


<참조>

posted by Peter Note
2013. 1. 11. 09:52 Languages/Java

1) Korea Spring User Group의 세미나 자료  


1. Spring MVC를 손쉽게 테스트하기 (백기선) : 동영상 , 발표 자료

2. RESTful API(including Mobile) with Spring 3.1 (윤성준) : 동영상발표 자료

3. Spring 3.1에서 Ehcache 활용전략  (김흥래) : 동영상발표 자료

4. SpringFramework in Scala (석종일) : 동영상발표 자료

5. Type-safe querying using Querydsl (김영한) : 동영상발표 자료



2) 내 관심 사항

  - 테스트하기 

  - RESTful API 만들기 

  - Ehcache 활용전략

posted by Peter Note
2012. 12. 27. 17:31 Languages/Java

Java 클래스의 bytecode instrument 프레임워크인 ASM Guide 문서를 읽고 간단히 정리해 보자 


* 참조 파일


> Object Based Model

  - ASM 라이브러리는 컴파일된 클래스의 generating 과 transforming API를 제공한다.

  - DOM(예)의 경우 : event 기반 모델로 클래스를 이벤트 시퀀스로 표현한다. (Event Based Model)

  - ASM의 경우 : object 기반 모델로 클래스를 오브젝트 트리로 표현한다. (Object Based Model)

 

> 구성

  - asm.jar : class parster 와 writer  (core API)

  - asm-util.jar : 개발, 디버깅시에 사용 (core 의존)

  - asm-commons.jar : 미리 정의한 class 변환기 (core 의존)

  - asm-tree.jar : object 표현을 event 표현으로 변환

  - asm-analysis.jar : 미리 정의한 분석기와 분석 프레임워크 (tree 의존)


> Core API

  - class methods, annotations, generics에 대한 generate 과 transform을 Core API 활용하여 어떻게 하는지 알아본다

  - 컴파일된 클래스 구조(Structure) : 간단히 3가지로 나뉨

    + modifier 영역 : public, private

    + field 영역 : modifier, type이나 annotation of a field, name 선언

    + method, constructor 영역 : modifier, name, return, parameter type, annotation of a method

  - 컴파일 클래스와 소스의 차이

    + 소스는 여러 클래스를 포함한다 : inner class

    + 컴파일 클래스는 하나 클래스로 표현하고 comment 제거하고 package, import도 포함하지 않는다. 

    + 컴파일 클래스는 "constant pool"가 있다. constant pool은 배열(Array)이다. 한번만 생성이 도고 index로 참조되어 진다. 

      >>> 컴파일 클래스의 전체 구조

    


    + 컴파일 클래스는 타입표현 명명이 틀리다. internal name 은 클래스의 전체 이름을 사용한다. 

       java/lang/String같이 slash(/)로 구분한다.

    + Internal name은 type에도 적용된다. (type descriptor)

      >>> type descriptor 맵핑

     


    + method descriptor는 type descriptor의 목록이다.

      >>> 메소드 예

    


  - ClassVisitor 추상 클래스가 컴파일된 클래스의 생성/변환을 담당한다. AnnotationVisitor, FieldVisitor, MethodVisitor 리턴

   

  - FieldVisitor 추상 클래스 

   


  - Core API는 ClassVisitor API에 기반하여 클래스 generate 와 transform 할 수 있게 3가지 core 컴포넌트를 제공한다

    + ClassReader : byte array 주어진 컴파일된 클래스를 파싱한다. ClassVisitor를 accept 메소드 파라미터로 주면 

                            visitXxx 메소드를 호출한다 (event producer)

    + ClassWriter : ClassVisitor의 subclass이고 컴파일된 클래스를 바이너리로 만든다. toByteArray메소드롤 얻을 수 있는 

                            byte array로 결과물을 생산한다 (event consumer) 

    + ClassVisitor : 다른 ClassVisitor를 받으면 메소드 호출을 위임한다 (event filter)

posted by Peter Note
2012. 12. 25. 23:55 Languages/Java

그루비도 Closure를 지원한다. 그렇다면 Closure에 대하여 알아보자. (좀 더 정리할 필요가 있겠음)


> 클로저의 가치

  - 함수 객체(function objects) 또는 익명 함수(anonymous function)로서 작용한다.

  - 유형 시스템(type system)이 데이터뿐만 아니라 코드도 나타낼 수 있어야 한다는 점에 유형 시스템에 대한 결과도 갖는다 (음 무슨 말인지 이해안감ㅜㅠ)

  - 함수들을 퍼스트-클래스 객체들로서 지원한다. 

  - 함수들은 변수에 저장될 수 있고, 매개변수로서 다른 함수에 저장된다.

  - 동적으로 생성되고, 함수들에서 리턴된다. 

  - 클러저는 Scheme, Common Lisp, Smalltalk, Groovy, JavaScript, Ruby, Python에서 찾아 볼 수 있다.


<참조>

  - 클로저 논의 IBM 번역

  - JavaScript에서의 클로저

posted by Peter Note
2012. 12. 25. 23:33 Languages/Java

IntelliJ IDE 에서 그루비를 실행하고 테스트해보자. 우선 Eclipse에서 어떻게 수행되는지 동영상을 보고 따라해 보도록 한다. 


> 이클립스에서 그루비 실행하기 

  - 그루비 한글번역 튜토리얼

  - IntelliJ IDE에서 JUnit 4 테스트를 생성하고 구동시키는 방법 



> IntelliJ IDE에서 그루비 생성하고 클래스 테스트하기 


위의 eclipse 기준 동영상을 IntelliJ IDE에 맞추어 테스트 해본다 

1) 새로운 프로젝트 생성

  - New Project 생성

  - step-01 : Java Module 선택


  - step-02 : src 디렉토리 선택

  - step-03 : Groovy 선택 (사전에 Groovy는 설치되어 있어야 한다)


2) 그루비 테스트 하기  

// collection & closure

def coll = ["groovy", "java", "ruby"]  // javascript처럼 컬렉션을 만들 수 있다

assert  coll instanceof Collection // assert 결과가 true이면 다음 문장으로 계속 수행함 

assert coll instanceof ArrayList

println coll.class

println coll


coll << "perl"  // 추가하기 


println coll


coll[4] = 'python'  // 배열처럼 직접 삽입

println coll


println coll - ['java'] // 값 빼기 


// closure 1

coll.each{  value ->    // 파라미터 명을 value로 설정함 

    println '> ' + value

}

// closure 2

def excite = { word ->

    return "${word}!!"

}

assert 'Dowon!!' == excite('Dowon')

println excite('Dowon')


// key=value의 map 객체를 만듦 

def hash = [name:'yun', 'age':27]

assert hash.getClass() == java.util.LinkedHashMap

println hash


hash.height = 177   // key=value 추가하기 

println hash


hash.put('height', 190)  // put 이용

println hash


3) Song 클래스 만들기

// set, get 메소드가 자동으로 만들어 진다. 

// getGenre() 메소드를 재정의한다

class Song {

    def name

    def artist

    def genre


    String toString() {

        "${name}, ${artist}, ${getGenre()}"

    }


    def getGenre() {

        genre.toUpperCase()

    }

}


4) SongExample로 Song 클래스 수행 : ctrl + shift + F10 으로 수행한다 

class SongExample {

    static void main(args) {

       // 생성자는 그루비가 자동으로 생성해 준다 

        Song sng = new Song(name: "tear's heaven", artist: "singer", genre: "rock")

        sng.name = "hi"

        sng.setArtist("dowon")   // set, get 메소드가 이미 있으므로 호출 가능하다 

        println sng


        Song sng2 = new Song()

        // name 지정을 하지 않았으므로 null이다. ?를 하면 null safety 체크한다  

        // 즉 name 이 null 이면 toUpperCase() 를 수행하지 않는다 

        println sng2.name?.toUpperCase()  

    }

}


5)  테스트 코드를 작성한다 : java의 junit 코드로 짜된다 어차피 그루비도 수행시 컴파일 되면 java와 같이 bytecode로 변경된다

  - ctrl + shift + t 클릭하면 "Create New Test..." 메뉴를 선택한다
   


  - JUnit4를 선택하고 OK 클릭한다
   


  - Test 코드를 작성한다 : Groovy 스타일 Test 케이스를 만들 수도 있고, Java 스타일 Test 케이스도 가능하다 (Bi-direction)

import junit.framework.Assert;
import junit.framework.TestCase;
import org.junit.Test;

public class SongTest  {
    @Test
    public void testToString() {
        Song song = new Song();
        song.setName("Smells like teen spirits");
        song.setArtist("youngsik");
        song.setGenre("hard rock");

        Assert.assertEquals("Smells like teen spirits, youngsik, HARD ROCK", song.toString());
    }
}


'Languages > Java' 카테고리의 다른 글

[ASM4] Core API - 01  (0) 2012.12.27
[Groovy] Closure 지원하는 그루비  (0) 2012.12.25
[Groovy] Domain Specific Language 배우기  (0) 2012.12.25
[JVM] Java란 무엇인가?  (0) 2012.11.21
[BeanShell] 설치하고 사용하기  (0) 2012.10.26
posted by Peter Note
2012. 12. 25. 02:04 Languages/Java

Groovy를 통해 많은 생태계가 만들어지고 있다. 그중 Gradle이라는 Build Automation 툴을 사용하려 한다. Groovy의 생태계와 DSL에 대해 알아보자 


> Groovy가 만들고 있는 생태계

  • Grails와 같은 Framework 에 사용
  • Easyb(BDD)와 같은 Testing 에 사용
  • Gradle 과 같은 Build Automation Tool 에 사용
  • 기타등등

> Groovy 기본 개념과 DSL 그리고 생태계

  • Groovy는 Dynamic 언어 (2003년 시작)
  • SpringSource, JBoss 등 많은 오픈소스진영에서 사용중
  • Fully Object-Oriented, Closures, Properties, Optional typing, wrapper APIs, authoring DSLs, lively ecosystem


> Groovy DSL 배우기 


posted by Peter Note
2012. 12. 23. 22:02 Languages/JavaScript

Java의 Spring과 같이 확장성이 높은 JavaScript 프레임워크를 만들기 위한 아키텍쳐에 대하여 알아보자 


  - Module Layer를 두어 모듈 단위로 모든것을 개발한다.

  - SandBox Layer 를 두어 Module이 상호 통신하는 인터페이스와 보안, 가이드 역할을 한다.

  - Core Layer 를 두어 Module의 LifeCycle을 책임진다. 모듈간 통신과 에러 핸들링, 확장을 수행. 

  - Base Library Layer 를 두어 기본 함수와 유틸을 제공한다. : JQuery, YUI 같은 것


> 유지보수 가능한 JavaScript 전략


> 고성능을 내기위한 JavaScript 전략 (Responsive JavaScript 코딩 전략)


  - UI Thread 작업시에는 Queue를 이용하라

  - JavaScript Execution 시간을 50ms 이상으로 하지 마라

  - JavaScript 다운로드하고 파싱하고 실행할때까지 HTML Rendering이 멈춘다. JavaScript은 무조건 HTML 맨 밑에 배치함

  - JavaScript를 쪼개 놓지 말고 합쳐서 다운로드 타임으로 조금이라도 줄여라 

  - 필요한 시점에 동적으로 스크립트 파일을 로딩한다

  - Reflow와 Repaint 횟수를 줄이는 것이 성능 최적화에 중요함

posted by Peter Note
2012. 12. 23. 21:51 Languages/JavaScript

Java에서 할 수 있다면 ECMAScript에서도 할 수 있지 않을까? 테스트를 어떻게 하는지 알아보자 


  - named function을 사용하라 (가급적 anonymous function 사용 배제)

  - namespace를 사용한다

  - 속성, 펑션은 return {key:value} 클로저 객체로 리턴한다

  - 펑션 내부 계산로직에 대해 return 하여 검증할 수 있게 한다

  - Functional Testing

    + gebish.org

    + zombie.labnotes.org

    + phantomjs.org


  - 단위 테스트 

    + QUnit ( docs.jquery.com/QUnit )

    + sinonjs.org

    + mocha

    + JsTestDriver

    + YUITest


> JsTestDriver를 통한 효율적인 JavaScript 테스팅하기



  - JsTestDriver와 Maven 연결 테스트하기

  - JsTestDriver 설정을 통하여 Jenkins에 xUnit Plugin 연동하여 테스트

  - 여러 브라우저에 대하여 테스트하기 

  - http://tddjs.com 참조


> BDD(Behavior Driven Development) JavaScript 


posted by Peter Note
2012. 12. 21. 16:18 Languages/JavaScript

렌더링 과정에 대하여 알아보고, 렌더링시 성능 최적화할 수 있는 방법들을 살펴보자 (책. 4장 렌더링)



▶ 전체 브라우저 렌더링 처리 과정


  - 전체 브라우저 처리과정 : HTML DOM 트리 + CSS 스타일 구조체 = 렌더 트리 생성 (레이아웃 처리) -> 페인트 (화면에 표현)

  - DOM 트리 생성 : HTML을 DOM 요소 노드 트리 형태로 구성.

  - 스타일 구조체 생성 : CSS 정보를 스타일 구조체(Style Struct)로 생성한다. 

  - 렌더 트리 생성 : DOM 트리와 각 노드에 스타일 정보를 설정하여 화면에 표현할 노드로 구성한다. DOM 트리와 렌더 트리는 1:1 대응하지 않는다.

  - 레이아웃 처리 : 렌더 트리의 각 노드 크기가 계산되어 위치계산한다.

  - 페인트(Paint) : 렌더 트리를 순회하면서 페인트 함수를 호출해 노드를 화면에 표현한다.



▶ 리플로와 페인트


  - 리플로(Reflow) : Ajax와 같은 데이터를 가져와서 화면에 뿌릴라 치면 변경이 필요한 렌더 트리에 대한 유효성 확인 작업과 함께 노드의 크기와 위치를 다시 계산한다. 이과정을 리플로 = 레이아웃(Layout) = 레이아웃팅(Layouting)  이라 한다. (부모 노드의 변경은 자식 노드 변경 리플로도 야기한다)

  - 리페인트(Repaint) : 변경 영역의 결과를 표현하기 위해 화면이 업데이트 되는 것을 의미한다. 리페인트 = 리드로(Redraw) 

  - 리플로 와 리페인트는 비용이 높다. 발생하는 원인을 살펴보자 

    + DOM 노드의 변경 : 추가, 삭제

    + DOM 노드 노출 속성을 통한 변경 : 추가, 삭제, 특성 변경

    + 스크립트 애니메이션 : 애니메이션은 DOM, 스타일 등이 짧은 시간에 수차례 변경되는 것임

    + 스타일 : 추가, 변경

    + 사용자 액션 : 브라우저 크기 변경, 글꼴 크기 변경등 



▶ 리플로 & 페인트 최소화 방법


  - 작업 그룹핑 : DOM 요소 변경시 같은 형태끼리 그룹으로 묶어서 실행한다. 

  - 실행 사이클 : 루핑 구문 즉 setTimeOut같은 구문에서 DOM 요소 핸들링을 배제한다.

  - display 속성 : 루핑이 어쩔 수 없다면 

element.style.display="none"; 

<looping구문> 

element.style.display="block";  


  - 이렇게 하면 루핑구문에서 "리플로+페인트"가 계속 발생하지 않고, none과 block 할때 딱 두번만 발생한다.

  - 노드 복제 : 루핑도는 구문에서 노드 핸들링시 원복 노드를 복제하여 사용함 

var clone = element.cloneNode(true);

<looping 구문>

parentNode.replaceChild(clone, element);


  - createDocumentFragment() 사용 : DOM 객체와 별개의 새로운 DOM 객체를 생성하여 사용하면 렌더링 성능 향상 가능함.

var fragment = document.createDocumentFragment(); 

<looping 구문안에서 fragment.appendChile(elems[e]); 호출 > 


  - 캐싱 : 별도의 변수에 자주 사용하는 속성값 또는 메소드값을 저장하여 사용한다. 

  - 하드웨어 가속 렌더링 : GPU를 이용한다. 브라우져 마다 설정값이 틀림. (크롬 :  chrome://flags 로 GPU 설정 확인 가능)


posted by Peter Note
2012. 12. 13. 16:48 Languages/JavaScript

NHN의 자바스크립트 성능 이야기 Chapter 3을 간략히 정리한다. jsMatch 도구를 통한 성능 측정 수치를 제공하여 신뢰를 준다.



▶ 성능우위 문법


  - 배열 생성시 : var arr = new Array(); 보다 var arr = []; 를 사용한다

  - 배열 접근시 : arr.push(i) 보다 arr[i] = value 를 사용한다

  - 객체 생성시 : var obj = new Object(); 보다 var obj = {}; 를 사용한다

  - 객체 접근시 : obj["a"] = 1 보다 obj.a = 1; 를 사용한다 

  - 문자열 생성시 : var str = new String("aaa"); 보다 var str = "aaa"; 를 사용한다 

  - 문자열 연산시 : loop문에서 문자열 조작시에 str += "test"; 보다 arr=[]; loop{ arr[i]="test"; } arr.join(""); 을 사용한다 (String과 StringBuffer개념과 유사)

  - 정규표현식 : 탐색 대상을 축소한다. loop 문 안에 정규표현식 넣지 말고 밖에 놓아 한번만 컴파일 처리되게 한다. loop문에 있으면 계속 컴파일됨 



▶ 스코프 체인 탐색 줄이기

  - 스코프 체인 : 탐색 성능을 높이는 것이 본질 (자바스크립트 실행성능 저하는 변수, 객체, 함수의 메모리상 위치 탐색 작업임)

  - 스코프 체인 구성 = 활성화 객체(Activate Object) + 전역 객체(Global Object)

  - 활성화 객체 : 함수 내부 접근시 생성 (지역변수, this, arguments 객체) -> 함수 빠져 나오면 활성화 객체 제거 됨 

  - 실행 문맥(Execution Context) -> 스코프 체인 (1, 2) -> 활성화 객체 (1) -> 전역 객체 (2) 로 프로그램 수행됨 

  - 함수가 전역 속성 참조 순서 : 실행문맥 > 스코프 체인 > 활성화 객체 (함수) > 스코프 체인 > 전역 객체의 속성 참조 

  - 활성화 객체에서 전역 변수 사용시 : 함수 내부에 var LocalVariable = GlobalVariable;  식을 첨부 (전역속성 탐색을 제거함)



▶ 프로토타입 체인 탐색 줄이기

  - new 연산자로 생성된 인스턴스 객체는 생성자의 프로토타입을 참조하게 된다

  - var obj = new Object(); obj는 Object의 프로토타입 속성에 접근 할 수 있다

  - 자신의 객체만 접근하고 할 경우는 hasOwnProperty를 이요한다 (추가)



▶ 반복문 & 조건문


  - for~in 문은 가급적 쓰지 말라

  - for(~) 문안에 Array.length 구하는 함수등을 호출하지 말고, 외부에서 var length = Array.length를 설정한다. 스코프체인의 활성화 객체를 찾아가는 탐색 경로를 거치게 되므로 응답성능이 느려진다. 

  - 조건절을 빠른 탐색을 위한 알고리즘을 적절히 적용한다 : quick-sort, merge-sort, breadth first search, depth first search등 

posted by Peter Note
2012. 12. 12. 18:01 Languages/JavaScript

웹에플리케이션을 개발할 때 JavaScript 와 CSS 사용이 많다. 특히 요즘음 JavaScript Module화 패턴을 이용하여 JS파일이 기하 급수적으로 늘어나고 있으므로 네트워크 비용을 줄여야하는 문제에 놓인다. 성능을 향상 시킬 수 있는 NHN의 비법을 요약한다. (Chapter 2. 기본적인 웹사이트 최적화 방법)


  - 이미지 파일이 많을 경우 -> CSS Sprite를 이용한다 (N-MET OSS 이용)

    + 성능에 전송 파일의 사이즈보다 개수가 중요하다. 이는 크기보다 네트워크 전송 비용이 더 크기때문이다 

  - HTTP 헤더에 정적 파일 만료날짜를 추가 -> Client PC에 Caching토록 한다 

    + 캐싱여부 판단 기준은 "이름"과 "인터넷 주소" : src="aa_20111231.js" or src="aa.js?20111231" 로 표현 

    + 만료날짜를 서버에 설정 : Apache의 mod_expires 모듈 설정

  - JavaScript 파일 통합 -> 파일의 개수를 최소화하여 네트워크 비용을 줄임

  - 파일 크기 최소화 -> Gzip압축을 사용한다 (파일크기 1~2KB 이상일 때 압축 권장. 이보다 크기가 작으면 압축해제시 CPU 비용이 더 큼)

  - 쿠키 크기 최소화 -> 헤더 정보에 쿠키가 들어가면 데이터 크기가 커진다

    + 사용하지 않는 쿠키 삭제

    + 최상위 도메인 설정 되도록 사용하지 말자

    + 만료날짜 최대한 짧게 한다

    + 쿠키 정보 필요없는 정적 파일(이미지, js, css)는 별도 도메인으로 서비스한다

  - 렌더링 성능 향상 -> DOM Tree - Render Tree - 좌표 배치 - 브라우져 화면 그리기 시작

    + CSS는 <head> </head> 사이에 넣는다 

    + JavaScript는 </body> 위에 넣는다 : js 수행시 렌더링이 멈추어 하얀 페이지 보일 수 있음

    + 최초 페이지에서 AJAX 통신하면 화면 렌더링이 두번 되므로 최초 호출시 AJAX 배제하자 

    + 태그 중첩을 최소화 한다 : <table> 되도록 쓰지 말고, <div>와 CSS로 Layout을 잡는다 (중첩이 많으면 렌더링 느려짐)

posted by Peter Note
2012. 11. 27. 16:54 Languages

Apache, PHP, MySQL을 가장 편하게 설치할 수 있는 방법을 제공하는 사이트 소개


  - APM 일반사항을 설치 : start, stop UI 제공

  - HongPD : 문서파일 검색 사이트 구축

  - WowIP : wifi 환경의 유동아피를 고정아이피화하여 내 PC를 서버로 만들 수 있게 해줌 


설정 관련 부분을 bitnami 처럼 패키징화하여 install wizard를 통하여 설치토록 해준다. Go~~~~od!


'Languages' 카테고리의 다른 글

[문서화 도구] Groc 사용하기  (0) 2013.03.09
posted by Peter Note
2012. 11. 26. 18:07 Languages/JavaScript

서버단에서 페이지별로 사용하는 템플릿 엔진들(FreeMaker, Velocity) 같은것이 있다면 클라이언트 화면단에서 AJAX를 통하여 받는 데이터를 통해 화면을 변경시켜주는 템플릿 엔진도 있다. JQuery에 jquery template 엔진(소개)이 있지만, 다른 것도 검토해 볼 필요가 있겠다. 


  - 추천 javascript template engine 

    + Pure : loop 단점 존재 

    + TrimPath : google code project (강력 추천)

  - 더 극적으로 socketstream을 이용하여 HTML rendering 방법 : Node.js에서 구동되는 bi-direction 통신가능 (GitHub 설명


Single Page Application(wikipedia)을 만들기 위해서는 javascript template engine이 필수 일듯 하다. 


posted by Peter Note
2012. 11. 21. 15:12 Languages/Java

Java란 무엇인가? 그 본질은 무엇인가라는 궁금증에 대하여 심도있고, 상세한 설명과 함께 쓰여진 블로깅이 있어서 링크한다. 엑셈의 WAS성능 관리 솔루션을 만드는 분이 아닐까 추측을 해본다. 


[JVM Internal]Java Performance Fundamental 교재를 공유합니다.

  - JVM = Runtime Data Area + Execution Engine + ClassLoader + Garbage Collection + Native Code (JVM 위키피디아)

  - Runtime Data Area = Java Stack(Frame Data = Operand Stack + Local Variable) + Method Area + Method Area

    + istore : Operand Stack -> Local Variable

    + iload : Local Variable -> Operand Stack

  - ClassLoader = Bootstrap (rt.jar) + Extension (jdk/ext directory) + System ClassLoader (application)

  - ClassLoader Work = Loading -> Linking -> Initializing

  - Execution Engine : byte code를 interpreting 하여 수행

    + JIT (Just In Time) Compiler : 많이 수행되는 것 일부를 Native Code로 Compile 하여 수행

    + HotSpot Compiler = Client or Server Compiler

      + Profile을 이용하여  Native Code Compiler 코드를 결정

      + Native -> Interpet로 돌아갈 수도 있음



> JVM 과 JavaScript Engine의 차이


posted by Peter Note
2012. 11. 12. 16:26 Languages/JavaScript

JavaScript를 하면서 어려웠던 새로운 개념이 Closure이다. 이참에 조금 정리해 보도록 하자 


▶ Closure 개념

  - 로컬 변수를 참조하고 있는 함수 내의 함수 (JavaScript 마스터북, Jpub출판, p180)

  - 즉, 클로저는 자신의 범위(Scope) 밖에 있는 변수들에 접근할 수 있는 함수를 의미한다 

  - inner function을 return 할때 closure가 된다 (원문)

function outerFn() {

var count=1;

return function (cnt) {

      count += cnt;

console.log(count);

}

}


var func = outerFn();

func(10); // 결과 값 11

func(10); // 결과 값 21

  1) func가 closure가 됨 : 내부 변수들 closure, private 변수 생성됨

  2) func(parameter) 호출해 줘도 내부 변수들은 다시 생성되는 것이 아니라 상태를 유지시켜서 참조 됨 

  3) 즉, 클로저가 만들어 지면서 내부 변수들은 별도로 유지되면서 상태값을 유지함

  4) 클로저의 참조를 제거하고 GC할려면 명시적으로 func=null; 함



다른 예제를 보자 
예) closure가 아님 
function foo(x) {
  var tmp = 3;
  function bar(y) {
    console.log(x + y + (++tmp));
  }
  bar(10);
}
foo(2); // 결과 값 16
foo(2); // 결과 값 16
foo(2); // 결과 값 16

예) closure 임
function foo(x) {
  var tmp = 3;
  return function (y) {
    console.log(x + y + (++tmp));
  }
}
var bar = foo(2); // bar is now a closure.
bar(10); // 결과 값 16
bar(10); // 결과 값 17
bar(10); // 결과 값 18

var bar2 = foo(2);
bar2(10); // 결과 값 16
bar2(10); // 결과 값 17

  - 로컬 변수를 계속 생성하지 않고 상태를 유지하면 사용할 수 있다 (마치 객체처럼 var bar2 = foo(2); 하면 또 다른 closure가 생성되면서 bar와 별도의 상태공유 변수 x와 tmp가 생성된다. 마치 클래스에서 객체생성하는 것 처럼 된다. closure 생성시에 arguement와 var로 선언된 variable 에 대한 참조가 가능해 진다. 결국 참조자들-x, tmp-가 일정 메모리에 저장되어 상태를 유지한다)


  - 위의 예에서 var bar = foo(2);를 하는 순간 foo function 객체의 x, tmp 변수의 레퍼런스를 closure 가 가진다 (즉, x, tmp 에 대한 변수 상태값이 유지되고, y 값은 bar(10)을 호출할 때 넘겨주는 값이 된다)


  - 클로저는 간단한 객체이다 (엄밀히 따져서 객체는 아니지만 객체식으로 치환해서 살펴보면 다음과 같다)

    + 클로저 : 객체 = 클로저를 감싸고 있는 부모 함수 foo : 생성자

    + 클로저 : 객체 = 클로저로 부터 참조되는 로컬 변수 tmp :  프로퍼티

    + 클로저 : 객체 = 클로저 자신 bar, bar2 : 메소드

    + 클로저 : 객체 = var bar = foo(2) 함수 호출 : 인스턴스화

    + 클로저 : 객체 = 클로저를 대입하는 변수 bar(10), bar2(10) : 인스턴스 <-- 요거 애매함


  - function 내부에 for문을 돌면서 function을 호출하여 callback 을 셋팅하는 오류 제거 (원문1, 원문2)


실제 사용해 보면서 좀 더 이해를 해나가야 겠다. JavaScript Master북의 글이 좀 더 쉽게 이해가 가니, 햇갈릴 때 책을 다시 정독해 보자. 


<참조>

  - 소스니 코브 : Closure 이해하기

  - Closure 정리 : 한글이라 이해하기 쉬울것임

  - Inside.JS : 한글 정리 예제 포함

posted by Peter Note
2012. 11. 12. 11:34 Languages/JavaScript

자바스크립트의 Function에는 Expression (FE) 과 Declaration (FD) 가 있다고 한다. 이에 대한 차이를 연구해 보자. 우선 존경해 맞이하는 소스니코브의 정리 내역과 구글링한 사이트를 읽고 정리한다 



▶ Function Declaration


  - 변수 할당 없는 이름있는 함수를 정의

  - "var"로 시작하지 않고 "function"으로 시작해야 한다(must)

- 명확한 이름을 가져야 한다
- 소스코드중에 오고 function body를 가지면 다른 function 안에도 위치한다
- entering the context stage에서 생성된다 (즉, function 안에 FD 존재않음)
- variable object(VO)에 영향을 준다 
function bar() {
return 3;

}


or


// 1) directly int the global context

function globalFD() {

// inside the body of another function

function innerFD() {}

}




▶ Function Expression


  - 변수 할당이 있는 표현식으로서 함수를 정의

  - 이름있는 또는 익명(anonymous) 함수 가능

  - FE는 "function"으로 시작하지 않아야 한다(must)

- 소스중에 expression position에 정의된다 
- 함수명은 optional 이다 
- variable object(VO)에 저장되지 않는다 
- code execution stage에서 생성된다 
// anonymous function expression
var a = function() {
return 3;
}

// named function expression
var a = function bar() {
return 3;
}

//self invoking function expression or immediately invoked function expression (IIFE, 즉시실행함수)
(function sayHello() {
alert("dowon hi");
})();

// in parentheses (grouping operator) can be only an expression
(function foo() {});

// in the array initialiser - also only expressions
[function bar() {}];

// comma also operators with expressions
1, function baz() {};


// FE is not available neither before the defintion

// because it is created at code execution phase.

alert(foo); // foo is not defined

(function foo() {});

// nor after, because it is not in the VO

alert(foo); // foo is not defined


// parentheses로 grouping 하기 

(function {}) ();

(function {}());


* Name Fuction Expression (NFE)

  - 재귀 호출을 위해 이름으로 자기자신을 호출할 수 있다 (이때 함수를 Variable Object에 저장할 필요가 있을까? 없다!)

  - 부모 context에서 생성할까? 노우!

  - FE로 하면 VO에 영향을 미치지 않는다 

(function foo(bar) {
if(bar) {
return;
}
foo(true); //foo name is available
})();

// but from the outside, correctly, is not  
// 즉, foo는 부모 scope에 없고 function의 [[Scope]]안에 specialObject에 저장한다 (하기 설명 참조)
foo(); // foo is not defined


위 소스 해석 (원문)

  - Interpreter가 code execution stage에서 FE를 만나면 FE를 생성하기 전에 special object를 만들고 현재 scope chain 앞에 놓는다 

  - FE 자신을 생성하고, 자신의 scope 프로퍼티에 scope chain 을 한다 (referencing)

  - special object에 unique 프로퍼티로 FE를 추가한다

  - 마지막에 parent scope chain으로 부터 special object를 제거 한다 

specialObject = {};

Scope = specialObject + Scope;

foo = new FunctionExpression;
foo.__scope__ = Scope;  // or foo.[[Scope]] = Scope;
specialObject.foo = foo; // [DontDelete], {ReadOnly}

delete Scope[0]; // remove specialObject from the front of scope chain



* FE의 특징

  - Variable Object (VO)에 속하지 않다 (스크립트 수행시 Execution Context-EC- 에 한 부분 = VO)

  - 따라서 FE는 Hoist안되고 FD만 Hoist 된다 (원문)

  - 그리고 FE는 자신의 내부 Scope에만 의미가 있지 외부(Outside)에는 의미가 전혀 없다 

  - VO = Function Declaration + Variable Declaration(var) + Arguments 들이 속한다 (FD가 최우선 순위 -> VD 순서로 Hoist됨)

  - FE로 하면 VO를 오염시키지 않기에 사용이 늘어나고 있다

예1)

bar(); // hoist 되어 정상 처리됨 

foo(); // error 발생 


function bar() { .... } // FD 

var foo = function() { .... }; // FE


예2)

var myFunction = function sameFunction() {

return myFunction === sameFunction; // true

};

console.log(myFunction()); // true 

console.log(sameFunction());  // [ReferenceError: contents is not defined] 에러 발생 



* FE에 사용하는 Grouping Operator 와 Immediately Invoked Fuction Expression (IIFE) 특징 

  - Grouping Operator인 () 은 variable과 function을 global scope와 격리된 private scope로 만드는 방법을 제공한다

  - IIFE는 jQuery, Underscore, Prototype, Dojo 등에서 global  scope을 깔끔하게 유지키 위해 private scope로 캡슐화, 모듈화에 중요하게 사용된다

  - 하기 예제는 외부세계로 부터 숨겨진 코드를 정의할 수 있고, private scope에서 동작하는 library variable을 만드는 것이다.

var Box = (function () {
    var contents = [];
    return {
        insert: function (thing) {
            contents.push(thing);
            return this;
        },
        count: function () {
            return contents.length;
        }
    };
})();

console.log(Box.insert('abc').insert(123).insert({
    width: 640, height: 360
}).insert(function () {
    return 'Hello!';
}).count()); // 4 를 출력

// This throws a ReferenceError since the JavaScript engine can't
// resolve the `contents` identifier.
// [ReferenceError: contents is not defined] 를 출력 
try {
    console.log(contents);  
} catch(err) { 
    console.log(err); 


  - IIFE는 function 호출처럼 arguements를 받고, 실행시간에 in-scope에 있는 모든 데이터에 대한 access가 가능한 Closure를 반환할 수 있다 (variable 상태 저장 가능)

var d, Saved, testSubject, i, l, x;

// Capture a start time.
d = new Date().getTime();

// `Saved` exposes a single API method `get` which returns that
// start time: the variable `d` is supplied as the argument
// identified within the function definition as `start`.
// 최기의  시작시간값을 저장하고 있다 
Saved = (function (start) {
    return {
        get: function () {
            return start;
        }
    };
})(d);

testSubject = {
    level1: {
        level2: {
            level3: {
                level4: {
                    val: 'value'
                }
            }
        }
    }
};

for (i = 0, l = 1000000; i < l; i++) {
    x = testSubject.level1.level2.level3.level4.val;
}

// Capture the time after diving five levels into the `testSubject`
// object literal one million times.
// 현재 시간을 구한다 
d = new Date().getTime();

// Output the current value of `d`.
// 현재 시간이 찍힘 
console.log(d); 

// Output the original value of `d`.
// 초기 IIFE의 시간이 찍힘
console.log(Saved.get());

// Output the difference which indicates how many seconds it took
// to do that object crawl.
console.log(d - Saved.get());

//------ 결과 
1352699019341 // d 현재 시간 
1352699019322 // Saved.get() IIFE 시간 
19  // 차이 값 



<참조>

  - javascript 블로그 : 간단하고 명확하게 정의내림 (표현형식만 설명)

  - 소스니 코브 : 너무 심도 있게 설명해서 집중하지 않으면 놓치기 쉬움 (왜 구별해서 사용하는지 설명)

  - 예제로 보는 javascript : Function Expression을 사용하는 이유를 가장 잘 설명함

'Languages > JavaScript' 카테고리의 다른 글

[JavaScript 성능향상] 웹사이트 최적화 방법  (0) 2012.12.12
[JavaScript] Template Engine  (0) 2012.11.26
[JavaScript] Closure 알아가기  (0) 2012.11.12
[JavaScript] Core 요약  (0) 2012.10.12
[JavaScript] Design Pattern  (0) 2012.09.10
posted by Peter Note
2012. 10. 26. 14:53 Languages/Java

BeanShell은 java syntax로 짠 script의 랭귀지 인터프리터이다. 

사이트 : http://www.beanshell.org 


▶ BeanShell 설치


  - 먼저 bsh-xxx.jar 파일을 다운로드 받는다

  - 윈도우라면 classpath 경로에 추가한다  

       


  - BeanShell은 GUI 또는 Command Line에서 수행할 수 있다

   + java bsh.Console : GUI

      


    + java bsh.Interpreter : text only command line

     


    + java bsh.Interpreter filename [args] : run script file


  - BeanShell은 일반 java appliction에서 호출 할 수도 있다 (application에서 bsh.Interpreter를 new 해서 호출)

  - BeanShell GUI 에서 loose type 으로 자바 코딩하듯이 짜면 된다. ( print()는 System.out.println()의 bsh 내장 함수)

    


  - 좀 더 자세한 사용자 메뉴얼 : http://www.beanshell.org/manual/bshmanual.htm 참조

  - default import 구문

    + javax.swing.event

    + javax.swing

    + java.awt.event

    + java.awt

    + java.net

    + java.util

    + java.io

    + java.lang


  - BeanShell 동작 방식

    + standalone 모드 : java bsh.Interpreter [filename] [arg..]

     

    + remote 모드 : java bsh.Remote [HTTP 또는 bsh URL] 

   



▶ BeanShell 을 Remote Server에서 접속하여 사용하기 

  - Remote Server Mode 흐름도 : 웹브라우져에서 접속하거나, Telnet 접속이 가능하다. 또는 Servlet 코드에서 접속도 가능하다

   


  - 웹브라우져 접속방법

    + 내 BeanShell이 있는 곳에서 내장함수 server(portNum); 수행

      

    

    + 불여우(FireFox)에서 http://<주소>:<portNum>/remote/jconsole.html 로 접속한다 (주의 : 브라우져에서 여러개 bsh console을 열어서 작업을 할 수 있으나 global session이어서 서로 share된다)

     


  - telnet 접속 : telnet <myhost> <port+1>  여기서는 "telnet localhost 8082"
    


  - 그외 BshServlet을 통한 호출도 가능 하다. 

  

▶ BeanShell 사용하는 곳


  - JMeter에서 BeanShell 적용하기 : http://nezah.egloos.com/4336838

  - Eclispe에 BeanShell적용하기 : http://blog.sangpire.pe.kr/69

  - 기타 기초적인 것은 구글링~~~ (구글 이자식들 독도명 지도에서 삭제해가지고 열받는 중. SW 주권을 찾을 때다)


posted by Peter Note
2012. 10. 12. 17:45 Languages/JavaScript

드미트리 소스니코브의 JavaScript Core에 대한 내용을 간략히 요약해 보자. 




▶ 오브젝트 (객체, An Object)

  - 오브젝트는 한개의 프로토타입 오브젝트를 가지고 있으면서 프로퍼티들의 집합이다. 

  - 오브젝트의 프로토타입은 내부 [[Prototype]] 프로퍼티에 의해 참조된다.

  - [[Prototype]] 보다는 __<internal-property>__ 를 사용하나, 특별히 프로토타입 오브젝트는 __proto__ 프로퍼티 변수로 표시한다.


예)

  var foo={

          x: 10,

          y: 20

   }

   해당 객체에는 3개의 프로퍼티가 존재하게 된다.

 



▶ 프로토타입 체인


  - 프로토타입 체인은 상속/공유되는 프로퍼티들의 구현에 사용되는 객체들의 유한 연결이다. 

  - ECMAScript는 자바와 같은 일반적인 class-based 상속이 아니라 prototype chain을 통하여 상속은 한다. 이를 위임형 상속(delegation based inheritance) 또는 프로토타입형 상속(prototype based inheritance)이라 한다. 

  - 이는 ECMAScript에는 class라는 개념이 없기 때문이다. 속성(프로퍼티)/메소드등을 동적으로 할당할 수 있기 때문에 class정의 자체가 필요없음

  - 예로 b, c의 공통영역에 a 객체를 저장하면, b, c는 자신에게 추가적인 프로퍼티와 메소드를 저장할 수 있는 것이다.  


  - b가 calculate 메소드를 찾아가는 방법 : b 객체안에 메소드가 없을 경우, prototype chain을 거쳐서 찾는다. 메소드를 찾는다. 찾지 못할 경우 undefined 값이 리턴된다.  (최상위 오브젝트 Object.prototype 값은 null 이다.) 

  - 주의 할것중 상속하여 사용시 this는 원래 객체를 가르킨다. 

  - 예로 this가 가르키는 객체로 this.y 는 b, c 객체이고, this.x는 a 객체를 가르킨다.  



▶ 생성자 (Constructor)


  - 생성자를 통해 객체를 생성시 유용한 것들이 있다. 

생성자를 사용하면 펑션의 prototype 프로퍼티가 <생성자 함수명칭>.prototype 객체를 가르킨다.  (그림 3.A)

예로 constructor function을 사용하여 b, c에 생성한 객체의 주소를 할당하면 b, c의 __proto__는 Foo.prototype 객체를 참조하게 된다. Foo.prototype 객체의 constructor는 원형의 constructor function 인 Foo를 가르키게 된다.

* 참조 : 자바스크립트의 new 의미 (http://zero.diebuster.com/zero/?p=36)



그림으로 그리면 다음과 같다 


  - Foo 자신의 __proto__는 Function.prototype 을 갖는다. 

  - Foo.prototype 오브젝트의 constructor는 자동 생성되어 Foo를 참조한다

  - Foo.prototype은 b, c 오브젝트의 prototype에 참조되는 Foo의 프로퍼티이다. (프로퍼티에 .x .calculate가 붙으면서 별도 객체가 되었다)


▶ Execution Context Stack

  - runtime program execution에 대해서 알려면 ECMAScript의 실행컨텍스트스택의 동작방식을 알아야 한다 

  - 3가지 타입 존재 : global code, function code, eval code 

  - 3가지 code는 execution context 인스턴스안에서 검증되어 진다. 

  - global context는 1개만 있고, function과 eval execution context들이 여러개 있게 된다. 만일 function이 호출되면 function execution context안으로 들어가 function code가 검증되어 진다. eval function은 특별히 eval execution context안에 들어서 eval code를 검증한다.  

  - Execution Context(EC)는 Stack에 담겨서 EC1 -> EC2 로 호출할 때마다 자기자신은 caller와 callee가 되어 코드 끝까지 수행이 되는 것이다. 

  글로벌 EC가 최소 caller가 되어 다음 foo(10) EC callee를 활성화 하고, foo(10) EC가 caller 되어 foo(20) EC callee를 활성화 하는 식으로 옮겨가는 구조를 Stack안에 구현되어 수행되는 것이다. 이른 execution context stack이라 한다. 


  - ECMAScript의 코드 동작방식에서 Global EC는 하나가 생성되어 있고, 펑션 EC는 Stack이 넣어져서 수행되고 완료되면 다시 Stack에서 빠지게 된다. 

  - 모든 EC를 Object로 간주되고, EC안의 code를 수행하는 주체가 된다. 



▶ Execution Context


  - EC는 context상태를 저장하기 위한 프로퍼티와 관련 코드 수행 경로 추적을 위한 프로퍼티등을 가지고 있는 단순 객체(오브젝트)이다.  

  - Variable Object (VO)는 EC와 관련된 scope of data 이다. (A variable object is a scope of data related with the execution context.)

  - 변수(variable)과 펑션선언(function declaration)을 저장한다. function expression은 저장하지 않는다. 



baz는 function expression이어서 Global Variable Object 에 저장되지 않는다. 


  - Activation Object (AO)는 Function context에서의 Variable Object이다. 

  - caller에 의해 function context가 활성화 되면 activation object가 생성되고 function이 호출된다. 

  - 호출시에 arguments객체-indexed map-에 파라미터 값를 담아서 넘겨준다.

  - activation object도 variable object이므로 variable, function declaration, 일반 파라미터, arguments 객체를 저장한다. 




▶ Scope Chain


  - 스코프 체인은 컨텍스트의 코드를 표현하는 식별자(identifiers)를 찾기위한 오브젝트 목록이다. (A scope chain is a list of objects that are searched for identifiers appear in the code of the context)

  - 규칙인 prototype chain과 동일하다. 

  - 즉, 자신의 스코프에서 variable/activation object를 못찾으면 부모의 VO/AO를 찾는다.

  - 스코프 체인은 일반적으로 부모 VO들의 목록(list)이다. 

  - context입장에서 식별자는 variable, function declaration, formal parameter들의 명칭이다. 


  - scope chain은 __parent__ 내장 프로퍼티로 연결된다. 또는 [[Scope]]로 나타내기도 한다.

이를 통해서 내부의 펑션이 외부의 변수 값을 참조할 수 있게 된다. 

반대로 만일 내부 펑션이 외부로 리턴되어 부모가 해당 펑션을 활성화하여 VO를 사용한다면 어떻게 될까? 요건 Closure 에서...




▶ Closure


  - ECMAScript에서 펑션은 일급 객체이다. (function is the first-class object)

  - 이말은 function을 다른 function에 argument로 전달 할수 있다는 것이다. - funargs- functional arguments라고 함

  - 또한 function을 리턴 할 수도 있다. functional value 라고 한다. 

  - funarg 문제는 closure 개념으로 풀어간다. 

  - Closure는 좀 더 상세하게 다른 쳅터에서 다룬다. 


▶ This 

  - This 값은 execution context와 관련을 맺는 특별한 오브젝트이다. 그래서 context object라고 불릴 수도 있다. 

  - 즉, an object which context the execution context is activated. 

  - this 값은 execution context의 프로퍼티이지 VO의 프로퍼티가 아니다. ( a this value is a property of the execution context, but not a property of the variable object.). 즉, this는 scope chain에 참여하지 않는다. look up 대상이 아니라는 것이다.

  - this 값은 caller에 의하여 제공받는다. 즉 EC1 -> EC2를 호출할때 EC1이 caller가 도고 EC2안에 this가 있다면 EC1의 오브젝트가 되는 것이다. 

  - 좀 더 자세한 사항은 다른 쳅터에서 다룬다. 


posted by Peter Note
prev 1 2 3 next