기본 콘텐츠로 건너뛰기

글

라벨이 javascript인 게시물 표시

JavascriptCore in Swift 3 연습

//: Playground - noun: a place where people can play import UIKit import JavaScriptCore /* swift to javascript */ let str = "var double=function(x) { return x*2 };" let context = JSContext () context ?. evaluateScript ( str ) let getDouble = context ?. objectForKeyedSubscript ( "double" ) getDouble ?. call (withArguments: [ 1 ]). toString () *2를 하는 double이라는 function을 js에서 만들고 swift에서 인지 1을 넣어 2를 반환하는 예. 스위프트에서 자바스크립트 함수를 호출할 때는  objectForKeyedSubscript를 사용하여 함수명을 지정하고 call(withArguments: [, ... ]) 를 사용하여 인자를 지정한다. 결과값은 JSValue 형이므로 적당히 변환해서 사용한다. /* javascript to swfit */ let str2 = "postMessage('갔다가 다시 올꺼야')" let postMessageBlock : @convention(block) (AnyObject?) -> (AnyObject) = { (data) in     print(data)     return data! } context?.globalObject.setValue(unsafeBitCast(postMessageBlock, to: AnyObject.self), forProperty: "postMessage") context?.evaluateScript(str2) 반대의 경...

RxJS 에서 GameScene 을 구현하고 있다.

결과물은 여기에 http://jsbin.com/wuhega/edit?js,output Reactive Programming 의 장점+효용이 극대화되는 분야는 아무래도 게임이지 않을까 싶어서 짬을 내어 RxJS로 슈팅게임을 만들고 있다. 배경+플레이어+총알:  https://jsbin.com/worewow/edit?js,output 1+적+폭파에니메이션:  https://jsbin.com/modedic/edit?js,output 2+coffee+적 움직임등 :  https://jsbin.com/yobuka/ 대략, 이런 흐름으로 살을 조금씩 붙여가면서 올리고 있는데 어느정도 튜토리얼을 만들려는 생각으로 ECMA6를 가지고 시작을 했지만 {}, (), [] 괄호노동을 통한 손목터널증후근과 코딩하는 시간 만큼 쌍 맞추는 시간이 소모되는 자신을 발견하고 개인의 행복을 위해(...) 다시 coffeescript로 바꿔서 진행하고 있다. 살 것 같다. 아효. 아마도 곧 합쳐질 것 같지만 어느정도 내용물이 만들어졌으니 이것들을 감싸는 껍데기를 어떻게 만들지 코드를 짜면서 고민해보았다. 일단 크게 나누어 보기를 Splash Scene - 한번만 노출. 게임명과 제작자에 대해 알리는 화면 Title Scene - 게임시작을 위해 대기하는 화면 Game Scene - 실제 게임 화면 GameOver Scene - 게임을 더 이상할 수 없는 상황. 이정도로 잡고 1>2>3>4>2>... 의 반복 구조로 설계를 해보기로 했다. 아무런 레퍼런스도 없고 검색해 본 것도 없어서 매우 삽질이 예상되지만 그래도 FRP(Functional Reactive Programming)원칙에 충실하려고 노력했다. 먼저, 화면을 준비한다. 'use strict' ### setup canvas ### c = document.createElement 'canvas' ...

spectrum 에게 물어보세요. multiple option을 flat 하게 하고 싶어요.

질문: 쇼핑몰에서 옵션이 여러개 있는데 이걸 조합해서 보여주고 싶어요. 사이즈: s, m, l 색상: blue, red 길이: short, long 대상: girl, boy, woman, man 이라고 했을 때 s blue short woman 이런 식으로요. 답변: reduce 를 사용하세요. 풀이 예제  << 클릭하면 coffee/js 소스랑 결과값 모두 볼 수 있어요. Array::flatMap = (lambda) ->   @concat.apply [], @.map lambda v=[  ['s','m','l']  ['blue','red']  ['short', 'long']  ['girl', 'boy', 'woman', 'man'] ] console.log "result\n",   v.reduce (x1,x2)->     x1.map (o)->       x2.map (p)->         "#{o} #{p}"     .flatMap (o)->o 분류의 갯수는 상관없어요. 두개를 순서대로 합쳐야한다! 싶을 때는 reduce로 어떻게 해봐야지! 하고 시작하는게 좋아요. 먼저 ['s', 'm', 'l'] 하고 ['blue', 'red'] 만 놓고 보자구요. map으로 이중 루프를 돌면서 둘을 조합하면 되겠지요? ['s', 'm', 'l'].map (o)->   ['blue', 'red'].map (p)->     "#{o} #{p}" 근데 이렇게 하면 [["s blue","s r...

[삽질주의] js에선 object를 어떻게 확장하는가? .map 만들기.

http://spectrum.egloos.com/5580651 옛날 글 소환인데 map을 object 에서도 한번 해볼려고 이렇게 시도해 보았다. > Object.defineProperty(Object.prototype, "map", {value: function(fn) {   for (idx in this) this[idx]=fn(this[idx]); return this; } }); > q={a:1, b:2} > q.map(v=>v+1) Object {a: 2, b: 3} ECMA5부터 Object.defineProperty 를 쓸 수 있고 prototype 삽질을 막을 수 있다. > q={a:1, b: {c: 2, d: 4}} > Object.defineProperty(Object.prototype, "map", {value: function(fn) {   let map=(f,arr)=>{     for (idx in arr)         arr[idx]=typeof arr[idx]==="object" && map(f,arr[idx]) || f(arr[idx]);     return arr;   }   return map(fn, this); }}); > q.map(v=>v+1) Object {a: 2, b: Object} a:2 b:Object   c:3   d:5 뭐 의도한대로 잘 나오긴 한다. value 인 경우만 fn을 실행하고 object면 재귀를 사용한다. 뭐 array만 들어와도 이건 망하겠네; google 에서 왜 [[a,2], [b,3]] 따위 자료 구조를 썼는지 어느정도 이해가 된다.

UI깎는 노인-Making a knob for Mobile

Knob, 흔히들 Dial 이라고 말하는 전통적인 인터페이스가 있다. 돌리고~돌리~고~ ( 출처 ) webAudio를 하다보니 (  http://jsbin.com/hacota ,  http://output.jsbin.com/tidoqi  등등) 직관적인 UI 컨트롤러가 필요해서 잠깐 찾다가 이럴게 아니라 최소한의 요소만 뽑아내서 만들어보기로 함. 목표는 PC/Android/iOS 모두 잘 작동하도록 하는 것. 구현할 기능을 생각해보면 현재 값을 시각화하는 요소가 있을 것 - 위 사진에서처럼 음각으로 만든 홈. 경계값이 있을 것 - 12시 방향 기준으로 -140도~140도까지 클릭 후 드래그 시만 움직이고 즉각적으로 반응 정도로 잡고 일단 SVG로 원을 두개 그려본다.       <circle cx="6em" cy="6em" r="5em"/>       <circle class="handle" cx="6em" cy="3em" r="0.6em"/> 단위는 서로 다른 디바이스에서도 잘 보이도록 em을 써서 만든다. 1em은 글자 한글자 높이정도의 단위인데 해상도에 대한 걱정을 덜어줘서 참 편하다. em은 이정도, 즉 1em=1글자 높이 이걸 돌려주기만 하면 된다. 돌리는 건 뭘로? css transform / rotate 를 사용한다. 두 개의 원을 그룹으로 묶어서 돌리자.     <g class="jog" style="-webkit-transform: rotate3d(0,0,1,{{knob}}deg); transform: rotate3d(0,0,1,{{knob}}deg)">       <circle cx="6em" cy="6em" r="5em...

node.js 를 위한 vim 환경 설정.

tmux를 쓰다보니 vim 환경 설정 셋을 문득 만들어 보고 싶었다. 1. 일단 vim 먼저 받고 sudo apt-get install vim 2. manage your runtimepath 관리용 pathgen 설치 mkdir -p ~/.vim/autoload ~/.vim/bundle; \ curl -Sso ~/.vim/autoload/pathogen.vim \     https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim 3. ~/.vimrc 없을테니 아래와 같이 생성. tab/indent 간격은 2에 탭 대신 space로 쓰기 위해 expandtab 추가 execute pathogen#infect() syntax on filetype plugin indent on set tabstop=2 set shiftwidth=2 set softtabstop=2 set expandtab 4. 아무 js 나 vim 으로 열어서 color 적용여부 확인 5. sensible plugin 설치 git clone git://github.com/tpope/vim-sensible.git ~/.vim/bundle/vim-sensible 6. node bundle 설치 git clone https://github.com/moll/vim-node.git ~/.vim/bundle/node 7. coffeescript bundle 설치 git clone https://github.com/kchmck/vim-coffee-script.git ~/.vim/bundle/vim-coffee-script/ 8. zen code 보다 더 좋은 Emmet 설치 - ctrl+y+, 로 활성화 git clone http://github.com/mattn/emmet-vim.git ~/.vim/bundle/emmet-vim 9. less 도 활성화 ...

Meteor에서 REST API를 사용하는 방법 #2

server쪽 API를 router package를 사용해 쓰다보면 header 같은 걸 다루거나 할땐 너무 단순하게 만들어서 곤란할 수 있다. 이전에도 다룬 적( http://spectrumdig.blogspot.kr/2012/08/meteor-rest.html )이 있지만 __meteor_bootstrap__ 객체를 통해 접근하면 node.js 식의 접근이 가능하다. Meteor update와 함께 Npm 객체가 생겼으니 이를 이용해 connect 객체를 사용해보자 http://www.slideshare.net/cjoudrey/building-your-first-node-app-with-connect-express 위 슬라이드를 한번 보면 이해에 도움이 될 것이다. WebApp.connectHandlers 가 connect.createServer()라는 걸 기억하면 된다. connect = Npm.require 'connect' server = WebApp.connectHandlers server.use connect.router (app)-> app.get '/info', (req,res)-> res.end "info" app.get '/user/:id', (req,res)-> res.end "user id: #{req.params.id}" 이와 같은 코드를 server 디렉토리에 안에 넣거나 Meteor.isServer일때 실행하도록 하자. 파일 업로드나 쿼리 문자열 처리(ex: ?a=1&b=c)하려면 각각 bodyParser( http://www.senchalabs.org/connect/bodyParser.html ) 와 query( http://www.senchalabs.org/connect/query.html )를 추가하는 것이 좋다. 위의 해당 링크에 보면 소스까지 공개 해놓아서 이해하기 쉬우니 ...

Unicode 2.0 에서 한글의 이해

요즘 SNS이나 SNG등등 기계적으로 문장을 생성하는 프로그램들이 넘쳐나는 시대에 의외로 한글처리를 제대로는 프로그램들이 드물구나 하는 생각에 간단한 한글 자소 분석기를 만들어보았다. 링크는 이쪽( http://jsbin.com/ofoqal/10/edit ) 애초에 만든 목적은 다음과 같다. 조사처리(은/는, 이/가, 을/를 등등)를 위해 단어의 마지막 글자의 종성을 조사하기 위함인데 예문을 들어보자면 "준기 는 강남에서 사진 을 찍었다." "예슬 은 홍대에서 식사 를 했다." "슬기 가 대화방에서 나갔습니다." "준기님은 강남에서 사진님을 찍으셨습니다 고갱님" 이라고 말하면 할말 없다. 한국식 소프트웨어(꼭 소프트웨어가 아니더라도)의 특징이자 장점이 무엇이냐라고 물으면 귀찮을 정도로 깨알같은 디테일이라고 대답할텐데 한글 기계화 작업에 대한 중요성은 프로그램을 만드는 사람들에게도 별로 중요하게 다가오지 않나보다. 에또 사설이 길었다. 한때 우리는 한글코드체계의 비표준 숲속에서 너무도 괴로운 나날들을 보낸 역사가 있다. KSC5601부터 시작해서 Microsoft통합형한글을 지나 Unicode 2.0의 시대가 왔다. 개인적으로 UTF-8을 사용하지 않고 EUC-KR이나 CP949를 쓰는 제품이나 서비스의 업체의 대표/관계자에게 1억 미만의 벌금 혹은 3년 이하의 금고형의 실형을 내려줬으면 할 정도로 너무나 많은 사람들을 불행하게 하고 막대한 비용을 지출한 악의 근원이라고 생각한다. 하지만 광명이 왔다. 기계적으로 납득이 가능한 검색 및 정렬이 용이한 Unicode 의 시대가 열렸단 말이다. 지금 당신이 복사해서 붙이고 있는 팁들 보다 훨씬 쉽고 명쾌하니 다음 그림을 한번 보자. (출처: http://www.w3c.or.kr/i18n/hangul-i18n/ko-code.html ) 어떤가? 무쟈게 쉽지 않은가? 현대 한글은 초성 ...

map과 reduce를 사용하여 distinct(group by) 하는 방법

oracle 같은 RDB 를 다루던 시절엔 user | dept ----------- john | 0000 tom | 0001 jack | 0000 jane | 0001 과 같은 형태의 테이블일때 부서의 목록을 뽑아 내고자 group by 나 distinct 를 사용하여 dept ----- 0000 0001 이와 같이 뽑아내곤 했는데 noSQL 을 사용하거나 array collection 형태의 데이터를 다룰때에도 이런 작업을 해야할 경우가 있다. 일단 예제로 다뤄볼 대상 collection 의 구조를 가정해 보자. documents = [   {     _id: "........",     message: "......",     user : {       _id: "........",       profile: {         displayName: "....."       }     } ] 흔한 게시판 형태의 데이터 구조라고 볼 수 있는데 각 documents 마다 고유한 _id 를 가지고 있고 해당 documents 를 작성한 user 객체가 각각 들어있는 경우라고 볼 수 있다. 그렇다면 documents 를 작성한 user 의 목록을 뽑아낼 수는 없을까? node 콘솔이나 브라우저용 개발 툴에서 복사 붙이기 용으로 코드를 예제 코드를 한번 넣어보자면 documents = [ { _id: "doc0001", message: "document 01", user: { _id: "user0001", profile: { displayName: "john", } } }, { _id: "doc0002", message: "document 02", us...

meteor 0.3.9 에서 사용자 인증을 써보자.

예전에 everyAuth 에 대한 글을 쓴적이 있는데 https://github.com/meteor/meteor/wiki/Getting-Started-with-Auth meteor wiki에 위와 같은 글이 있더라. 발빠르다 meteor. 투자받더니 탄력이 붙었는지 쭉쭉 잘나가는군. 일단 meteor 설치부터 다시하자. 이전에 Quick start 가이드대로 curl https://install.meteor.com | /bin/sh 이렇게 설치했지만. 이번엔 git 에서 auth Branch를 따서 갈 것이므로 수동 설치하자. git clone git://github.com/meteor/meteor.git cd meteor 수동설치래봤자 적절한 곳에 clone 하고 인스톨 하는게 전부인데. auth는 다른 branch에 있기 때문에 일단 clone 하고 해당 경로에 진입만한 상태에서 git branch -r 로 리모트 브랜치를 확인해보자   origin/HEAD -> origin/master   origin/auth   origin/auth-email   origin/auth-test-isolation   origin/auth-twitter   origin/avital   origin/avital-remove   origin/avital-watch   origin/david-handlebars   origin/dev-bundle-bump   origin/devel   origin/email   origin/forms   origin/jade   origin/master   origin/release-0.1   origin/release-0.1-templates   origin/spark   origin/spiderable ...

javascript에서 forEach의 성능 문제

http://jsperf.com/for-vs-foreach/9  를 보고 forEach가 정말 그렇게 느려? 라고 생각이 들어서 node 커맨드라인을 열고 아래와 같이 처 넣고 실행. 어짜피 IE에서도 안되는거 Array를 prototype 확장하여 forEach 를 만들어서 쓰곤 했다. Array.prototype.forEach=function(callback) {   for (var i=0,len=this.length; i<len; i++) {     callback(this[i], i);   } } 그래서 이것도 넣어서 같이 돌려봤다. -------------------------- var i, values = [], sum = 0; for (i = 0; i < 10000; i++) {  values[i] = i; } function add(val) {   sum += val; } var itercount =2000; sum=0; time = +new Date(); for (var _i=itercount; _i>=0; _i--) {   values.forEach(add); } console.log("forEach legacy:"+ (+new Date()-time)); sum=0; time = +new Date(); for (var _i=itercount; _i>=0; _i--) {   for (i = 0; i < values.length; i++) {     add(values[i]);   } } console.log("simple for:"+ (+new Date()-time)); Array.prototype.forEach2=function(callback) {   for (var i=0,len=this.length; i<len; i++...

mysql password() function 을 node.js 에서 사용하려면

기존 mysql 로 다른 사람이 구축한 테이블의 데이터를 mongodb 로 이전하려고 보니 사용자 암호와 주민등록번호 뒷자리가 암호화 되어 있었다. stackoverflow 를 뒤져보니 http://stackoverflow.com/questions/5894193/implementation-of-mysqls-password-function-in-java 이런게 있더라. 단순하게 sha1 으로 두번 암호화하고 대문자화 한담에 맨 앞에 * 붙여주는게 전부인데 이상하게 잘 안되더라. 자바를 한동안 안봐서 그런가 눈알에 힘 빡주고 보니 두번 복호화 하는 과정에서 첫번째 복호화한 값은 byte[] 형이란게 보이더라 http://nodejs.org/api/crypto.html#crypto_hash_update_data_input_encoding node.js 에는 'sha1', 'md5', 'sha256', 'sha512' 와 같은 다양한 형태의 복호화 알고리즘을 지원하는 crypto package가 있다. 그래서 콘솔을 열고 이렇게 쳐 보았다. # node > var crypto = require('crypto'); > var first=crypto.createHash('sha1').update('test').digest(' binary '); > var second=crypto.createHash('sha1').update(first).digest(' hex '); > "*"+second.toUpperCase(); '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29' mysql 에서 확인해보았다. > select password('test') *94BDCEBE19083CE2A1F959FD02...

Meteor 에서 Client 와 Server 가 서로 자료 전달하는 방법.

javascript 를 한판에 같이 넣어도 되지만 client 와 server 로 각각 폴더를 분리해서 쓰고 있다. server 쪽에서 Meteor 객체의 methods 를 통해 함수를 정의하고 client 에서 해당 함수명을 키값으로 call 을 사용하고 callback을 받는 구조다. client side : Meteor.call('login', $('#login').val(), $('#password').val(), function(retVal) {   console.log("result:"+retVal); }); call의 경우 인자는 몇개든지 상관은 없다. 마지막에 callback만 잊지말자. server side : Meteor.methods({   login: function(username, password) {     console.log("" + username + " is connected");     // do something     return 'ok';   } }); 클라이언트 서버간 자료교환을 수동으로 하는 것도 상당히 간편하다 주저하지 말고 생각하는 걸 쏟아보자. http://docs.meteor.com/#meteor_methods 자세한 내용은 위의 링크를 참조.

Meteor로 진지하게 접근해 보는 Rapid Prototyping web application

일단 진지진지 열매 10개 먹고 시작하자. 1. 빠르게 만들고 2. 적게 코드를 쓰고 3. 시각적으로 보기 좋을 것 필요한 건 뭐? 1. 빠르게 만들 프레임 워크 2. 적게 코드를 쓸 수 있는 언어 3. 시각적인 뼈대를 받쳐줄 템플릿 내가 선택한 건? 1. Meteor 2. Coffeescript + Less 3. Twitter bootstrap 자 시작해볼까? 미리 설치해야할 것들 1. node.js + npm ( http://nodejs.org/#download ) 2. meteor ( http://meteor.com/ ) 3. Coffeescript (npm install -g coffee-script) 4. jQuery plug-in (meteor add jquery) 5. less plug-in (meteor add less) 6. coffeescript plug-in (meteor add coffeescript) 7. bootstrap plug-in (meteor add bootstrap) 4,5,6은 meteor 용 plug-in들인데 매번 less나 coffeescript를 컴파일하지 않아도 클라이언트쪽에서 쓸 수 있다는 점이 엄청 편하다. 글 쓰는 도중 meteor 가 0.3.4로 업데이트 되면서 bootstrap지원이 추가되었다. 만세! 일단 meteor 가 기본으로 생성한 css와 javascript 를 삭제하고 less와 coffeescript 로 교체하자. <프로젝트명>.coffee 파일은 이정도로 시작하자. # make Posts into global variable @Posts = new Meteor.Collection 'Posts' # when client if Meteor.is_client $.extend Template.add, events: 'click #add': -> Posts.i...