객체의 생성이란 무엇인가, 플라톤의 이데아처럼 어딘가에 존재하는 것으로부터 현실에 필요한 속성을 부여하며 만들어지는 것인가, 아니면 옆에 있는 다른 객체를 복사하여 속성을 원하는 대로 고쳐쓰는 것인가?

개발자가 철학적인 사고를 하기 쉬운 것들은 이런 사고가 설계에 도움이 되기 때문아닌가?

c/c++의 struct, class를 생각하면, 텅빈 설계도 같은 것에서 메모리를 차지하면 만들어지는 것은 플라톤의 이데아 같은 것이 생각나고, prototype 객체를 우선만들고 복사한 다음 속성을 변경하여 쓰는 Javascript 같은 것은 후자와 같은 모양 아닐까?

몇 년 된 간단한 생각을 일단 적어 둠.

과거에 BASIC을 배울 땐 서브루틴과 함수가 분리되어 있었다. 포트란도 그러했다. 그러다가 C 언어를 배울 땐, return 유무에 따라 성질이 달라질 뿐 모두 함수로 통합이 됐다. 그러다가 JavaScript를 배울 땐, _객체_로서 함수 개념을 배우게 된다. 이 말은 함수와 자료가 통합되었다라고 말할 수 있다.

Javascript가 구현하는 함수객체는

function func1 ( ) {
  /* code */
}
  • func1()으로 쓰면 { ... } 안의 내용이 실행된다.
  • func1.abc = "def" 로 쓰면 func1를 객체 취급하여 'abc'라는 키를 추가한다.

이런 발상의 전환이 통합의 구체적인 모습이다.

  • func1.apply
  • func1.call
  • func1.bind

이런 함수는 func1 이라는 함수 객체가 만들어질 때 추가되는 속성이라고 생각하면된다.

짧은생각

Javascript와 python에서 제공하는 배열/리스트에서 특정 값의 위치를 찾는 비슷한 명령어로 각각 indexOf, index 라는 메소드가 있다. 이 둘은 찾지 못했을 때의 특성이 다른데,

  • Javascript: -1 을 return 한다.
  • Python: ValueError 예외를 발생한다.

언어를 다루다보면 이 둘은 묘한 선택의 순간을 만드는데, 전자는 매번 return 값을 확인해야하고, 후자는 앞 뒤로 예외 처리 구문을 넣어야한다.

Javascript/Java/C++ 계열에 익숙하다보면 정상적인 처리를 해야하는 상황을 예외를 발생시켜 점프하는 것에 약하지만 부담을 느낀다. 스택을 되돌리는 백그라운드 작업에 원하는 모든 리소스 해제는 잘 일어나는 것일까랄지, 단순히 값 하나만 비교하면 되는데 굳이 예외를 위해 백그라운드로 일어나는 작업을 컴파일러에게 맡겨야하나라든지 아무래도 부담스럽다.

Python 쪽에서는 없는 인덱스로 -1을 return 하는 순간 list[-1] 접근하는 것은 마지막 원소에 접근하는 방법이 되므로 아무래도 오류가 아닌 값처럼 인식될 수 있다. Javascript에서도 Array.slice(음수값)으로 python의 음수값 처럼 사용가능하지만 어쨌거나 기본적인 인덱스 연산으로는 접근이 불가능하므로 -1을 return 해도 큰 문제는 없다. python의 인덱스 연산은 -1에 대해 정상 작동하기 때문에 예외를 일으키는 방법밖엔 선택지가 없어 보인다.

추신

이 생각은

 50 function get_attrs(filter) {
 ...
 60   var attrs = [ 
 61       {name:"charset-configured", value: "utf-8"},
 62       {name:"charset-supported", value: "utf-8"},
          ....
 70   ];
 ...
 85   return attrs.filter(function (attr) {
 86     return ~filter.indexOf(attr.name)
 87   })
 88 }

이런 코드를 읽다가 86줄의 -1 에 대한 negate (~) bit operation을 보다가 꼬리를 문 생각임.

python dictionary 의 update 함수는 return 값으로 None을 되돌린다. 이거 dict 자신을 return 하면, copy와 더불어 더 간단한 method-chain으로 쉽게 쓸 수 있는 일이 많았을텐데, 왜 None인것이야?

요샌 일부러 마크다운편집이 가능하면 그걸 써보려고 노력한다. 오래 알아왔지만, 글 쓰는 일이 줄어들어 마크업이 할 일이 줄어 드니 영 느리다. 그래서 간단한 의식의 흐름대로 기술을 할 때, 쓰는 나와 읽는 당신의 관계에서 단순히 글의 연속으로 전달되는 것이 아닌, 강약이 전달되려면 강조 혹은 병렬적 정보전달은 필요한 것 아닌가 싶다.

머라고 주절 주절 쓰는 것은 사실 마크다운 문법을 테스트하기 위함이지 그 ^이상^도

이하

도 아니다. 어떤 문법은 것은 지원되지 않을 수도 있음을 고려해서 테스트해 본다.

문법을 익히는데 쓰는 글은

  1. 의미가 없어도 상관없고,
  2. 표현이 거칠거나
  3. 맥락을 뛰어 넘는 전개

가 이루어지기도 한다.

그래도 글의 모양을 갖추려면,

  • 가독성이 고려되어야하고
  • 적당한 길이어야하며
  • 무엇보다 독자가 실망하는 일이 없어야한다.

당신은 문법 연습을 하는 것이지, 실제 의미 있는 글을 쓰는 것이 아니기 때문이다.

오늘은 여기까지 연습하자.

npm, yarn을 설치했다면, bootstrap theme 변경을 위한 초간단 테스트를 할 수가 있다.

#!/bin/bash  
mkdir bootstrap-customizing  
cd bootstrap-customizing  
yarn init -y  
yarn add bootstrap node-sass  
mkdir -p public/css  
yarn node-sass --recursive --output public/css \  
  --source-map true --source-map-contents true \  
  node_modules/bootstrap/scss

bootstrap은 scss로 관리되고 있으므로 yarn(npm)으로 받아다가 바로 컴파일 해 볼 수가 있다. 위의 예는 directory 만들고, 빠르게 node package 를 초기화한 다음, bootstrap과 node-sass 컴파일러를 받은 후 directory to directory로 scss 파일을 css로 바꾸는 방법이다.

unzip 을 구현해 볼까?

하는 마음이 들었다. 다 뻘짓이 되긴 할텐데, 동기는 이렇다. 윈도우에서 한글로 된 파일을 압축하면 맥에서 잘 풀리지가 않는다.

7z으로 풀어 볼까?

7z도 안되는군.

7z 옵션중에 charset을 지정하는게 있더라.

CP949를 넣어보니 안된다.

아, 이게 머라고, 2020년에도 고통을 받아야하나.

huffman coding 이런거 봐야하나. 그 테이블 튜닝을 하면 성능이 더 좋아지려나? 실리콘밸리의 파이드파이퍼는 대체 뭘 쓴 거지?

아 놔..

  1. self 2020.03.08 23:37

    혹시 unarchiver를 시도해보셨나요?
    https://macpaw.com/the-unarchiver

    • Coolen 2020.03.12 22:25 신고

      https://apps.apple.com/us/app/the-unarchiver/id425424353?mt=12

      이건가요?

  2. self 2020.03.20 00:06

    답이 늦었네요. 이미 해보셨을 것 같은데, 예. 맞습니다.

PostScript 를 공부할 일이 있다. 프린터에 사용되는 스크립트 언어인데, 좀 보다 보니 재밌는 스택 기반 언어로 되어 있다. (Forth가 그런 스타일의 언어였구나) 화장실 비치해 두고 조금씩 보는 책 중에 비트코인 프로그래밍 책이 있다. 여기에도 컨트랙이 스크립트로 되어 있는데, 스택기반언어란다.

어쩌다 동시에, 두 종류의 새 언어를 보는데 비슷한 형식이다. 이런 우연이?

비슷한 스타일의 언어를 동시에 보는 것은 재밌는 일이지. 그냥 그렇다고.

 

가끔, man page 보다가 끝내면 화면이 사라져서 내용을 계속 보고 싶은 경우 짜증날 때가 있잖수? man 이 내부적으로 less를 사용하는데….

export LESS_IS_MORE=1

해두면 아주 옛날 방식으로 less가 돌아가므로 man 종료시 마지막 페이지가 유지됨.

Javascript에서 하나의 배열에서 다른 배열로 원소들을 옮기는 것은 내장 명령어로 구현되어 있지 않다. 따라서 구현을 직접해야하는데, 다음과 같이 한다. src 배열에서 dest 배열에 원소를 추가하면서 옮긴다고 하면,



Array.prototype.splice.bind(dest,dest.length,0).apply(dest, src.splice(0));


splice 함수는 배열의 내용을 자르는 것 뿐 아니라 새로운 원소들로 대치하는 것도 가능하다.


splice(start-index, [length, [insert element1, [insert element2 ...]]])


와 같은 방식으로 사용한다. length가 생략되면 배열 끝까지를 나타내므로


src.splice(0)


으로 모든 원소를 잘라낸 뒤, 


dest.splice( dest.length, 0, element1, element2, element3, ...)


로 element1, element2, element3... 을 추가하는 방법을 이용한다.


원소의 길이가 정해지지 않았으므로 apply를 사용해서 임의의 길이를 넘기는 방법을 이용한다. (apply는 첫번째 인자로 this 객체를 받고 두번째 인자로 arguments 를 받는다.)


bind 명령은 this 와 argument를 미리 고정하는 함수를 되돌리므로 apply에 넘기기 전에 dest, length, 0을 bind하여 맨 마지막에 뭔가를 추가하는 함수로 만들어준다.


자세한 설명은 여기까지.


+ Recent posts