'전체'에 해당되는 글 35건

  1. 2010/08/25 HTTP Cache 관련 정리해둔거 (작성자: azki)
  2. 2010/05/19 Git 사용기 (windows 환경에서 GIT-GUI 와 github.com 을 중점으로) (3)
  3. 2010/04/25 탱크 게임 업데이트. (AI 부분 구현 및 UI 개선)
  4. 2010/04/20 canvas 와 excanvas 를 이용하여 만들어보고 있는 탱크 게임 (클라이언트 부분)
  5. 2010/04/20 iPhone Safari 브라우저 기능 레퍼런스 및 뷰포트 설정.
  6. 2010/04/20 env.js 사용시 부족한 부분 수정
  7. 2010/03/22 Rhino 와 env.js 를 사용해서 자바 서버에서 javascript 를 구동해보자.
  8. 2009/03/16 Java (J2SE 5.0) and C# Comparison
  9. 2009/03/16 [펌] C# I/O와 네트워킹 by Raffi Krikorian
  10. 2009/03/16 [펌] Free unix timestamp and epoch conversion tool
  11. 2009/02/06 SourceSafe Error 'Cannot find SS.INI for user'
  12. 2009/01/19 [ATA] UX
  13. 2009/01/16 What is false in javascript?
  14. 2008/12/01 apply Style Sheet rules
  15. 2008/11/28 [ATA] 기획 참고 정보들
  16. 2008/11/18 javascript 막코딩으로 flip 효과 시도 (뒤집는 효과)
  17. 2008/11/06 [ATA] 통신 소켓 생각들
  18. 2008/10/30 자바스크립트로 마우스 휠 (mousewheel) 움직임 체크.
  19. 2008/07/18 prototype의 constructor에 대한 질문. (왜 저장해뒀지?)
  20. 2008/07/02 JSON 2 Table v 1.01 제이슨 데이타를 테이블로 출력합니다
  21. 2008/06/10 input type 변경의 크로스 브라우저 문제 (password)
  22. 2008/05/26 <button> 엘리멘트의 크로스 브라우징 문제 (1)
  23. 2008/05/21 JavaScript 에서 style 속성 구하기
  24. 2008/05/14 JavaScript Eval 함수의 IE에서 사용 주의점
  25. 2008/05/14 JavaScript 배열 변수 메소드 정리
  26. 2008/05/14 User preferences color table v 1.0
  27. 2008/05/14 JPT v 1.0 자바스크립트 코드 포퍼먼스 테스터 (JavaScript code Performance Tester)
  28. 2008/05/14 APC (Alternative PHP Cache) 유저 캐시 리스트 (user cache list) - apc_cache_info()
  29. 2008/05/14 [ATA] APC in php.ini
  30. 2008/05/14 [ATA] 준비물
2010/08/25 20:49
정리 테이블 : 

소개 슬라이드 : 

저작권은 azki 에게 있습니다만, 알아서 쓰삼ㅋㅋ
저작자 표시 동일 조건 변경 허락
Posted by 아즈키
2010/05/19 00:27
javascript 관련 오픈 소스를 찾다보면 자주 들리게 되는 github.com 를 써보기로 하고, 사용해 본 결과를 정리한다.


일단 git 에 대해 간략하게 설명하면 다음과 같다.

1. 백과사전:
Git은 프로그램 등의 소스코드 관리를 위한 분산 버전 관리 시스템이다. 리누스 토르발스에 의해 개발되었다.

2. 공식 사이트:
무료 오픈소스인 분산 버전 관리 시스템인데, 작은 프로젝트나 큰 프로젝트나 할 것 없이 속도와 효율성이 있게 처리할 수 있게 설계되어있다고 한다.
모든 Git 클론은 모든 히스토리와 리비전 트래킹 기능을 지닌 완전한 레파지토리인데, 네트워크 억세스나 중앙 서버에 의존하지 않는다고 한다. 브랜칭과 머징이 빠르고 쉽게 된댄다.

3. 그림:
그림 한장에 대부분의 기능이 다 설명 되는듯.
SVN과 다르게 commit이 로컬에서만 이루어지고, 서버에 반영은 push라는 동작으로 이루어 진다는 점이 중요한듯. 서버에서 처음에 모두 받을 때는 pull로 왕 끌여당기고, 그 후로는 fetch와 checkout을 통해 받게 되고, commit 전에 add 라는 작업이 있는 정도.

4. 다른 좋은 글:


일단 목적은 내가 쓰는 환경인 windows 에서 편리하게 사용하는 것. 윈도우즈 관련 툴을 찾아보니 다음과 같은 것이 있었다. 
지금 현재 최신 버전은 1.7.0.2 인데 이 것을 첨부한다.


일단 설치는 쉽다. 계속 넥스트만 눌러주면 된다.



다 하고 나면 아래 처럼 탐색기 오른쪽 버튼 메뉴에 뭔가가 생긴다.


나의 프로젝트를 git를 이용해서 관리할려면 해당 폴더로 가서 Git Init Here 눌러주면 된다(bash로 하는 방법도 있는데, 그건 찾아보면 관련 자료가 많이 나온다. 검색해보시길). 윈도우7에서는 저게 안되니 GIT GUI 를 구동한 다음에 Create New Repository 를 클릭해서 해당 폴더를 선택해주면 된다. 세가지 방법 모두 동일한 작업이다.


init 시켜주면 위와 같이 숨겨진 폴더가 생기고 거기에 레파지토리가 생기는듯.
이제 다시 오른쪽 버튼을 클릭하면 다음과 같이 새로운 메뉴가 뜬다. Add all files now 해보자.


GIT GUI 툴에서는 아래 이미지 처럼 추가가 가능하다. Rescan 눌러서 스캔한 다음에 Commit 메뉴안의 Stage To Commit 누르면 동일한 작업이 가능하다. 윈도우7 환경에서는 두번째 방법으로만 가능하다.


윈도우XP에서는 GIT GUI를 아래 처럼 쉽게 띄울 수 있다(Git Commit Tool 클릭).


요기까지 했다면 아래와 같은 화면이..


커밋 메시지를 대충 적고 Commit 버튼을 누르면 로컬 레파지토리에 커밋된다.


다시 탐색기에서 오른쪽 버튼을 누르면 Git History 메뉴가 보이게 된다.


Git History 를 눌러서 커밋이 잘 되었는지 확인해 보자.


잘 된듯.
혼자 로컬 레파지토리에서 커밋하고 버전 컨트롤하는 부분은 이걸로 완성.
이제 github.com 을 이용하기 위한 세팅을 해보자.


일단 회원 가입은 알아서..


가입 한 후에는 New Repository 를 눌러 레파지토리를 만들자.



레파지토리는 완성이 된듯. 아래 이미지 중간에 보이는 "git@github.com:azki/simpletank.git" 라는 주소가 읽기/쓰기 접근을 할 수 있는 URL 이다.


다시 툴로 돌아와서 Remote 메뉴의 Add 를 눌러보자.


이름을 아무거나 마음에 드는걸로 대충 적고 아까 그 주소를 적어주자. 스샷에는 azki로 되어있는데 프로젝트 이름을 적는 것이 더 좋을듯하다.
참고로, 내가 해본 결과 저 이름을 한글로 쓰면 나중에 툴에서 문자가 깨져서 오동작하는 부분도 있었다. 왠만하면 저런건 영어로 하는 것이 좋을듯.


그 후 SSH Key 를 만들자. Help 안에 Show SSH Key 를 누르면 된다.


Generate Key 를 누르면 키가 생성되는데, 현재 버전에서는 따로 이메일 주소를 입력할 수 없다. 이메일 주소를 입력하고 키를 발급 받고 싶다면 아래와 같이 Git Bash 를 이용하자. 명령어는
ssh-keygen -C "메일주소" -t rsa
이다.


사용자 폴더안의 .ssh 폴더안에 키값이 저장된다. 내 경우 Win7 이기 때문에 "C:\Users\azki\.ssh" 에 저장되었지만, XP 일 경우 "C:\Documents and Settings\azki\.ssh" 에 저장될 것이다. 나중에 지우고 싶으면 찾아 들어가서 지워버리면 된다.

아무튼 툴에서 보여주는 SSH Key 를 복사하자. 위에서 설명한 경로안의 id_rsa.pub 파일을 텍스트에디터로 열어서 봐도 된다.


키를 github 에 등록하자. 프로젝트 첫 화면에서 상단의 Admin 버튼을 누르면 설정할 수 있는 관리자 화면으로 넘어간다. 그 곳에서 왼쪽 메뉴의 Deploy Keys 를 누르면 아래 처럼 등록할 수 있다. 타이틀은 메일 주소로ㅋ


등록 완료!


이제 다시 툴로 돌아와서 push를 해보자(커밋은 이미 아까 저 위에 위에 위에 위에 위에 위에서 했으니까 바로 푸시!).


아까 Remote의 Add로 추가했던 레파지토리가 보인다. 선택하고 push하자. 등록 안하고 Arbitrary Location으로 URL을 써줘도 되긴함.


push를 누르면 잘 푸시된다. 혹시나 SSH키를 만들 때 passphrase를 입력해놓았다면 암호를 물어보는데 입력해주면 된다.


http://github.com/azki/simpletank 에서 새로고침 해주면 아래 처럼 푸시한 녀석들이 잘 올라가 있는 것을 볼 수 있다.


프로젝트의 루트 폴더에 README 파일을 넣어주면 파일 내용이 화면에 나타나기도 한다. 다만 한글 등을 쓸려면 UTF-8 형식으로 된 파일로 올려야 될듯(아래 처럼 글씨 깨진다).


작성한 사용자를 정확히 표시할려면 툴에서 다음과 같은 설정을 해줘야하는 듯하다. Edit의 Options...


유저 이름과 이메일 어드레스를 넣어주자.


이렇게 유저 설정을 한 다음에 아까 그 README 파일도 UTF-8 형식으로 다시 커밋하고 푸시한 다음에 보면 아래 처럼 매우 잘 나온다. :]


일반적인 사용에 대한 사용기 끝~!


느낀점.
커밋이 로컬에서 이루어지기 때문에 무척 빠르다. 마찬가지로 히스토리 관리나 리버전 따위 작업 역시 엄청난 속도..
특히 이전에 쓰던 SVN의 경우는 내부 네트워크에 놓고 쓸 경우에도 꽤 처리 시간이 걸렸었다. 그리고 외부 서버에 놓고 쓸 경우 엄청난 인내심이 요구되었었다. 예전에 구글에서 제공하는 레파지토리 호스팅(code.google.com/hosting)도 쓸려고 프로젝트를 만들어보고, 네이버 개발센터(dev.naver.com)에서도 프로젝트를 만들어보고 했는데 그걸 못쓰고 버린건 다 그런 이유. 특히 구글은 소스 파일 몇개 커밋 하는데 10초 이상 걸리는 등 엄청나게 느려서 10분 써보고 바로 포기했었다. 일단 이런 면에서 git는 매우 합격이다. 참 좋은 녀석인듯. 앞으로 쫌 많이 활용해야 겠다.

ps.
github의 모토가 원래 "소셜 소스 코드 공유"라는데 그런 부분에 대한 것이나, SVN에 없는 멋진 기능 등을 발견하면 나중에 또 포스팅 하겠음. ㅋㅋ 읽어주신 분들 ㄳ~!

Posted by 아즈키
2010/04/25 18:48
저번에 올렸던 탱크 게임에서 추가적으로 컴퓨터 AI 부분을 구현해 보았다. 플레이어 수, 팀, 컴퓨터 난이도 등의 값이 설정이 가능하나 Ui로는 만들어 놓지 않았음. 이전 글을 참고하실 분은 하세요.
2010/04/20 - [javascript/web] - canvas 와 excanvas 를 이용하여 만들어보고 있는 탱크 게임 (클라이언트 부분)


데모(Demo)


아이폰 세로 해상도 최적화
아이폰 사파리에서 세로 해상도에서 잘보이도록 수정하였다. 이전 버전에서는 아이폰을 가로하였을 때를 기준으로 작성했었는데, 막상 써보니 세로가 더 편한 것 같아서 바꿨다. 바꾸면서 탱크의 HP는 canvas 영역에 원모양으로 넣었다. 호환성 부분은 이전 수준을 유지했다(IE6, IE7, IE8, FF3, Chrome4, Opera10, iPhone Safari 등 주요 브라우저). 아 그리고, 데스크탑에서는 마우스 휠로 파워 조절이 가능하도록 했다. 주로 마우스만으로 각도, 파워 조절하는데 화면 구석에 있으면 파워 조절이 힘들어서.


이동 기능 추가
포탄을 쏘는 것 외에 이동하는 것도 추가했다. 버튼을 클릭하거나, 단축키인 v를 눌러도 된다. 좀 더 쎄거나, 여러발이 나간다거나, 공격 범위가 넓거나 한 강력한 포탄도 넣고 싶은데 버튼 들어갈만한 자리가 없어서 일단 보류. 참고로 컴퓨터 Ai도 가끔씩 이동하게 해놨다. 컴퓨터는 상대가 멀리있고 자신이 공격을 받았을 경우 이동할 확률이 높다.


컴퓨터 AI 추가
혼자 놀기 위해서 컴퓨터 AI를 만들어 추가했다. 데모에서는 사람이 조정하는 동그라미 탱크 3대와 컴퓨터가 조정하는 세모 탱크 3대가 싸우게 해놨다. 난이도는 5 정도의 수치(나한테는 이정도가 쉽지도 않고 어렵지도 않은듯). 난이도는 1 이상으로 정도로 줄 수 있지만, 숫자가 높아질 수록 점점 차이가 없어진다. 1로 설정하면 쉽고, 아마 보통 수준은 3이나 4 정도 일 것 같다.


컴퓨터 AI 구현 방식
AI가 동작하는 기본 방식(Ai01)은 다음과 같다.
1. 목표물 설정.
2. 각도 설정.
3. 파워 설정.
4. 결과 확인.
목표물은 가장 가까운 위치에 있는 상대편을 고르도록 했다. 각도는 목표물과의 사이에 있는 땅의 좌표를 모두 조사하여 그 땅을 넘길 수 있는 최소한의 각도를 구하고, 파워에 따라서 못 넘길 수도 있으므로 약간의 보정치를 더해줬다. 파워는 대충 거리와 각도를 가지고 구하도록 하였다. 중요한 부분은 결과를 Shot 객체에서 콜백으로 받아서 분석하는 부분이다. 발사한 결과 목표물보다 멀리 나갔으면 다음번에 쏠 때 파워를 줄이고, 더 조금 나갔으면 파워를 높이는 방식이다.
이 기본 방식에서 확장시킨 부분(Ai02)이 난이도 조절이 가능한 부분인데, 그 부분은 AI가 자체적으로 시뮬레이션용 Shot 객체를 내장하여 발사전에 결과를 분석한 후 가장 좋은 결과를 발사하도록 구현하였다. 즉, 난이도의 수치에 따라 그 만큼 시뮬레이션을 하여 데이타를 만들어서 그 중에 가장 좋은 결과를 반영하게 된다.


소스(Source)
후기
원래 앞으로의 계획은 AI 추가 따위가 아니였는데, 갑자기 땡겨서 만들어 버렸다 -_-; 만들고 나니 게임 시작전에 팀 설정하는 부분 (유저 수, 컴퓨터 수, 난이도 설정 등)을 넣고 싶어짐.. 그리고 통신 부분도 만들어야 하는데!!! 시간이 없다 ㄱ-
Posted by 아즈키
2010/04/20 18:58
요새는 탱크 게임을 만들어 보고 있다. 목표는 iPhone 에서도 동작 가능한 멀티플레이어 탱크게임이다. 현재 클라이언트 부분의 기본적인 기능을 거의 완료했다.




호환성
excanvas (http://code.google.com/p/explorercanvas/) 를 사용하여 IE 브라우저에서도 동일하게 동작하도록 만들었다. 테스트는 IE6, IE7, IE8, FF2, FF3, Chrome4, iPhone Safari 등에서 했다. iPhone Safari 에서는 할만한데, iPhone Opera Mini 5.0 에서는 너무 느리더라. 아이폰용 viewport 설정(http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html)을 해서 해상도가 유지되도록 설정했다. 사이즈는 아이폰에서 가로보기로 하면 딱 맞도록 하였다.


유저 인터페이스
현재 사용자들에게 주어진 제어권은 각도와 힘의 조절, 그리고 발사다. 각도와 힘을 조절하는 방법은 3가지를 구현했다. 지도위를 마우스 클릭하여 힘과 각도를 조절 가능하며, 오른쪽에 위치한 select 박스를 통해 선택 가능하고, 키보드의 w, a, s, d 키나 화살표키를 사용하여 조절이 가능하다. select 박스를 통해 설정 가능하도록 만든 것은 iPhone 에서 다른 form 구성 요소보다 훨씬 값을 설정하기 쉽기 때문이다. 발사는 키보드의 f 키를 누르거나 오른쪽에 위치한 Shoot 버튼을 클릭하면 이루어진다.


포탄 애니메이션 프레임 문제
포탄 애니메이션은 포물선 운동에서의 x 좌표와 y 좌표의 값을 계속 변경시키는 것으로 구하는데, 일반 데스크탑 환경과 달리 iPhone 등 느린 환경에서는 같은 프레임으로 동작시켰을 경우 5배 이상의 시간이 걸리기도 한다. 그래서 한 프레임에 걸리는 시간을 체크하여, 프레임 수를 줄이는 방식의 코드를 적용하였다. 프레임간의 간격을 5ms 로 하고, 한 프레임을 뿌리는데 걸리는 시간이 현재 프레임 간의 간격의 2배 이상인 경우에는 프레임 간의 간격의 기본 값을 5ms 씩 늘리도록 하였다. 이 방식을 통해 동작이 느린 환경에서 프레임 수를 자동으로 줄이고 포탄이 날라가는 시간을 조절하였다.


한계
excanvas 는 IE 브라우저에서 vml 을 통해 canvas 를 보여주도록 하는 js library 인데, 몇가지 제한가 있다. 특히 text 를 그리는 API 가 호환되지 않는다. 그리고, iPhone Safari 에서도 글씨 위치가 정확하지 않는 등 호환성의 문제가 있었다. 그래서 턴을 나타내는 "TURN:" 이라는 글자를 line 을 이용하여 그렸다. 브라우저 호환이 되는 글자를 표현하는 방법이 따로 없기 때문에 image 나 line, html 등을 이용해야 한다.


전체적인 구조

HTML 의 element 들과 디펜던시가 있는 부분들은 SimpleTank.Ui 클래스가 담당한다. html 의 이벤트를 제어하거나, 내용을 변경하는 부분을 당담한다. 그리고 SimpleTank.Map, SimpleTank.Tanks, SimpleTank.Shot 들은 각각 canvas context 객체를 받아서 각자 맡은 부분을 그린다.

자세한 부분이 궁금한 사람은 코드를 뜯어 보시길..


소스(Source)


앞으로 계획
앞으로 서버 부분을 제작하여 멀티플레이어 온라인 대전이 되도록 서비스를 해볼 생각이다. 항상 느끼는 것이지만, 게임 자체의 구현보다 서비스를 기획하는 부분이 어렵다.
  1. 계정 없이 접속해서 게임을 할 수 있도록 할 것인가? 아니면 Open API 를 이용하여 인증하게 할 것인가? 혹은 회원가입을 받을 것인가?
  2. 유저가 방을 생성하도록 해서 서로 대전이 되도록 할 것인가? 접속자 목록을 보여주고 초대하는 형식으로 대전하도록 할 것인가? 접속시 자동으로 대전 상대들을 찾아 줄 것인가? 여러가지 방식을 동시에 지원해줄 것인가?
  3. 등등.. 여러가지 고민이 앞선다.
그리고 바람 가중치, 랭킹 서비스, 탱크의 모양과 성능의 종류 선택, 포탄, 아이템 등의 구입과 사용 개념 등을 추가할 계획이다.
Posted by 아즈키
2010/04/20 15:41
사파리 브라우저 레퍼런스.

메타 태그.

뷰포트.

좋다. 신난다. 응용 할 것들이 넘쳐나는구나!
Posted by 아즈키
2010/04/20 11:32

env.js 의 몇가지 부족한 점이 있어서 수정한 부분에 대해 포스팅..

원본: 


원본 파일에서 내게 필요했던 부분 (innerHTML) 중에 잘못 구현되어 있거나, 부족했던 부분이 아래와 같이 있어서 수정하였다.
  1. html 에서 inline style 이 나타나지 않는 문제.
  2. 내용이 없는 경우 닫는 태그가 없는 문제.
  3. 결과물 문자열을 만드는 방식이 문자열 변수에 계속 += 연산자를 사용하는 방식이라서 비효율적으로 동작하는 문제(조금 복잡한 DOM을 다루게 되면 innerHTML을 한번 구하는데 1분 이상 걸리는 등 심각한 성능 문제가 나타남).
env.rhino.js 파일의 6404 번째 라인쯤에 있는 xhtml getter 함수를 다음과 같이 수정합니다.

get xhtml() {
// HTMLDocument.xhtml is non-standard
// This is exactly like Document.xml except the tagName has to be 
// lower cased.  I dont like to duplicate this but its really not
// a simple work around between xml and html serialization via
// XMLSerializer (which uppercases html tags) and innerHTML (which
// lowercases tags)
var ret = "",
ns = "",
name = (this.tagName+"").toLowerCase(),
attrs,
attrstring = "",
i,
retArray = [],
childRet;

// serialize namespace declarations
if (this.namespaceURI){
if((this === this.ownerDocument.documentElement) ||
(!this.parentNode)||
(this.parentNode && 
(this.parentNode.namespaceURI !== this.namespaceURI)))
ns = ' xmlns'+(this.prefix?(':'+this.prefix):'')+
'="'+this.namespaceURI+'"';
}
// serialize Attribute declarations
attrs = this.attributes;
for(i=0;i< attrs.length;i++){
attrstring += " "+attrs[i].name+'="'+attrs[i].xml+'"';
}
var _toCamel = function(name) {
if(name){
return name.replace(/\-(\w)/g, function(all, letter){
return letter.toUpperCase();
});
}
return name;
};
if (this.style && this.style.length > 0) {
attrstring += " style=\"";
var so = this.style;
var i, sl = so.length;
for(i = 0; i < sl; ++i){
attrstring += so[i] + ":" + so[_toCamel(so[i])] + ";";
}
attrstring += "\"";
}
if(this.hasChildNodes()){
// serialize this Element
retArray.push("<");
retArray.push(name);
retArray.push(ns);
retArray.push(attrstring);
retArray.push(">");
for(i=0;i< this.childNodes.length;i++){
childRet = this.childNodes[i].xhtml;
retArray.push(childRet? childRet: this.childNodes[i].xml);
}
retArray.push("</");
retArray.push(name);
retArray.push(">");
}else{
retArray.push("<");
retArray.push(name);
retArray.push(ns);
retArray.push(attrstring);
retArray.push("></");
retArray.push(name);
retArray.push(">");
}
return retArray.join("");
}

수정한 파일:

Posted by 아즈키
2010/03/22 15:02
매우 간만에 정리할만한 짓을 해서 정리중..

일단 url 부터..




일단 그냥 javascript 자체는 jdk 1.6 부터 ScriptManager 로 그냥 실행 시킬 수 있다. 아래같이 걍 쓰면 된다.

import javax.script.*;

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval("print(1+3);");


그런데 문제점은 기존의 코드를 그대로 돌릴 수 없다는 점. 가장 문제는 window 객체도 없고 document 도 없다. 물론, html 영역도 없으므로 기존의 코드가 브라우저의 내장 객체들을 사용하면 그 코드는 돌아가지 않는다.
그런 객체들을 만들어주는 코드가 바로 env.js 이다. 순수 자바스크립트로 이루어져있는 이 코드는 window 객체부터, document 객체는 물론이고, dom 객체들의 innerHTML 같은 속성까지 구현해놓았다.


그럼 ScriptManager 에 env.js 를 넣고 실행한 후 하면 될 것 같다. 하지만 문제는 또 있다. env.js 는 ScriptManager 가 제공하는 자바스크립트 스펙만으로는 동작하지 않는다. env.js 에는 getter, setter 같은 것이 구현되어 있는데, 그건 ECMA-262 Edition 4 부터 지원되는 것 같다. 아무튼 그냥 jdk 1.6 안에 있는 걸루는 안되니 rhino 를 따로 받아서 해야한다.

env.js 나 js-14.jar 나 그냥 url 로 들어가서 받아도 된다.
아무튼 jar 를 자바빌드패스를 설정해서 넣어주고, 다음과 같이 하면 된다.

import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Scriptable;

ContextFactory factory = ContextFactory.getGlobal();
Context cx = factory.enterContext();
cx.setOptimizationLevel(-1);// without 64kb limit
Scriptable shared = cx.initStandardObjects();
Scriptable scope = cx.newObject(shared);
cx.evaluateReader(scope, new java.io.FileReader("env.rhino.js"), "", 1, null);
String source ="";
source += "var div = document.createElement(\"div\");";
source += "div.innerHTML = \"korea\";";
source += "document.body.appendChild(div);";
source += "document.body.innerHTML;";
Object result = cx.evaluateString(scope, source, "", 1, null);
System.out.println(result);//"<div>korea</div>"


룰루랄라.. 너무 잘된다. 응용이 매우 가능할듯.
Posted by 아즈키
2009/03/16 17:15

출처 : http://www.harding.edu/USER/fmccown/WWW/java1_5_csharp_comparison.html

Java (J2SE 5.0) and C# Comparison



Java

C#

Comments
// Single line
/* Multiple
    line  */

/** Javadoc documentation comments */
// Single line
/* Multiple
    line  */

/// XML comments on a single line
/** XML comments on multiple lines */
Data Types

Primitive Types
boolean
byte
char
short, int, long
float, double


Reference Types

Object   (superclass of all other classes)
String
arrays, classes, interfaces

Conversions

// int to String
int x = 123;
String y = Integer.toString(x);  // y is "123"

// String to int
y = "456";
x = Integer.parseInt(y);   // x is 456

// double to int
double z = 3.5;
x = (int) z;   // x is 3  (truncates decimal)

Value Types
bool
byte, sbyte
char
short, ushort, int, uint, long, ulong
float, double, decimal
structures, enumerations

Reference Types
object    (superclass of all other classes)
string
arrays, classes, interfaces, delegates

Convertions

// int to string
int x = 123;
String y = x.ToString();  // y is "123"

// string to int
y = "456";
x = int.Parse(y);   // or x = Convert.ToInt32(y);

// double to int
double z = 3.5;
x = (int) z;   // x is 3  (truncates decimal)

Constants
// May be initialized in a constructor
final double PI = 3.14;
const double PI = 3.14;

// Can be set to a const or a variable. May be initialized in a constructor.
readonly int MAX_HEIGHT = 9;

Enumerations

enum Action {Start, Stop, Rewind, Forward};

// Special type of class
enum Status {
  Flunk(50), Pass(70), Excel(90);
  private final int value;
  Status(int value) { this.value = value; }
  public int value() { return value; }
};

Action a = Action.Stop;
if (a != Action.Start)
  System.out.println(a);               // Prints "Stop"

Status s = Status.Pass;
System.out.println(s.value());      // Prints "70"

enum Action {Start, Stop, Rewind, Forward};

enum Status {Flunk = 50, Pass = 70, Excel = 90};

No equivalent.





Action a = Action.Stop;
if (a != Action.Start)
  Console.WriteLine(a);             // Prints "Stop"

Status s = Status.Pass;
Console.WriteLine((int) s);       // Prints "70"

Operators

Comparison
==  <  >  <=  >=  !=

Arithmetic
+  -  *  /
(mod)
/   (integer division if both operands are ints)
Math.Pow(x, y)

Assignment
=  +=  -=  *=  /=   %=   &=  |=  ^=  <<=  >>=  >>>=  ++  --

Bitwise
&  |  ^   ~  <<  >>  >>>

Logical
&&  ||  &  |   !

Note: && and || perform short-circuit logical evaluations

String Concatenation
+

Comparison
==  <  >  <=  >=  !=

Arithmetic
+  -  *  /
(mod)
/   (integer division if both operands are ints)
Math.Pow(x, y)

Assignment
=  +=  -=  *=  /=   %=  &=  |=  ^=  <<=  >>=  ++  --

Bitwise
&  |  ^   ~  <<  >>

Logical
&&  ||   !

Note: && and || perform short-circuit logical evaluations, no & and | equivalents

String Concatenation
+

Choices

greeting = age < 20 ? "What's up?" : "Hello";

if (x < y)
  System.out.println("greater");

if (x != 100) {   
  x *= 5;
  y *= 2;
}
else
  z *= 6;

int selection = 2;
switch (selection) {     // Must be byte, short, int, char, or enum
  case 1: x++;            // Falls through to next case if no break
  case 2: y++;   break;
  case 3: z++;   break;
  default: other++;
}

greeting = age < 20 ? "What's up?" : "Hello";

if (x < y) 
  Console.WriteLine("greater");

if (x != 100) {   
  x *= 5;
  y *= 2;
}
else
  z *= 6;

string color = "red";
switch (color) {                          // Can be any predefined type
  case "red":    r++;    break;       // break is mandatory; no fall-through
  case "blue":   b++;   break;
  case "green": g++;   break;
  default: other++;     break;       // break necessary on default
}

Loops

while (i < 10)
  i++;

for (i = 2; i <= 10; i += 2)
  System.out.println(i);

do
  i++;
while (i < 10);

for (int i : numArray)  // foreach construct 
  sum += i;

// for loop can be used to iterate through any Collection
import java.util.ArrayList;
ArrayList<Object> list = new ArrayList<Object>();
list.add(10);    // boxing converts to instance of Integer
list.add("Bisons");
list.add(2.3);    // boxing converts to instance of Double

for (Object o : list)
  System.out.println(o);

while (i < 10)
  i++;

for (i = 2; i <= 10; i += 2)
  Console.WriteLine(i);

do
  i++;
while (i < 10);

foreach (int i in numArray) 
  sum += i;

// foreach can be used to iterate through any collection 
using System.Collections;
ArrayList list = new ArrayList();
list.Add(10);
list.Add("Bisons");
list.Add(2.3);

foreach (Object o in list)
  Console.WriteLine(o);

Arrays

int nums[] = {1, 2, 3};   or   int[] nums = {1, 2, 3};
for (int i = 0; i < nums.length; i++)
  System.out.println(nums[i]);

String names[] = new String[5];
names[0] = "David";

float twoD[][] = new float[rows][cols];
twoD[2][0] = 4.5;

int[][] jagged = new int[5][];
jagged[0] = new int[5];
jagged[1] = new int[2];
jagged[2] = new int[3];
jagged[0][4] = 5;

int[] nums = {1, 2, 3};
for (int i = 0; i < nums.Length; i++)
  Console.WriteLine(nums[i]);

string[] names = new string[5];
names[0] = "David";

float[,] twoD = new float[rows, cols];
twoD[2,0] = 4.5f;

int[][] jagged = new int[3][] {
    new int[5], new int[2], new int[3] };
jagged[0][4] = 5;

Functions
// Return single value
int Add(int x, int y) {
   return x + y;
}

int sum = Add(2, 3);

// Return no value
void PrintSum(int x, int y) {
   System.out.println(x + y);
}

PrintSum(2, 3);

// Primitive types and references are always passed by value
void TestFunc(int x, Point p) {
   x++;
   p.x++;       // Modifying property of the object
   p = null;    // Remove local reference to object
}

class Point {
   public int x, y;
}

Point p = new Point();
p.x = 2;
int a = 1;
TestFunc(a, p);
System.out.println(a + " " + p.x + " " + (p == null) );  // 1 3 false




// Accept variable number of arguments
int Sum(int ... nums) {
  int sum = 0;
  for (int i : nums)
    sum += i;
  return sum;
}

int total = Sum(4, 3, 2, 1);   // returns 10

// Return single value
int Add(int x, int y) {
   return x + y;
}

int sum = Add(2, 3);

// Return no value
void PrintSum(int x, int y) {
   Console.WriteLine(x + y);
}

PrintSum(2, 3);

// Pass by value (default), in/out-reference (ref), and out-reference (out)
void TestFunc(int x, ref int y, out int z, Point p1, ref Point p2) {
   x++;  y++;  z = 5;
   p1.x++;       // Modifying property of the object     
   p1 = null;    // Remove local reference to object
   p2 = null;   // Free the object
}

class Point {
   public int x, y;
}

Point p1 = new Point();
Point p2 = new Point();
p1.x = 2;
int a = 1, b = 1, c;   // Output param doesn't need initializing
TestFunc(a, ref b, out c, p1, ref p2);
Console.WriteLine("{0} {1} {2} {3} {4}",
   a, b, c, p1.x, p2 == null);   // 1 2 5 3 True

// Accept variable number of arguments
int Sum(params int[] nums) {
  int sum = 0;
  foreach (int i in nums)
    sum += i;
  return sum;
}

int total = Sum(4, 3, 2, 1);   // returns 10

Strings

// String concatenation
String school = "Harding ";
school = school + "University";   // school is "Harding University"

// String comparison
String mascot = "Bisons";
if (mascot == "Bisons")    // Not the correct way to do string comparisons
if (mascot.equals("Bisons"))   // true
if (mascot.equalsIgnoreCase("BISONS"))   // true
if (mascot.compareTo("Bisons") == 0)   // true

System.out.println(mascot.substring(2, 5));   // Prints "son"

// My birthday: Oct 12, 1973
java.util.Calendar c = new java.util.GregorianCalendar(1973, 10, 12);
String s = String.format("My birthday: %1$tb %1$te, %1$tY", c);

// Mutable string
StringBuffer buffer = new StringBuffer("two ");
buffer.append("three ");
buffer.insert(0, "one ");
buffer.replace(4, 7, "TWO");
System.out.println(buffer);     // Prints "one TWO three"

// String concatenation
string school = "Harding ";
school = school + "University";   // school is "Harding University"

// String comparison
string mascot = "Bisons";
if (mascot == "Bisons")    // true
if (mascot.Equals("Bisons"))   // true
if (mascot.ToUpper().Equals("BISONS"))   // true
if (mascot.CompareTo("Bisons") == 0)    // true

Console.WriteLine(mascot.Substring(2, 3));    // Prints "son"

// My birthday: Oct 12, 1973
DateTime dt = new DateTime(1973, 10, 12);
string s = "My birthday: " + dt.ToString("MMM dd, yyyy");

// Mutable string
System.Text.StringBuilder buffer = new System.Text.StringBuilder("two ");
buffer.Append("three ");
buffer.Insert(0, "one ");
buffer.Replace("two", "TWO");
Console.WriteLine(buffer);     // Prints "one TWO three"

Exception Handling

// Must be in a method that is declared to throw this exception
Exception ex = new Exception("Something is really wrong.");
throw ex;  

try {
  y = 0;
  x = 10 / y;
} catch (Exception ex) {
  System.out.println(ex.getMessage());
} finally {
  // Code that always gets executed
}

Exception up = new Exception("Something is really wrong.");
throw up;  // ha ha


try
{
  y = 0;
  x = 10 / y;
} catch (Exception ex) {      // Variable "ex" is optional
  Console.WriteLine(ex.Message);
} finally {
  // Code that always gets executed
}

Namespaces

package harding.compsci.graphics;












import
harding.compsci.graphics.Rectangle;  // Import single class

import harding.compsci.graphics.*;   // Import all classes

namespace Harding.Compsci.Graphics {
  ...
}

or

namespace Harding {
  namespace Compsci {
    namespace Graphics {
      ...
    }
  }
}

// Import all class. Can't import single class.
using Harding.Compsci.Graphics;

Classes / Interfaces

Accessibility keywords
public
private
protected
static



// Inheritance
class FootballGame extends Competition {
  ...
}

// Interface definition
interface IAlarmClock {
  ...
}

// Extending an interface
interface IAlarmClock extends IClock {
  ...
}

// Interface implementation
class WristWatch implements IAlarmClock, ITimer {
   ...
}

Accessibility keywords
public
private
internal
protected
protected internal
static

// Inheritance
class FootballGame : Competition {
  ...
}

// Interface definition
interface IAlarmClock {
  ...
}

// Extending an interface
interface IAlarmClock : IClock {
  ...
}

// Interface implementation
class WristWatch : IAlarmClock, ITimer {
   ...
}

Constructors / Destructors

class SuperHero {
  private int mPowerLevel;

  public SuperHero() {
    mPowerLevel = 0;
  }

  public SuperHero(int powerLevel) {
    this.mPowerLevel= powerLevel;
  }

  // No destructors, just override the finalize method
  protected void finalize() throws Throwable {
    super.finalize();   // Always call parent's finalizer  
  }
}

class SuperHero {
  private int mPowerLevel;

  public SuperHero() {
     mPowerLevel = 0;
  }

  public SuperHero(int powerLevel) {
    this.mPowerLevel= powerLevel;
  }

  ~SuperHero() {
    // Destructor code to free unmanaged resources.
    // Implicitly creates a Finalize method.

  }
}

Objects

SuperHero hero = new SuperHero();

hero.setName("SpamMan");
hero.setPowerLevel(3);

hero.Defend("Laura Jones");
SuperHero.Rest();  // Calling static method

SuperHero hero2 = hero;   // Both refer to same object
hero2.setName("WormWoman");
System.out.println(hero.getName());  // Prints WormWoman

hero = null;   // Free the object

if (hero == null)
  hero = new SuperHero();

Object obj = new SuperHero();
System.out.println("object's type: " + obj.getClass().toString());
if (obj instanceof SuperHero)
  System.out.println("Is a SuperHero object.");

SuperHero hero = new SuperHero();

hero.Name = "SpamMan";
hero.PowerLevel = 3;

hero.Defend("Laura Jones");
SuperHero.Rest();   // Calling static method

SuperHero hero2 = hero;   // Both refer to same object
hero2.Name = "WormWoman";
Console.WriteLine(hero.Name);   // Prints WormWoman

hero = null ;   // Free the object

if (hero == null)
  hero = new SuperHero();

Object obj = new SuperHero();
Console.WriteLine("object's type: " + obj.GetType().ToString());
if (obj is SuperHero)
  Console.WriteLine("Is a SuperHero object.");

Properties

private int mSize;

public int getSize() { return mSize; }
public void setSize(int value) {
  if (value < 0)
    mSize = 0;
  else
    mSize = value;
}


int s = shoe.getSize();
shoe.setSize(s+1);

private int mSize;

public int Size {
  get { return mSize; }
  set {
    if (value < 0)
      mSize = 0;
    else
      mSize = value;
  }
}

shoe.Size++;

Structs



No structs in Java.

struct StudentRecord {
  public string name;
  public float gpa;

  public StudentRecord(string name, float gpa) {
    this.name = name;
    this.gpa = gpa;
  }
}

StudentRecord stu = new StudentRecord("Bob", 3.5f);
StudentRecord stu2 = stu;  

stu2.name = "Sue";
Console.WriteLine(stu.name);    // Prints "Bob"
Console.WriteLine(stu2.name);   // Prints "Sue"
Console I/O
java.io.DataInput in = new java.io.DataInputStream(System.in);
System.out.print("What is your name? ");
String name = in.readLine();
System.out.print("How old are you? ");
int age = Integer.parseInt(in.readLine());
System.out.println(name + " is " + age + " years old.");


int c = System.in.read();   // Read single char
System.out.println(c);      // Prints 65 if user enters "A"

// The studio costs $499.00 for 3 months.
System.out.printf("The %s costs $%.2f for %d months.%n", "studio", 499.0, 3);

// Today is 06/25/04
System.out.printf("Today is %tD%n", new java.util.Date());

Console.Write("What's your name? ");
string name = Console.ReadLine();
Console.Write("How old are you? ");
int age = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("{0} is {1} years old.", name, age);
// or
Console.WriteLine(name + " is " + age + " years old.");

int c = Console.Read();  // Read single char
Console.WriteLine(c);    // Prints 65 if user enters "A"

// The studio costs $499.00 for 3 months.
Console.WriteLine("The {0} costs {1:C} for {2} months.\n", "studio", 499.0, 3);

// Today is 06/25/2004
Console.WriteLine("Today is " + DateTime.Now.ToShortDateString());

File I/O

import java.io.*;

// Character stream writing
FileWriter writer = new FileWriter("c:\\myfile.txt");
writer.write("Out to file.");
writer.close();

// Character stream reading
FileReader reader = new FileReader("c:\\myfile.txt");
BufferedReader br = new BufferedReader(reader);
String line = br.readLine();
while (line != null) {
  System.out.println(line);
  line = br.readLine();
}
reader.close();

// Binary stream writing
FileOutputStream out = new FileOutputStream("c:\\myfile.dat");
out.write("Text data".getBytes());
out.write(123);
out.close();

// Binary stream reading
FileInputStream in = new FileInputStream("c:\\myfile.dat");
byte buff[] = new byte[9];
in.read(buff, 0, 9);   // Read first 9 bytes into buff
String s = new String(buff);
int num = in.read();   // Next is 123
in.close();

using System.IO;

// Character stream writing
StreamWriter writer = File.CreateText("c:\\myfile.txt");
writer.WriteLine("Out to file.");
writer.Close();

// Character stream reading
StreamReader reader = File.OpenText("c:\\myfile.txt");
string line = reader.ReadLine();
while (line != null) {
  Console.WriteLine(line);
  line = reader.ReadLine();
}
reader.Close();


// Binary stream writing

BinaryWriter out = new BinaryWriter(File.OpenWrite("c:\\myfile.dat"));
out.Write("Text data");
out.Write(123);
out.Close();

// Binary stream reading
BinaryReader in = new BinaryReader(File.OpenRead("c:\\myfile.dat"));
string s = in.ReadString();
int num = in.ReadInt32();
in.Close();

 

Posted by 아즈키
2009/03/16 11:04
by Raffi Krikorian, 역 한빛리포터 2기 신동섭 자바가 프로그래밍 언어로 유명해진 이유는 입력/출력과 네트워킹 동작을 행함에 있어 자바가 지니고 있는 편리성 때문이다. 자바는 C#과 같은 맥락을 가지고 있으며 복잡함에 대해 신경쓰지 않아도 되는 라이브러리를 제공한다. 이 시리즈 중 앞의 두 기사에서는 자바 프로그래머가 간단한 C# 프로그램을 구축하기 위해 알아야 하는 언어 구조의 다른점을 중점적으로 다루었다. 이번 기사는 이러한 라이브러리들의 공통적 사용패턴을 따라 I/O와 네트워킹을 다루는 몇몇 C# 네임스페이스에 중점을 두고 작성할 예정이다. 스트림의 이해 자바와 C#에서 스트림이란 보통 콘솔로부터 콘솔까지, 파일시스템에서 파일시스템까지, 네트워크에서 네트워크까지 바이트를 읽고 쓰는 것을 포함한다. 두 언어 모두에서 스트림 패러다임은 하나의 프로그램을 바이트 그룹으로 동작하거나 이동할 필요가 있을 때 더 일반적으로 사용된다. 자바는 두 개의 추상 클래스인 java.io.InputStreamjava.io.OutputStream을 제공한다. 이 클래스는 프로그램이 이러한 두 스트림 서브 타입으로부터 읽고 쓸 수 있게 인증될 필요가 있는 구현되지 않은 메소드를 포함하고 있다. 반면, C#은 이러한 두 개의 클래스를 System.IO.Stream 하나로 통합한다. 하나는 읽기를 하고 하나는 쓰기를 하는 객체 두 개 대신에 C# 스트림 객체는 CanReadCanWrite 프로퍼티를 그 능력을 검증받을 필요가 있다. 동기 I/O 동기 I/O는 두 언어에 있어서 문법적으로 아주 비슷하다. C# System.IO.Stream와 함께 자바 java.io.InputStreamjava.io.OutputStream은 바이트 배열로 동작하는 메소드와 함께 한 번에 1 바이트를 동작하는 메소드를 가진다. (C#은 전체 배열에 대한 운영 문법이 필요하다. C#은 대신에 offset/length 쌍으로 배열을 사용하는 방법만 알고있다.)
기능 자바 C#
1 바이트를 읽어라 java.io.InputStream에 있는 read() 메소드 System.IO.Stream에 있는 ReadByte() 메소드
전체 바이트 배열을 읽어라 java.io.InputStream에 있는 read( byte[] b ) 메소드 그러한 구문적 메소드 없음 - offset/count 쌍을 가진 읽기 메소드를 사용할 것
바이트 배열의 일부분으로 읽어라. java.io.InputStream에 있는 read( byte[] b, int off, int len ) 메소드 System.IO.Stream에 있는 Read( byte[] buffer, int offset, int length ) 메소드
1 바이트를 작성해라. java.io.OutputStream에 있는 write( int b ) 메소드 System.IO.Stream에 있는 WriteByte( byte value ) 메소드
전체 바이트 arrayjava.io.OutputStream을 작성해라 write( byte[] b ) 메소드 특정 메소드 없음 - offset/count 쌍을 요청하는 메소드를 사용할 것
바이트 배열의 일부분을 작성해라 java.io.OutputStream에 있는 write( byte[] b, int off, int len ) 메소드 System.IO.Stream에 있는 Write( byte[] buffer, int offset, int length ) 메소드
[표 1] 자바와 C#에서 동기 I/O 메소드 동시에 스트림하도록 일하기 원할 때 사용하는 메소드들 자바 프로그래머들을 위한 조언 중 하나는 IOException을 포착하는 것을 잊지 말라는 것이다. 자바와는 달리 C# 컴파일러는 컴파일 할 때 예외(exceptions)를 강요하지 않기 때문이다. 비동기 I/O 자바는 I/O 동작을 공식적으로 비동기로 수행하는 방법이 부족하다. 스트림에 발생하는 읽기 또는 쓰기 야기시킨 후 그 결과를 나중에 점검하는 '내장' 방법이 없다. 자바에서 가장 근접한 시뮬레이션은 동기 메소드 주위에 java.lang.Thread를 생성하는 것이며 콜백을 실행하거나 부작용을 일으키는 스레드를 가지고 있거나 I/O 동작상태에 있을 수도 있다. C#은 그 라이브러리에 내장된 비동기 I/O 메소드를 가지고 있다. 예를 들어 자바에서 비동기 read(byte[] b) 호출을 실행하기 위해 콜백 또는 이후에 점검될 수 있는 상태 모두에서 할 수 있는 구현은 아래와 같다.
// variables to hold the side effects of the read
int read; // to hold the result of the read
IOException exception; // to hold a possible exception
Object wait  ... 
     // some value to block on until the end of the = call

// a wrap around a read on the InputStream variable "is"
( new Thread( new Runnable() {
  public void run() {
    try {
      read  is.read();

    } catch( IOException error ) {
      exception  error;

    } finally {
      synchronized( wait ) {
        // wake up all other threads waiting on this
        // read
        wait.notifyAll();

        }

      // call a callback method
      callback();

      }

    }

} ) ).start();
이것은 '읽기'와 '예외'에 각각 저장된 것에 읽기 값 또는 읽을 때 포착되는 예외를 발생시킬 것이다. 다른 스레드는 변수 'wait'를 수반하거나 비동기 읽기가 완성될 때를 알기 위해 'callback' 메소드를 구현할 수도 있다. 이것을 정리함에 있어 C#은 위에서 언급한 모든 기능을 포함하는 BeginReadEndRead 메소드를 제공한다. AsyncCallback과 상태 객체인 두 개 이상의 변수를 가지는 것을 제외하고 BeginReadRead의 서명은 비슷하며 BeginRead의 서명은 나중에 비동기 읽기의 과정을 점검하는데 사용하는 IasyncResult 객체를 환원한다. BeginRead의 표준사용은 아래와 같다.
IAsyncResult iar sbs.BeginRead( buffer, 0, 1, new AsyncCallback( = callback ), null );
아래와 같이 보이는 callback 메소드
public void callback( IAsyncResult iar )
실제로 몇 바이트를 읽었는지 알아 보기위해 EndRead 메소드 호출은 IAsyncResult 오브젝트로 호출될 수 있다. EndRead를 호출하는 것은 BeginRead이 완성될때까지 블록킹 할 것이라는 것을 경고받는다. 블록킹 없는 읽기상태를 발견하기 위해 IasyncResult 환원에 대한 IsCompleted 프로퍼티가 리턴되는지 점검해라. 또한 buffer 변수의 내용이 비동기식 읽기가 완성될 때까지 보장되지 않는다는 것에 주목해야 한다. 스트림 구현 자바와 C# 스트림은 여러분이 자바 스트림에 대해 알고있는 것처럼 C# 스트림 구현이 그렇게 어렵지 않기 때문에 거의 비슷하다고 볼 수 있다. 이 두 가지를 구현하는데 있어 주요한 차이점은 적절한 읽기, 쓰기 메소드가 구현되어야 하는 것 외에도 C# 스트림 클래스는 읽기 또는 쓰기 두 가지 모두가 가능하기 때문에 성능 프로퍼티는 스트림이 할 수 있는 것을 정확하게 반영해야 한다는 것이다.
기능 자바 C#
읽기 java.io.InputStream에 있는 read() 메소드 System.IO.Stream에 있는 ReadByte() 메소드
검색 java.io.InputStream에 있는 메소드를 생락하고 파일 내로 향하는 필요한 연산을 수행하고, markSupported, mark 및 스트림으로 되돌아가는 reset 메소드를 구현 이 스트림이 Seek 메소드를 검색하고 구현할 수 있는지 프로그램을 보고하기 위해 System.IO.Stream에 있는 CanSeek 프로퍼티를 사용해라.
쓰기 java.io.OutputStream에 있는 write 메소드 구현 (다시 한 번, 최적화 하기위해 OutputStream에 있는 다른 write 메소드들이 제작될 수 있음) CanWrite라고 명명된 System.IO.Stream 프로퍼티로부터 참값을 환원해라. 그리고 최소한 Write, WriteByte, BeginWrite/EndWrite 메소드 중에 하나를 써라.
[표 2] 자바와 C#에서 스트림 구현하기 대응하는 스트림 클래스에서 구현될 필요가 있는 메소드 리스트 C# 스트림 클래스는 기능 구현을 위한 메소드에 관련된 많은 옵션을 제공한다. 모든 메소드의 기본 구현이 다른 메소드를 사용할 수 있는 것처럼 ReadWrite(두 가지 모두 바이트 배열, 오프셋과 길이를 차지함)를 오버라이딩 하는 것은 일반적으로 충분하다. 단순하게 읽기/쓰기 메소드 중 최소한 하나만이라도 오버라이딩 하는 것은 전체 스트림에 요구되는 기능을 추가해 줄 것이다. ReadByteWriteByte의 기본 구현은 롱 값을 바이트 배열로 바꿀 것이다. 반면에 비동기 BeginReadBeginWrite 메소드 기본 구현은 분할된 스레드로 ReadWrite를 실행할 것이다. 읽기와 쓰기 이 기사의 대부분은 C#에서 System.IO.Stream 클래스와 관련된 사항에 많은 시간을 할애했다. 그렇지만 가끔씩 System.IO.TextReaderSystem.IO.TextWriter에 대한 사항에 대해서도 생각해 볼 필요가 있다. 이 두 클래스는 다른 클래스 타입이 쓰기를 다루고 있는 동안 또다른 클래스 타입은 읽기를 하는 자바 I/O 모델과 아주 흡사하다. 그런 점에서 C# 스트림 객체는 바이트를 동시에 읽고 쓰는 방법에 대한 지식을 캡슐화 하고 TextReaderTextWriter 클래스는 읽기와 쓰기 특성을 각각 캡슐화한다. 위의 두 가지로부터 나온 가장 일반적으로 사용되는 클래스는 System.IO.StreamReaderSystem.IO.StreamWriter 클래스로서 이들 두 클래스는 Stream 객체를 취할 수 있으며 선택사항으로 바이트 스트림을 문자 스트림(C#은 기본으로 UTF-8 인코더/디코더를 사용)으로 바꾸는 방법을 명세하는 System.Text.Encoding 객체를 취할 수 있다. 만약 스트림과 유사한 기능으로 접근하는 것이 요구되고, 바이트로 동작하는 것 대신 문자 사용을 위해 프로그래밍을 하고 있다면 스트림 클래스의 미묘한 차이를 다루는 것보다 TextReaderTextWriter 클래스의 서브 클래스를 구현하는 것이 더 쉬울 수도 있다. 만약 스트림이 적절히 구현되었다고 할지라도, 여러분은 커스텀 스트림을 랩핑(Wrapping)하기 위해 StreamReaderStreamWriter 클래스를 사용해야 한다. 파일시스템 I/O 자바에서 디스크 작동 실행은 아주 간단하다. 그것은 java.io.FileInputStream이나 java.io.FileOutputStream 둘 중 하나를 사용하고 java.io.File 객체를 조작하는 것과 관련된 것이다. 이 전에서부터 많이 언급해왔던 것처럼 C#은 자바와 거의 비슷하지만 미묘한 차이가 있다. 자바에서처럼, C# 파일 객체는 파일 시스템 하에서 확고한 관계를 형성하지 않는다. 존재하지 않는 파일을 위해 파일 객체를 생성할 수 있으며 존재하는 파일을 위해 파일 객체를 생성해 파일을 열려고 할 때까지 C# 프로그램도 모르게 CLR하에서 그 파일을 이동시킬 수도 있다. 자바와 달리 파일 객체는 파일시스템으로 스트림을 환원해줄 AppendText 또는 CreateText와 같은 정적 메소드를 가지는 것만큼 훨씬 더 중요한 역할을 수행할 수 있다. 자바에서는 FileInputStream을 위한 생성자는 똑같은 기능을 얻기 위해 사용되어야 한다. 자바에서 쓰기를 위한 새로운 파일을 생성하기 위해서는 FileInputStream을 사용해야 한다.
FileOutputStream fos new FileOutputStream( "brand-new-file.txt" =);
fos.write( ... )
그렇지만 C#에서는

Stream s File.Create( "brand-new-file.txt" );
또는

StreamWriter sw File.CreateText( "brand-new-file.txt" );
을 새 파일을 얻기 위해 Stream 또는 StreamWriter 을 허락한다. (FileOutputStream의 생성자 중 하나로 'append' 불린을 설정함에 따라 자바에서는 appending이 수행됨) C#은 OpenWriteOpenText라고 이름 붙여진 정적 메소드를 가지는 반면 자바는 java.io.FileInputStream를 사용하는 파일로부터 읽기를 허락한다. 마지막으로 C#은 Open 메소드에 더욱 세심한 컨트롤을 제공하며 이 메소드는 파일 퍼미션과 접근 내용을 설정할 수 있는 능력을 보여준다.
기능 자바 C#
쓰기 위한 새로운 파일 생성 java.io.FileOutputStream 사용 정적 File.Create 메소드나 정적 CreateText 사용 또는 인스턴스 CreateText 메소드 사용
기존 파일에 쓰기 java.io.FileOutputStream 사용 정적 또는 인스턴스 OpenWrite 메소드 사용
파일에 텍스트 추가하기 java.io.FileOutputStream 사용 그러나 append 매개변수를 차지하는 생성자를 사용해야 함. 정적 또는 인스턴스 AppendText 메소드 사용
파일로부터 텍스트 제거하기 java.io.FileInputStream 사용 정적 또는 인스턴스 OpenRead, OpenText 메소드 사용
[표 3] 읽기와 쓰기를 위한 파일 조작 자바와 C# 모두에서 파일로부터 쓰거나 읽기 위해 사용하는 메소드 호기심을 위해 언급할 가치가 충분한 C#이 가져온 또다른 향상점은 File.Copy 메소드의 추가라고 말할 수 있다. 파일 시스템 I/O를 사용했던 대부분의 자바 프로그래머들은 파일을 적절하게 옮기는 능력이 부족했다. Java.io.File에는 파일이름을 다시 정의할 수 있는 renameTo 메소드를 포함하고 있지만 파일시스템 경계(디스크, 네트워크 등등)에서는 실행되지 않는다. 대개의 경우 프로그래머는 자신의 이동 명령어를 구현해야만 했다. 이동 명령어는 java.io.FileInputStreamjava.io.FileOutputStream 모두를 사용해 파일을 복사하고 원본 파일을 지운다. File.Move 명령어 역시 볼륨(Volumes)과 파일시스템 경계에서는 실행되지 않는다고 하더라도 Copy 메소드의 C# 산물은 작은 파일들을 옮긴다. C# 파일-시스템 구현은 자바 모델이 대처해야만 하는 범용 플렛폼을 다룰 필요는 없다. Java.io.File.pathSeparatorjava.io.File.separator과 일치하는 변수는 없다. 불행하게도 이것은 또한 java.io.File 생성자중 호의적인 public File( File parent, String child )이 존재하지 않는다는 것을 의미한다. 그 대신 C# 프로그래머는
File parent  ...
File child  new File( parent.FullName + "\" + childName );
와 함께 새로운 System.IO.File 객체를 생성하는 문제가 남는다. 네트워크 이해하기 두 가지 프로그래밍 언어(C#, Java) 모두는 기본레벨 소켓 구현에 있어 몇 가지 추상적 계층을 제공한다(당연히 자바의 java.net.Socket 클래스는 C#의 System.Net.Sockets.Socket 클래스보다 더 추상적임).
Tier 자바 C#
응답/요청 java.net.URLjava.net.URLConnection System.Net.WebRequest
프로토콜 TCP/IP를 위한 java.net.Socketjava.net.ServerSocket; UDP를 위한 java.net.DatagramSocketjava.net.MulticastSocket TCP/IP를 위한 System.Net.Sockets.TCPListenerSystem.Net.Sockets.TCPClient ; System.Net.Sockets.UDPClient
원래 소켓 없음 System.Net.Sockets.Socket
[표 4] 자바와 C#에서 네트워크 아키텍처 계층 자바와 C# 모두 인터페이스의 다른 점에 영향을 주도록 허락하는 네트워크를 위한 서로 다른 추상 층을 갖고 있다. 응답/요구 계층은 한쪽 끝에서 연결을 초기화하고 스트림으로 바이트를 보낸다. 그리고 응답으로 바이트 집합을 기다리는 동안 블록킹하는 HTTP 형태의 요구를 위해 사용될 수 있다. 좀더 유연한 스트림 작동을 위해 프로토콜 계층은 아주 유용하다(우리는 아래에서 TCP/IP 동작을 커버할 것이다). 대부분 자바 프로그래머들은 네트워크 작동을 최적화하지 않는다면 정확한 소켓 콘트롤을 요구하지는 않는다. C#은 만약 필요하다면 원래의 버클리 소켓을 제어할 수 있는 능력을 제공한다. 응답/요구 계층 이 계층은 모든 네트워킹을 제거하고 앞뒤로 데이터를 이동할 수 있도록 스트림 같은 인터페이스를 제공한다. 자바는 HTTP URL을 가질것이고 아래와 같은 코드를 실행함으로써 간단히 GET을 실행할 것이다.
URL url  new URL( "http://to.post.to.com" );
URLConnection urlConnection  url.openConnection();
InputStream input  urlConnection.getInputStream();
... read stuff from input ...
input.close();
C#은 System.Net.WebRequest 객체로 이 코드를 모방한다:

WebRequest request WebRequestFactory.Create( = "http://to.post.to.com" );
Stream input request.GetResponse().GetResponseStream();
... read stuff from input ...
input.Close();
이러한 두 가지 구현은 기본적인 소켓 생성과 HTTP protocol 요구를 숨길 것이며 프로그래머가 데이터를 싣고 받는데 사용할 수 있는 스트림을 제공할 것이다. C# 스트림 클래스처럼, WebRequest 클래스는 읽기 위한 WebResponse 객체 또는 쓰기 위한 요구 스트림을 비동기적으로 얻기 위한 메소드를 가진다. 프로토콜 계층 System.Net.Sockets.TCPClient 클래스는 java.net.Socket에 친숙한 자바 프로그래머들에게 더 친숙해 보여야 한다. 왜냐하면 이 두 가지는 거의 똑같기 때문이다. 사용되는 리턴 스트림 대신에 프로그래머가 소켓 구현을 다룰 필요가 없는 것처럼 둘 다 아주 비슷한 API 및 비슷한 기능을 공유한다. 간단한 텔넷 클라이언트 구현은 간단히 아래의 코드를 사용함으로써 자바에서 조합될 수 있다:
Socket telnet  new Socket( "telnet.host.com", 23 );
OutputStream output  telnet.getOutputStream();
InputStream input  telnet.getInputStream();
그리고 위의 두 스트림도 telnet.host.com에 텔넷에 결합하는데 사용될 수 있다. C#으로도 거의 같은 형태로 똑같은 프로그램을 쓸 수 있다.
TCPClient telnet  new TCPClient( "telnet.host.com", 23 );
Stream telnetStream  telnet.GetStream();
StreamWriter output  new StreamWriter( telnetStream );
StreamReader input  new StreamReader( telnetStream );
또한, 자바로 들어오는 소켓을 설정하고 아래 코드를 사용하여 받는 것처럼 TCP/IP 연결을 받는 것은 두 언어에 있어 아주 비슷하다.
ServerSocket server  new ServerSocket( 23 );
Socket accept  server.accept();
반면에 C#은 아래와 같은 코드를 사용한다.
TCPListener server  new TCPListener( 23 );
server.Start();
Socket accept  server.Accept();
두 언어에서 인정되는 각각의 소켓은 따로 다루어져야 한다. 자바에서 선호하는 방법(java 1.4까지)은 받는 개개의 소켓을 위한 스레드를 생성하는 것이었다. 똑같은 것이 C# 소켓에서도 사용될 수 있다. 그러나 소켓 클래스는 'select' 메소드로 이벤트 구동 인터페이스를 사용하는 능력을 제공한다. (이벤트 구동 모델에서 소켓 프로그래밍은 이 기사의 범주를 벗어나는 것이므로 다루지 않겠다.) Raw 소켓 계층 이제 우리는 대부분의 자바 프로그래머에게 익숙하지 않은 영역으로의 모험을 시작할 것이다. 자바만 사용하는 프로그래머들은 버클리 소켓 구현에 대해 알 필요가 없었다. 왜냐하면 버클리 소켓 구현은 java.net.Socket java.net.DatagramSocket 클 래스에 의해 추출되기 때문이었다. 이 버클리 소켓 클래스를 적절하게 조작함으로써 눈에 익은 자바 기능의 스트림을 성취할 수 있다. 지금까지 우리는 자바(I/O와 네트워킹을 수행할 수 있는 능력)로부터 가장 강력한 추상개념을 포함하는 C# 레퍼토리에 대해 살펴보았다. 다음 기사에서는 병렬 동작을 허용하는 멀티스레딩을 다룰 것이다. Raffi Krikorian은 메사추세스 주 캠브리지에서 컨설턴트로 활동하고 있으며 대용량 분산 P2P 시스템, JXTA와 C#에 능통한 전문가 이다.
 
Posted by 아즈키
2009/03/16 10:23
출처 : http://www.epochconverter.com/


Free unix timestamp and epoch conversion tool


The current Unix epoch time is   1207534309      

Convert epoch to human readable date and vice versa
   or  batch convert epochs to human dates

Mon Day Yr   Hr Min Sec
/   /      :   :   GMT    

   or  batch convert
Format: RFC 2822 formatted date

Epoch dates for the start and end of the year/month/day
Show start & end of  year  month  day

Mon Day Yr  
/   /       or  Epoch List By Month & Year

Convert seconds to days, hours and minutes
 
More date conversion tools
Calculate the difference between 2 dates

What is epoch time?
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds. The epoch timestamp 0 can be written in ISO 8601 format as: 1970-01-01T00:00:00Z. One epoch hour is 3600 seconds, one epoch day is 86400 seconds long, leap seconds are not calculated. Many Unix systems store epoch dates as a signed 32-bit integer, which might cause problems on January 19, 2038 (known as the Year 2038 problem or Y2038).

Human readable time  Seconds
1 minute 60 seconds
1 hour 3600 seconds
1 day 86400 seconds
1 week 604800 seconds
1 month (30.44 days)  2629743 seconds
1 year (365.24 days)   31556926 seconds

How to get the current epoch time in ...
Perl time
PHP time()
Ruby Time.now (or Time.new). To display the epoch: Time.now.to_i
Python import time first, then time.time()
Java long epoch = System.currentTimeMillis()/1000;
Microsoft .NET C# epoch = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
VBScript/ASP DateDiff("s", "01/01/1970 00:00:00", Now())
MySQL SELECT unix_timestamp(now())
PostgreSQL SELECT extract(epoch FROM now());
SQL Server SELECT DATEDIFF(s, '19700101', GETDATE())
JavaScript Math.round(new Date().getTime()/1000.0) getTime() returns time in milliseconds.
Unix/Linux date +%s
Other OS's  Command line: perl -e "print time" (If Perl is installed on your system)

Convert from human readable date to epoch
Perl Use these Perl Epoch routines
PHP mktime(hour, minute, second, month, day, year)  
Ruby Time.local(year, month, day, hour, minute, second, usec ) (or Time.gm for GMT/UTC input). To display add .to_i
Python import time first, then int(time.mktime(time.strptime('2000-01-01 12:34:00', '%Y-%m-%d %H:%M:%S')))
Java long epoch = new java.text.SimpleDateFormat ("dd/MM/yyyy HH:mm:ss").parse("01/01/1970 01:00:00");
VBScript/ASP DateDiff("s", "01/01/1970 00:00:00", time field)  
MySQL SELECT unix_timestamp(time) Time format: YYYY-MM-DD HH:MM:SS or YYMMDD or YYYYMMDD  
PostgreSQL SELECT extract(epoch FROM date('2000-01-01 12:34'));
With timestamp: SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-08');
With interval: SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
SQL Server SELECT DATEDIFF(s, '19700101', time field)
JavaScript use the JavaScript Date object
Unix/Linux date +%s -d"Jan 1, 1980 00:00:01"

Convert from epoch to human readable date
Perl Use these Perl Epoch routines
PHP date(output format, epoch); Output format example: 'r' = RFC 2822 date  
Ruby Time.at(epoch)
Python import time first, then time.gmtime(epoch) time is an array of year, month, day, hour, min, sec, day of week, day of year, DST  
Java String date = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new java.util.Date (epoch*1000));
VBScript/ASP DateAdd("s", epoch, "01/01/1970 00:00:00")  
PostgreSQL SELECT TIMESTAMP WITH TIME ZONE 'epoch' + epoch * INTERVAL '1 second';  
MySQL from_unixtime(epoch, optional output format) The default output format is YYY-MM-DD HH:MM:SS  
SQL Server DATEADD(s, epoch, '19700101')
JavaScript use the JavaScript Date object
Linux date -d @1190000000 (replace 1190000000 with your epoch, needs newer version of date)
Other OS's Command line: perl -e "print scalar(localtime(epoch))" (If Perl is installed) Replace 'localtime' with 'gmtime' for GMT/UTC time.

Full screen epoch clock | Epoch Conversion Functions | Related Books
Esta página en Español: Convertir Epochs / Tiempos Unix
Please note: All tools on this page are based on the time settings of your computer.  

add to Favorites - add to Del.icio.us
www.epochconverter.com - © 2008 Misja.com - contact - privacy - Unicode Tools
Posted by 아즈키
2009/02/06 11:17
회사 개발 서버가 죽고 리부팅을 한 다음에 보니깐..

어떤 한분이 접속이 안대는 에러가 있었다.

'Cannot find SS.INI file for user ******'

라는 메시지가 뜨면서 로그인이 안되는 문제였다.

구글링을 통해 어떤 친절한 외국분의 설명을 듣고 수정에 성공하였다.

방법은 간단.

소스세이프 파일이 있는 폴더로 가서, users 폴더안의 유저이름으로 된 폴더 안을 보면..

~.tmp 로 된 파일이 있고 SS.INI 파일이 없다.

그럼 그 ~.tmp 파일의 이름을 SS.INI 로 바꿔주기만 하면 된다.

Posted by 아즈키
2009/01/19 17:26

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

2009/01/16 11:26
갑자기 포스팅이 하고싶어서 씀.


자바스크립트에서 조건식을 쓸때 무엇이 false 이고 무엇이 true 일까?

boolean 값인 true 나 false 는 그 자체가 true, false 이다.

number 일 경우 0 이나 NaN 이면 false, 그 외에는 모두 true 이다.

string 일 경우 "" 이면 false, 그 외에는 모두 true 이다.

object 의 경우 null 일 경우 false, 그 외에는 모두 true.

function, array 등은 모두 true.

정리하면.. 자바스크립트 조건문에서 true 는 false, 0, NaN, "", null 을 제외한 모든 값이다.


ps. 위를 응용한 재미있는 사실

if ("0") alert(1);
else alert(0);
 1 이 출력됨. (true)

if ("0" == true) alert(1);
else alert(0);
 0 이 출력됨. (false)

if ("0" == false) alert(1);
else alert(0);
 1 이 출력됨. (true)

조건문에서 "0" 은 true 지만, "0" == false 이다.

 참고 :

자바스크립트 타입 비교 테이블 + 테이블 작성 스크립트

Posted by 아즈키
2008/12/01 13:50

스타일 적용시에는 styleSheet 오브젝트의 (document.styleSheets : Array) 메소드를 사용하는데,

  • IE 에서는 addRule 을 사용

인자값을 3개(필수3개)로,

  1. 0번 argument에는 선택자('div', 'p' 등..)를 넣고,
  2. 1번 argument에는 스타일 명령("color:blue", "overflow:hidden" 등..)을 넣는다.
  3. 2번 argument에는 0부터 시작하는 pages 컬렉션(document.styleSheets[?].pages : Array)에서의 위치할 인수를 넣는다. (-1을 넣으면 제일 뒤에 위치하게 된다.)
    반환값은 항상 -1이다. (주의: 오류가 없어도 -1을 반환)
  • FF 에서는 insertRule 를 사용

인자값은 2개(필수2개)로,

  1. 0번 argument에는 스타일 명령을 선택자를 포함하여 넣는다. (예: "#myTable {-moz-user-select:none}")
  2. 1번 argument에는 0부터 시작하는 cssRules 컬렉션(document.styleSheets[?].cssRules : Array)에서의 위치할 인수를 넣는다. (주의: addRule과는 다르다, -1 인자값을 넣으면 에러가 난다.)
    반환값은 cssRules 컬렉션에서의 위치한 위치값이다.

ps. 아즈키네 2번째 블로그 옛글중에 가져옴 (http://2.azki.org/182)

Posted by 아즈키
2008/11/28 23:33

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

2008/11/18 17:56
자바스크립트 막코딩으로 (특별한 animation/effect 라이브러리 사용 없이) 뒤집는 효과를 구현해 보았습니다

구현을 위주로 엉망으로 짠 코드라  부끄럽지만, 올리고 봅니다.


  • url
http://fliptest.azki.org/proto.html
(상수값으로 효과를 만들어본 첫번째 버전)
http://fliptest.azki.org/
(몇가지 변수를 적용할 수 있는 두번째 버전)


  • 소개
4각형과 3각형의 조합으로 접히는 효과를 내보았습니다.
실제 flip 과정중 캡쳐화면입니다.
사용자 삽입 이미지
그리고 element 의 구성은 3가지로 이루어져 있습니다.
사용자 삽입 이미지
왼쪽 삼각형과 오른쪽 삼각형이 입체적으로 착각하도록 할 수 있습니다.

삼각형을 만드는 방법은 참고사이트중 Triangles in Javascript 에 자세하게 나와있습니다.
사용자 삽입 이미지


  • 참고 사이트
http://lab.smashup.it/flip/
(Flip!0.4 - A jQuery plugin)
http://www.uselesspickles.com/triangles/demo.html
(Triangles in Javascript)
http://www.xentrik.net/css/filters.php
(CSS Filters)


ps.
참고사이트중 Flip!0.4 - A jQuery plugin 에서 처음 flip 효과를 보았는데,
그 flip 은 Opera browser 를 지원하지 못합니다. 제가 만든 것은 됩니다 :]
테스트 한 브라우저 목록입니다.
  • FF2, FF3
  • IE6, IE7, IE8
  • Opera 9
  • safari 3 (windows)
  • Chrome 0.3
Posted by 아즈키
2008/11/06 00:57

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

2008/10/30 11:05
등록 부분
initialize: function(id, container){
    (...)

    var thisP = this;
    AzLib.Event.observe(
        this._element,
        AzLib.Browser.Gecko ?
            "DOMMouseScroll" :
           "mousewheel",
        function(e){
            thisP.__event_mouseWheel(e);
        }
    );

    (...)
}

콜백 부분
__event_mouseWheel: function(e){
    AzLib.Event.stop(e);
    var delta = 0;
    if (e.wheelDelta) { /* IE, Opera, Safari, Chrome */
        delta = -e.wheelDelta / (AzLib.Browser.Chrome? 360: 120);
    } else if (e.detail) { /* Gecko */
        delta = e.detail / 3;
    }
    this._verticalScrollbar.stepPosition(delta * this.wheelRowCount);
}

mouse wheel 관련 자료를 찾아보니 살짝? 오동작도 하고 크롬 브라우저에 대한 처리가 안되어있어 수정하여 적용중인 코드.

IE6, IE7, IE8beta, FF2, Opera9, Safari3, Chrome0.2 에서 테스트 됨.
Posted by 아즈키
2008/07/18 16:15
prototype의 constructor에 대한 질문.

function A(){
  this.a = 'a';
}

function B(){
  this.b = 'b';
}


위와 같은 함수가 있을때,

★예제 1.

A.prototype = B.prototype;

var obj = new A;

-- 예제1의 결과

obj.constructor // function B(){ this.a = 'b'; }
A.prototype.constructor //function B(){ this.a = 'b'; }
obj.a // a
obj.b //undefined

★예제 2.

A.prototype = new B

var obj = new A;

-- 예제2의 결과

obj.constructor // function B(){ this.a = 'b'; }
A.prototype.constructor //function B(){ this.a = 'b'; }
obj.a // a
obj.b // b

-- 궁금증 --

예제1 에서 보시면 obj의 생성자도 B고 A.prototype의 생성자또한 B입니다.
그런데, obj는 B를 참조하지 못하고 있습니다.
(예제에는 없지만 B.prototype은 참조하고 있습니다.)

저는 A.prototype 에 B.prototype을 할당하면 B도 같이 넘어오는것 처럼 보이는데,

실제로 결과를 확인해보니 B의 prototype개체만 넘어옵니다.

그렇다면 왜,, A.prototype.constructor와 obj.constructor는 B가되는것일까요??
A가 참조하지 않는다면, 생성자는 그대로 A가되야 하지 않을까요?

그리고 예제2에서 처럼 new연산자를 통해서 A.prototpye = new B를 하면 prototpye과

생성자가 같이 넘어오는 건가요..?

정리를 한다고 했는데,, 제가 질문하는 의도가 그대로 전달되는지 조심스럽네요^^;

답변 부탁드립니다.


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


아즈키의 답:

A.prototype 나 B.prototype 이 생성된 과정을 생각하세요..
그리고 A.prototype 이나 B.prototype 은 A와 B와는 별개라고 생각하세요..
B.prototype 은
function B(){
this.b = 'b';
}
을 쓰신 순간에 생성되고,
그리고, B.prototype 의 생성자 (constructor) 는 B 가 되겠죠..
(B.prototype.constructor == B)

A.prototype = B.prototype;
를 하셔서 이제.
A.prototype 는 B.prototype 가 되고.(똑같은객체)
A.prototype.constructor 는 B가 됩니다.
(B.prototype.constructor 는 B 이니까요.) 삭제
아즈키     그 리고, new A 로 해서 만든 obj 의 경우의 implicit prototype link는 B.prototype 을 가르키고 있겠죠.. (참고: FF에서는 __proto__ 라는 키워드로 implicit prototype link를 확인할 수 있습니다)
그래서 a.constructor == B 가 되는겁니다. (실제적으로 a 는 constructor 라는 프로퍼티를 가지지 않습니다. constructor 는 a 의 implicit prototype link 인 B.prototype 에서 받아오는 것 입니다.)

A.prototype = new B
하신것은 new B 해서 나온 object를 A.prototype 으로 쓰겠다는 것 인데요..
그럼 obj = new A 해서 생긴 obj 의 constructor 는
obj 의 implicit prototype link 인 "new B 해서 나온 object"의 implicit prototype link인 B.prototype 의 constructor 인 B 가 나오고요.
A 의 prototype 은 "new B 해서 나온 object" 이므로, 마찬가지이고요. 삭제
아즈키     그리고,
obj.a 는 new A 할 때 생긴 프로퍼티고, obj.b 는 new B 할 때 생긴 거니 둘다 됩니다..
물론, obj.a 는 obj 자체가 가진 프로퍼티지만, obj.b 는 obj 의 implicit prototype link 인 "new B 해서 나온 object"가 가진 프로퍼티죠..

아마도, prototype 의 개념에 대해서 조금 오해를 하고 계신 것 같습니다.
ecma4-262 문서를 보시면 도움이 되실 것 같습니다. (특히 4.2.1 Object 파트를 보시면.) 삭제
hym73     친절하고 상세한 답변 정말 많은 도움되었습니다.
감사드립니다.

덧붙여 질문하나 드리자면,, 답변에서 말씀하고 계신 "implicit prototype link"가 무엇을 뜻하는지요?^^
아즈키     네. implicit prototype link 라는건 자세한건 문서를 보시면 (ecma) 좋습니다.
특히 자바스크립트에서는 이게 이거다 하는 말이 많은데.. (OOP다, 아니다. function 이다, object 다. class 다 아니다 등등)
일단은 ecma 스펙문서에 나온 단어구요.
대략적으로 설명드리면..
explicit prototype link 와 implicit prototype link 가 있습니다.
var A = function() {};
var Ap = A.prototype;
var a = new A();
위와 같은 예제에서,
A의 explicit prototype link가 Ap이고
a의 implicit prototype link가 Ap입니다.
explicit 단어를 붙인 것은 A.prototype 으로 명시적으로 접근할 수 있기 때문인 것 같습니다.
implicit 단어를 붙인 것은 a 에서 Ap에 명시적으로 접근을 할 수 없기 때문인 것 같네요.. (하지만 FF에서는 __proto__ 라는 키워드를 만들어서 접근할 수 있도록 했습니다) 삭제
아즈키     그럼 역활에 관해 좀 더 설명드리자면.

위 예제에서
Ap.b = 23;
하면
a.b == 23
이 true 입니다.
실제적으로 a 가 b 를 가지고 있는 것이 아니고, Ap 에서 가져오는 것이죠..
이것이 implicit prototype link 입니다.

그리고 부가적인 설명을 드리자면
a의 implicit prototype link인 Ap의 implicit prototype link가 만약 Cp라면..
Cp.c = 84;
했을 때, a.c == 84 가 true 입니다
즉, 자기 자신이 그 멤버(프로퍼티)를 안 가지고 있으면 implicit prototype link를 따라 계속 탐색을 합니다.
이것을 prototype chain 이라고 부릅니다.

조금이나 도움이 되었다니 제가 더 감사합니다 좋은 하루 되세용
Posted by 아즈키
2008/07/02 09:18
다른 팀의 업무를 도와주며 한두시간의 시간을 투자해서 만든 프로그램입니다.. (그런데 사용할 일이 사라져서 빛을 보지도 못한 프로그램입니다;)


  • URL
http://json2table.azki.org/ 입니다


  • 소개
JSON 문자열을 textarea 에 넣고 2 table ! 버튼을 누르면 JSON 데이타를 테이블로 출력하고, 출력하는데 걸린 시간을 출력합니다. 표시하는 룰은 object 타입은 테이블로 나타내고, array 타입은 row로 나타냅니다.
(참고: array 타입일 경우 테이블의 첫번째 로우에 각 item 의 이름(key)이 표시되는데, 그 아이템의 순서가 뒤바뀌거나 item 의 이름 종류나 개수가 일치하지 않는 경우 예외처리를 해놓지 않아서 정확하게 동작하지 않습니다)


  • 예제

{
    code: 'success',
    data: {
        member: {
            name: '김성준',
            id: 'azki',
            sno: '0701082'
        }
    }
}
위의 JSON 코드를 넣으니 아래 테이블로 표시되네요..
codedata
success
member
nameidsno
김성준azki0701082
15ms

아래부터는 다른 예제입니다

{
    "dataset": [{
        "columnInfo": [{
            "type": "string",
            "size": 10,
            "name": "departure_city"
        }, {
            "type": "string",
            "size": 10,
            "name": "departure_date"
        }, {
            "type": "string",
            "size": 10,
            "name": "arrival_city"
        }, {
            "type": "string",
            "size": 10,
            "name": "arrival_date"
        }],
        "rows": [{
            "arrival_city": "TOKYO",
            "departure_date": "03Jul08",
            "arrival_date": "05Jul08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "03Jul08",
            "arrival_date": "06Jul08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "10Jul08",
            "arrival_date": "12Jul08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "10Jul08",
            "arrival_date": "13Jul08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "17Jul08",
            "arrival_date": "19Jul08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "17Jul08",
            "arrival_date": "20Jul08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "24Jul08",
            "arrival_date": "26Jul08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "24Jul08",
            "arrival_date": "27Jul08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "31Jul08",
            "arrival_date": "02Aug08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "31Jul08",
            "arrival_date": "03Aug08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "07Aug08",
            "arrival_date": "09Aug08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "07Aug08",
            "arrival_date": "10Aug08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "14Aug08",
            "arrival_date": "16Aug08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "14Aug08",
            "arrival_date": "17Aug08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "21Aug08",
            "arrival_date": "23Aug08",
            "departure_city": "BUSAN"
        }, {
            "arrival_city": "TOKYO",
            "departure_date": "21Aug08",
            "arrival_date": "24Aug08",
            "departure_city": "BUSAN"
        }],
        "name": "Schedule"
    }]
}
위의 JSON 코드를 넣으니 아래 테이블로 표시되네요..

dataset
columnInforowsname
typesizename
string10departure_city
string10departure_date
string10arrival_city
string10arrival_date
arrival_citydeparture_datearrival_datedeparture_city
TOKYO03Jul0805Jul08BUSAN
TOKYO03Jul0806Jul08BUSAN
TOKYO10Jul0812Jul08BUSAN
TOKYO10Jul0813Jul08BUSAN
TOKYO17Jul0819Jul08BUSAN
TOKYO17Jul0820Jul08BUSAN
TOKYO24Jul0826Jul08BUSAN
TOKYO24Jul0827Jul08BUSAN
TOKYO31Jul0802Aug08BUSAN
TOKYO31Jul0803Aug08BUSAN
TOKYO07Aug0809Aug08BUSAN
TOKYO07Aug0810Aug08BUSAN
TOKYO14Aug0816Aug08BUSAN
TOKYO14Aug0817Aug08BUSAN
TOKYO21Aug0823Aug08BUSAN
TOKYO21Aug0824Aug08BUSAN
Schedule
109ms

  • 추후 업데이트될 수도 있는(?) 기능들..
    • JSON 데이타를 포맷팅해주는 기능 (보기 편하게)
    • 색상등으로 좀 더 보기 편하게 해주는 기능
    • 두가지 이상의 JSON 데이타를 서로 비교-분석 해주는 기능
    • 많은 케이스에 대해서 테스트가 이뤄지지 않은 상태라 버그가 있을 가능성이 높음. -> 디버깅..
Posted by 아즈키
2008/06/10 15:12
소스1.
var input = document.createElement("input");
input.setAttribute("type", "text");
document.body.appendChild(input);

소스1. 적용 이후 다음 소스가 적용되지 않는다.. IE 에서만 ^^;

소스2.
input.setAttribute("type", "password");

IE 에서 나타나는 에러 메시지는 "이 명령은 지원하지 않습니다."

물론, setAttribute 메소드를 사용하지 않고 input.type = "..."; 로 적용시켜도 에러가 남.

FF2, Opera9, Safari3 에서는 정확히 잘 동작한다. IE6, IE7, IE8 beta1 에선 에러가 난다..


프로젝트에서는 아래와 같은 코드로 대체했다
 
if (Prototype.Browser.IE) {
    var outerHTML = this._input.outerHTML;
    outerHTML = outerHTML.replace(/type=[a-z]*/, "");
    outerHTML = outerHTML.replace(/value=""/, "value=\""+this._getText()+"\"");
    // IE 에서는 한번 지정된 type을 변경할 수 없어서 새로운 Element 를 만들어야 함.
    // IE 에서 password 타입의 텍스트 박스는 outerHTML 에서 value 값이 나타나지 않아서 다시 넣어줘야함.
    var newInput = document.createElement(outerHTML);
    if (this._getPassword()) {
        newInput.setAttribute("type", "password");
    }
    this._input.parentNode.replaceChild(newInput, this._input);
   
    //이벤트등록해제 등등 reference value 에 관련된 모든 것들 해제
    //...
    this._input = newInput;
    //...
    //이벤트등록 등등 reference value 에 관련된 모든 것들 재등록
}
else {
    this._input.setAttribute("type", this._getPassword()? "password": "text");
}

ps. 이벤트 등 element 값 자체를 등록시켜놓은 부분에 대해 수정이 반드시 필요하다.

참고로 이 문제의 다른 해결 방법이 없는지.. 구글을 찾아보니 역시나 비슷한게 있었다
http://codingforums.com/showthread.php?t=107073
Change input type="text" to input type="password"

Code:
<script type="text/javascript">
function passit(ip){
var np=ip.cloneNode(true);
np.type='password';
if(np.value!=ip.value)
np.value=ip.value;
ip.parentNode.replaceChild(np,ip);
}
</script>

<form id="login" action="#" method="post">
<input id="username-field" type="text" name="username" title="Username" onmousedown="javascript:this.value=''; javascript:this.focus();" value="Username" tabindex="1" />
<input id="password-field" type="text" name="password" title="Password" onmousedown="javascript:this.value=''; passit(this.form[0]); javascript:this.focus();" value="Password" tabindex="2" />
<input type="submit" name="submit" value="sign in" tabindex="3" />
</form>


나도 처음에 cloneNode 메소드를 생각했었는데, 사용하지 않았다..
이유는 type="text" 인 input 을 type="password" 로 변경은 가능하지만..
반대로는 불가능했기 때문이다. -ㅁ-
어째뜬..
IE does not like to change dynamically the type, thus one solution might be to replace entirely the object.
Posted by 아즈키
2008/05/26 19:22
소스1.
<button style="
    width: 152px;
    height: 100px;
    background: red;
    border: 15px solid blue;
    overflow: hidden;
    position: absolute;
">
<div style="
    width: 122px;
    position: absolute;
    left: 0px; top: 0px;
    background: green;
">
azki's test
</div>
</button>

출력물1. (FF2)


출력물2. (IE6, IE7 도 동일하게 나온다)


출력물3. (왼쪽부터 Opera9, Safari3... 비슷함)



직관적으론 출력물3 처럼 나와야 하겠지만 불행히도 FF와 IE에서는 이상하게 나온다..
내부 div 에 top 과 left 속성을 제거해보자.. 더욱 더 가관이다.

소스2.
<button style="
    width: 152px;
    height: 100px;
    background: red;
    border: 15px solid blue;
    overflow: hidden;
    position: absolute;
">
<div style="
    width: 122px;
    position: absolute;
    background: green;
">
azki's test
</div>
</button>

출력물1. (FF2)


출력물2. (IE6, IE7 도 동일하게 나온다)


출력물3. (Opera9)


출력물4. (Safari3)



내가 원하는 것은 소스1의 출력물3과 같은 형태인데,
참 어려운것 같다 ㅡㅡ
더욱 재미난 것은... FF 의 디버깅 도구 firebug 에서 보여지는 부분이다. (소스1)

날 약올리듯이? 내가 원하는 부분을 정확하게 가르키고 있다.

일단 하나 하나를 분석해보니..

border 가 좌우 좌표를 이상하게 만드는 것 같았다. (IE와 FF에서)

그리고 FF 에서는 padding 이 또 문제를 안쪽 div의 위치를 움직이고 있었다.

소스1에서 border 와 padding 을 모두 0px 로 준 결과를 살펴보면 다음과 같다

소스3.
<button style="
    width: 152px;
    height: 100px;
    background: red;
    border: 0px;
    padding: 0px;
    overflow: hidden;
    position: absolute;
">
<div style="
    width: 122px;
    position: absolute;
    left: 0px; top: 0px;
    background: green;
">
azki's test
</div>
</button>

출력물1. (FF2)

출력물2. (IE6, IE7, Opera9, Safari3)



결국 적절한 해답은 못 찾았고..

소스3의 상태에서 FF만 따로 위치를 잡아주는 식으로 처리를 했다
left 속성: -3 , top 속성: -(높이/2+1)


부록::
프로젝트에서는 javascript 로 이런식으로 구성되어 있다 ㅡㅡㅋ

initialize: function() {//컴포넌트 객체를 생성할 때 호출됨..
        //...
        if (Prototype.Browser.Gecko) {
            this._label.setX(-3);
        }
        else {
            this._label.setX(0);
            this._label.setY(0);
        }
}
,
//...
,
onresize: function() {//사이즈 변경시에 호출됨..
        //...
        if (Prototype.Browser.Gecko) {
            this._label.setY(-1-Math.floor(height/2));
        }
}

Posted by 아즈키
2008/05/21 10:57

Javascript 로 지정한 style 의 경우 구하는 예
element.style["fontSize"]

IE 의 경우 구하는 예
element.currentStyle["fontSize"]

FF 의 경우 구하는 예
document.defaultView.getComputedStyle(element, "").getPropertyValue("font-size")


참고: IE 의 경우 filter 값을 구하는 방법의 예.
element.filters.item("alpha").opacity

Posted by 아즈키
2008/05/14 09:27
예전부터 알고 있었던거라 그때 정리해 쓸려했는데..
조금 더 보편화된 패턴이 발견되면 정리할려다 시간이 많이 흘러 이렇게 그냥 정리.. (결국 보편화된 패턴이나 다른 이상 증상은 아직 발견하지 못했습니다. 발견하신분이나 이 문제에 대해 이견이 있으신분은 꼭 리플을 달아주시면 감사드리겠습니다.)

이제라도 증상에 대해 기록해 두어야 될거 같아 정리해 올림-.-

  • 증상 & 분석
IE 에서는 eval 구문에 다음 스트링을 사용하였을 때 반환이 되지 않음.
"(function() {})"
다른 4대 브라우저(FF,Opera,Safari) 에서는 반환이 된다.

typeof eval("(function() {})");
가 IE 에서만 "undefined" 가 나온다
나머지 브라우저에서는 잘 된다 ("function" 반환)

IE가 eval 안에서 function 구문이 동작하지 않는 건 아닌거 같다
typeof eval("(function() {return function() {};})();")
은 또 "function" 으로 나오기 때문이다

  • 대안
그냥 function 을 eval 로 정리해서 쓰고 싶을 땐.. (function 내용을 스트링 값으로 선언하고 싶을 때?)
  1. function 구문을 eval 밖으로 빼고 소스 부분만 eval 로 넣는다.
    var a = eval("function() { var a=1; alert(++a); return a; }");
    대신
    var a = function() { eval("var a=1; alert(++a); return a; ") };
    를 사용한다.

  2. 그냥 eval 대신 Function 을 사용한다.
    var a = eval("function() { var a=1; alert(++a); return a; }");
    대신
    var a = new Function("var a=1; alert(++a); return a;");
    를 사용한다.
ps. 필자는 2번 방식을 좋아한다. 속도가 더 빠르기 때문이다. (똑같은 구문이라면 eval을 사용하는 것이 거의 속도가 큰 차이로 떨어진다. 그렇기 때문에 난 왠만하면 eval 은 쓰지 않는다.)
Posted by 아즈키
2008/05/14 09:27
업무 or 개인 프로젝트 시 자주 쓰게 되는 배열 변수 메소드를 정리하였습니다.

  • .sort
sort ([sortFunction: function]) : array
해당 배열 자신을 정렬한다. (기존 배열 변경)
sortFunction 을 생략하면 charCode 값을 기준으로 오름차순으로 정렬한다.
반환값은 자기 자신의 레퍼런스다. (non copy)
sortFunction 은 function 타입이며, 두개의 인자를 받는다. sortFunction 이 음수를 반환하면 그 두 아이템을 스왑한다. (양수나 0을 반환시에는 스왑하지 않는다.)
각 배열 아이템의 짝을 모두 수행하는 것은 똑같지만 수행하는 순서는 브라우저 별로 조금 다르다.
배열 ["a", "b", "c"] 를 .sort 메소드로 sortFunction 에 던질 경우 FF 는
sortFunction ("a", "b") -> sortFunction ("c", "a") -> sortFunction ("b", "a")
순으로 던지고, IE 에서는
sortFunction ("b", "b") -> sortFunction ("c", "a") -> sortFunction ("b", "a")
순으로 던진다.
sortFunction 이 무조건 음수를 반환하는 경우 결과값 또한 다르게 나온다. (물론 정상적인 비교를 수행하는 함수라면 같은 결과가 나오겠지만, 같은 코드가 다른 결과값을 낸 다는 사실에 흥미를 갖고 수행시켜보았다)
FF: ["c", "a", "b"]
IE: ["b", "c", "a"]

  • .reverse
reverse () : void
해당 배열 자신을 뒤집는다.

  • .push
push ([item1 : mixed [, item2 : mixed [, item3 : mixed, ...]]]) : item
푸시하고 마지막으로 추가된 아이템을 반환한다. (3개의 item을 추가했을 경우 item3을 반환)

  • .pop
pop () : item
팝한다. 비어있는 경우엔 undefined 를 반환한다.

  • .shift
shift () : item
시프트한다. 팝을 기능을 반대방향으로 수행한다.

  • .unshift
unshift ([item1 : mixed [, item2 : mixed [, item3 : mixed, ...]]]) : void
언시프트한다. 푸쉬의 기능을 반대방향으로 수행한다. 반환값은 브라우저별로 다르므로 사용하지 않는 것이 좋다. (예로 IE6 에서는 undefined 을 반환하지만, FF2 에서는 push와 마찬가지로 마지막 인자값을 반환한다)

  • .slice
slice (start : int [, end : int]) : array
지정된 부분을 복사해 새로운 배열을 반환한다. start는 포함하지만, end는 포함하지 않는다.
start 가 음수면 legnth + start 로 처리한다.
end 가 음수면 length + end 로 처리한다.
end 가 생략되면 배열의 끝까지 추출한다.
원래 배열변수에 영향을 주진 않는다. (복사해서 새로운 배열을 만듬)

  • .splice
splice (start : int, deleteCount : int, [item1 : mixed [, item2 : mixed [, item3 : mixed, ...]]]) : array
지정된 부분을 삭제하고, 그 부분에 새로운 아이템을 추가한다. 그리고 반환은 삭제된 아이템들을 가진 새로운 배열이다. (deleteCount 가 0 일 경우 빈 배열이, 1 일 경우 아이템이 1개인 배열이 반환)
deleteCount 가 0 이면 삭제되는 것이 없다.
item 을 생략하면 삭제만 수행한다.
배열 가운대 인자를 추가할 경우(deleteCount = 0)나 배열 중간에 있는 인자를 삭제할 경우(item 생략) 활용가능하다.

  • .concat
concat ([item1 : mixed [, item2 : mixed [, item3 : mixed, ...]]]) : array
배열에 아이템들을 추가한 새로운 배열을 반환한다. 푸쉬와 비슷하게 추가되지만, 기존 배열에 영향을 미치지 않고 새로운 배열을 반환한다는 점에서 다르다.
추가되는 순서는 당연히 왼쪽에서 오른쪽으로 순서대로이다.

  • .join
join ([separator : string]) : string
배열 요소들 사이에 separator 을 넣어서 하나의 string을 만들어 반환한다. separator 를 생략할 경우 ","(ascii 44)로 처리한다.


ps. 배열 변수는 레퍼런스 값이다.즉,
var a = b = [1];
var c = [1];
에서
a == b 는 true 지만 a == c 는 false 다.
Posted by 아즈키
2008/05/14 09:27
업무용(?)으로 종종 쓰고 있는, User preferences for colors 입니다.

개인적으로 보기 위해 테이블로 작성하였습니다.

  • URL
http://upct.azki.org/

  • 소개
윈도우에서 설정한(디스플레이 설정에서 화면배색 부분) 색상들을 HTML 에서 가져다 쓰는 것 입니다.
CSS2 에서 추가되었다고 합니다. 참고로 꼭 윈도우즈에서만 적용되는 건 아닙니다. 우분투에서 파이어폭스로 테스트 해본 결과 됩니다.
4 대 브라우저(FF,IE,Opera,Safari)에서 다 적용됩니다. 다만 윈도우 버전 Safari에서는 설정값을 윈도우즈의 것으로 가져오지 않는군요. (내부적으로 설정된 컬러를 쓰더군요, Mac 에서는 어떤지 모르겠습니다. 아마 잘 되겠죠?)

  • 기반 자료 출처
이용석의 JavaScript & DHTML (http://user.chollian.net/~spacekan/css/preferences-colors.htm)
아주 오래전부터 알고 다니는 사이트인데 지금 봐도 참 좋은 사이트입니다. ^^
Posted by 아즈키
2008/05/14 09:26
개인적으로 관심이 있는 분야라서 코드 실행시간을 체크하는 스크립트를 짰습니다..

  • URL
http://jpt.azki.org/ 입니다

  • 소개
code A 에 테스트할 코드를 넣고 Test! 버튼을 누르면 그 코드가 Loop Count 만큼 실행됩니다
그리고 그 시간을 체크하여 화면에 표시해주는 프로그램입니다

  • 예제
code A 에 다음 코드를 넣습니다
a = 0;
code B 에 다음 코드를 넣습니다
var a = 0;
Loop Count
500000
으로 적어줍니다

code A 밑의 버튼 Test! 를 누릅니다
저의 경우 (FF2) 다음과 같은 결과값이 나오네요.
*Func Time: 1015 ms
*All: 2187 ms
*Empty Func: 1172 ms
code B 밑의 버튼 Test! 를 누릅니다
*Func Time: 78 ms
*All: 1250 ms
*Empty Func: 1172 ms
*All 에 해당되는 것은 코드를 Loop Count 만큼 반복해서 수행시킬 때 걸린 시간이며, *Empty Func 에 해당되는 것은 코드를 넣지 않고 Loop Count 만큼 반복만 수행했을 때 걸린 시간입니다. 그러므로 실제적으로 코드에 의해 걸린 시간은 *Func Time 시간 = ( *Empty Func 시간 - *All 시간 ) 이라는 논리입니다 ^^

결론: 변수 하나를 쓰더라도 var 를 붙여 주어 지역변수로 명확하게 표현해 사용하는 것이 빠르군요^^;


  • 추후 업데이트될 수도 있는(?) 기능들..
    • 타이머를 두어서 너무 시간이 오래걸리는 코드를 중도에 멈춤?
    • 실행시간을 계산해서 적절한 count 반복.
    • 두가지 이상의 코드에 대해 결과값 비교.
    • 입력한 시간을 기준으로 그 시간동안 몇번 실행되는지 체크.
Posted by 아즈키
2008/05/14 09:26
array apc_cache_info  ([ string $cache_type  [, bool $limited  ]] )

인자값중 $cache_type 을 "user" 로 주면 apc_cache_info 를 사용해서 apc_store 나 apc_add 로 캐시한 내용들의 목록을 가져올 수 있다. 예제 코드와 그 출력된 결과는 다음과 같다.
<?php
$s = "example string";
apc_store('five', $s, 5);
apc_store('minute', $s, 60);
apc_store('noTTL', $s);
print_r(apc_cache_info('user'));
?>

more..

Array
(
[num_slots] => 2000
[ttl] => 0
[num_hits] => 0
[num_misses] => 0
[start_time] => 1196245414
[expunges] => 16
[mem_size] => 1644
[num_entries] => 3
[num_inserts] => 24
[file_upload_progress] => 1
[memory_type] => IPC shared
[locking_type] => file
[cache_list] => Array
(
[0] => Array
(
[info] => five
[ttl] => 5
[type] => user
[num_hits] => 0
[mtime] => 1196246312
[creation_time] => 1196246312
[deletion_time] => 0
[access_time] => 1196246312
[ref_count] => 0
[mem_size] => 546
)

[1] => Array
(
[info] => noTTL
[ttl] => 0
[type] => user
[num_hits] => 0
[mtime] => 1196246312
[creation_time] => 1196246312
[deletion_time] => 0
[access_time] => 1196246312
[ref_count] => 0
[mem_size] => 548
)

[2] => Array
(
[info] => minute
[ttl] => 60
[type] => user
[num_hits] => 0
[mtime] => 1196246312
[creation_time] => 1196246312
[deletion_time] => 0
[access_time] => 1196246312
[ref_count] => 0
[mem_size] => 550
)

)

[deleted_list] => Array
(
)

)


쉽게 리스트를 뽑아 올 수 있다. 하지만 문제가 있다. ttl을 설정할 시 ttl이 만료되어도 (즉 변수를 apc_fetch 를 통해 가져올 수 없는 경우에도) 리스트에 나타난다는 것이다. 성능상의 이유로 캐시리스트를 리플레시하지 않는 것 같다. 대신 apc_fetch 를 통해 해당 변수를 접근 한 후에는 리스트에서 사라진다. 실제적으론 ttl을 적용할려면 time() 으로 현재 시간을 얻어내서 배열의 mtime값과의 차가 ttl값을 넘기는지 확인하여야 한다. 목록에서 지우기 위해서는 해당 변수에 한번 접근을 하면 된다.(apc_fetch)
Posted by 아즈키
2008/05/14 09:25

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

2008/05/14 09:25

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.