diff options
Diffstat (limited to 'ko-kr')
-rw-r--r-- | ko-kr/bash-kr.html.markdown | 382 | ||||
-rw-r--r-- | ko-kr/bf-kr.html.markdown (renamed from ko-kr/brainfuck-kr.html.markdown) | 3 | ||||
-rw-r--r-- | ko-kr/erlang-kr.html.markdown | 333 | ||||
-rw-r--r-- | ko-kr/javascript-kr.html.markdown | 3 | ||||
-rw-r--r-- | ko-kr/json-kr.html.markdown | 80 | ||||
-rw-r--r-- | ko-kr/kotlin-kr.html.markdown | 376 | ||||
-rw-r--r-- | ko-kr/lua-kr.html.markdown | 2 | ||||
-rw-r--r-- | ko-kr/markdown-kr.html.markdown | 308 | ||||
-rw-r--r-- | ko-kr/vim-kr.html.markdown | 235 | ||||
-rw-r--r-- | ko-kr/xml-kr.html.markdown | 168 | ||||
-rw-r--r-- | ko-kr/yaml-kr.html.markdown | 172 |
11 files changed, 2057 insertions, 5 deletions
diff --git a/ko-kr/bash-kr.html.markdown b/ko-kr/bash-kr.html.markdown new file mode 100644 index 00000000..8e271d1f --- /dev/null +++ b/ko-kr/bash-kr.html.markdown @@ -0,0 +1,382 @@ +--- +category: tool +tool: bash +contributors: + - ["Max Yankov", "https://github.com/golergka"] + - ["Darren Lin", "https://github.com/CogBear"] + - ["Alexandre Medeiros", "http://alemedeiros.sdf.org"] + - ["Denis Arh", "https://github.com/darh"] + - ["akirahirose", "https://twitter.com/akirahirose"] + - ["Anton Strömkvist", "http://lutic.org/"] + - ["Rahil Momin", "https://github.com/iamrahil"] + - ["Gregrory Kielian", "https://github.com/gskielian"] + - ["Etan Reisner", "https://github.com/deryni"] + - ["Jonathan Wang", "https://github.com/Jonathansw"] + - ["Leo Rudberg", "https://github.com/LOZORD"] + - ["Betsy Lorton", "https://github.com/schbetsy"] + - ["John Detter", "https://github.com/jdetter"] +translators: + - ["Wooseop Kim", "https://github.com/linterpreteur"] +filename: LearnBash-kr.sh +lang: ko-kr +--- + +Bash는 유닉스 셸의 이름이며, 리눅스와 맥 OS X의 기본 셸로 그리고 GNU 운영체제를 위한 셸로서 배포되었습니다. +이하의 거의 모든 예시들은 셸 스크립트의 일부이거나 셸에서 바로 실행할 수 있습니다. + +[(영어) 이곳에서 더 알아보세요.](http://www.gnu.org/software/bash/manual/bashref.html) + +```bash +#!/bin/bash +# 스크립트의 첫 줄은 시스템에게 스크립트의 실행법을 알려주는 '셔뱅'입니다. +# https://ko.wikipedia.org/wiki/%EC%85%94%EB%B1%85 +# 이미 보았듯이 주석은 #으로 시작합니다. 셔뱅 또한 주석입니다. + +# 간단한 헬로 월드 +echo 헬로 월드! + +# 각각의 명령어는 개행 혹은 세미콜론 이후에 시작됩니다. +echo '첫번째 줄'; echo '두번째 줄' + +# 변수 선언은 다음과 같습니다. +Variable="어떤 문자열" + +# 하지만 다음은 틀린 형태입니다. +Variable = "어떤 문자열" +# Bash는 Variable이 실행해야 하는 명령어라고 판단할 것이고, 해당 명령어를 찾을 +# 수 없기 때문에 에러를 발생시킬 것입니다. + +# 다음도 같습니다. +Variable= '어떤 문자열' +# Bash는 '어떤 문자열'이 실행해야 하는 명령어라고 판단하여 에러를 발생시킬 것입니다. +# (이 경우에 'Variable=' 부분은 '어떤 문자열' 명령어의 스코프에서만 유효한 +# 변수 할당으로 해석됩니다.) + +# 변수 사용은 다음과 같습니다. +echo $Variable +echo "$Variable" +echo '$Variable' +# 할당, 내보내기 등 변수 자체를 사용할 때에는 $ 없이 이름을 적습니다. +# 변수의 값을 사용할 때에는 $를 사용해야 합니다. +# 작은 따옴표는 변수를 확장시키지 않는다는 사실에 주의하세요. +# (역자 주: '$Variable'은 변수 Variable의 값이 아닌 문자열 "$Variable"입니다.) + +# 인수 확장은 ${ }입니다. +echo ${Variable} +# 이는 인수 확장의 간단한 예시입니다. +# 인수 확장은 변수로부터 값을 받아 그 값을 "확장"하거나 출력합니다. +# 확장을 통해 인수나 그 값이 변경될 수 있습니다. +# 이하는 확장에 대한 다른 예시들입니다. + +# 변수에서의 문자열 치환 +echo ${Variable/Some/A} +# 처음으로 나타나는 "Some"를 "A"로 치환합니다. + +# 변수의 부분열 +Length=7 +echo ${Variable:0:Length} +# 변수 값에서 처음 7개 문자만을 반환합니다. + +# 변수의 기본값 +echo ${Foo:-"Foo가_없거나_비어_있을_때의_기본값"} +# null(Foo=) 값이나 빈 문자열(Foo="")일 경우에만 작동합니다. 0은 (Foo=0)은 0입니다. +# 기본값을 반환할 뿐 변수 값을 변경하지는 않는다는 사실에 주목하세요. + +# 중괄호 확장 { } +# 임의의 문자열을 생성합니다. +echo {1..10} +echo {a..z} +# 시작 값으로부터 끝 값까지의 범위를 출력합니다. + +# 내장 변수 +# 유용한 내장 변수들이 있습니다. +echo "마지막 프로그램의 반환값: $?" +echo "스크립트의 PID: $$" +echo "스크립트에 넘겨진 인자의 개수: $#" +echo "스크립트에 넘겨진 모든 인자: $@" +echo "각각 변수로 쪼개진 스크립트 인자: $1 $2..." + +# echo와 변수의 사용법을 알게 되었으니, +# bash의 기초를 조금 더 배워봅시다! + +# 현재 디렉토리는 `pwd` 명령어로 알 수 있습니다. +# `pwd`는 "print working directory(작업 디렉토리 출력)"의 약자입니다. +# 내장 변수`$PWD`를 사용할 수도 있습니다. +# 이하는 모두 동일합니다. +echo "I'm in $(pwd)" # `pwd`를 실행하여 문자열에 보간 +echo "I'm in $PWD" # 변수를 보간 + +# 터미널이나 결과의 출력물이 너무 많다면 +# 명령어 `clear`를 이용해 화면을 지울 수 있습니다. +clear +# 컨트롤+L 또한 화면을 지울 수 있습니다. + +# 입력 값 읽기 +echo "이름이 뭐에요?" +read Name # 변수 선언이 필요 없다는 데 주목하세요. +echo $Name님, 안녕하세요! + +# 평범한 if 구조도 있습니다. +# 'man test'로 조건문에 대해 더 알아보세요. +if [ $Name != $USER ] +then + echo "사용자가 아닙니다." +else + echo "사용자입니다." +fi + +# $Name이 비어 있다면, bash는 위의 조건을 다음과 같이 인식합니다. +if [ != $USER ] +# 이는 문법적으로 유효하지 않습니다. +# 따라서 bash에서 비어 있을 수 있는 변수를 "안전하게" 사용하는 법은 다음과 같습니다. +if [ "$Name" != $USER ] ... +# $Name이 비어 있다면 bash는 +if [ "" != $USER ] ... +# 와 같이 인식하여 예상한 대로 동작합니다. + +# 조건부 실행도 있습니다. +echo "항상 실행" || echo "첫 명령어가 실패해야 실행" +echo "항상 실행" && echo "첫 명령어가 실패하지 않아야 실행" + +# if문과 함께 &&와 ||을 사용하려면, 대괄호가 여러 쌍 필요합니다. +if [ "$Name" == "철수" ] && [ "$Age" -eq 15 ] +then + echo "$Name이 철수이고 $Age가 15일 때 실행" +fi + +if [ "$Name" == "민희" ] || [ "$Name" == "상민" ] +then + echo "$Name이 민희이거나 상민일 때 실행" +fi + +# 표현식은 다음 형식으로 표기됩니다. +echo $(( 10 + 5 )) + +# 다른 프로그래밍 언어와는 달리, bash는 셸이기 때문에 현재 디렉토리의 컨텍스트에서 +# 실행됩니다. 현재 디렉토리의 파일과 디렉토리를 ls 명령어로 나열할 수 있습니다. +ls + +# 다음은 실행을 제어하는 옵션의 예시입니다. +ls -l # 모든 파일과 디렉토리를 분리된 줄에 나열 +ls -t # 디렉토리 내용을 마지막으로 수정된 날짜(내림차순)에 따라 정렬 +ls -R # 이 디렉토리와 그 안의 모든 디렉토리에 대해 재귀적으로 `ls` 실행 + +# 이전 명령어의 결과는 다음 명령어에 입력될 수 있습니다. +# grep 명령어는 입력을 주어진 패턴에 따라 필터링합니다. 다음은 현재 디렉토리의 +# .txt 파일을 나열하는 방법입니다. +ls -l | grep "\.txt" + +# `cat`을 이용해 stdout으로 파일을 출력합니다. +cat file.txt + +# `cat`으로 파일을 읽을 수도 있습니다. +Contents=$(cat file.txt) +echo "파일 시작\n$Contents\n파일 끝" + +# `cp`를 이용해 파일이나 디렉토리를 다른 곳으로 복사할 수 있습니다. +# `cp`는 원본의 새로운 버전을 생성하므로 사본을 편집하는 것은 +# 원본에 영향을 주지 않으며 그 반대도 마찬가지입니다. +# 목표 위치에 이미 파일이 있다면 덮어쓰게 됩니다. +cp srcFile.txt clone.txt +cp -r srcDirectory/ dst/ # 재귀적으로 복사 + +# 컴퓨터 간에 파일을 공유하려고 한다면 `scp` 혹은 `sftp`를 사용합니다. +# `scp`는 `cp`와 매우 유사하게 동작하며 +# `sftp`는 더 상호작용적입니다. + +# `mv`로 파일 혹은 디렉토리를 다른 곳으로 이동합니다. +# `mv`는 `cp`와 유사하지만 원본을 삭제합니다. +# 또한 `mv`로 파일의 이름을 바꿀 수도 있습니다. +mv s0urc3.txt dst.txt # sorry, l33t hackers... + +# bash는 현재 디렉토리의 컨텍스트에서 실행되기 때문에, 다른 디렉토리에서 명령어를 +# 실행하고 싶으실 수 있습니다. cd를 이용해 위치를 변경합니다. +cd ~ # 홈 디렉토리로 변경 +cd .. # 한 디렉토리 위로 이동 + # (즉 /home/username/Downloads에서 /home/username로) +cd /home/username/Documents # 특정 디렉토리로 이동 +cd ~/Documents/.. # 아직도 홈 디렉토리... 아닌가?? + +# 서브셸로 디렉토리를 넘어서 작업할 수도 있습니다. +(echo "처음엔 여기 $PWD") && (cd 어딘가; echo "이제는 여기 $PWD") +pwd # 아직도 첫 디렉토리에 있음 + +# `mkdir`로 새 디렉토리를 만듭니다. +mkdir myNewDir +# `-p` 플래그는 필요하다면 해당 디렉토리의 경로 중간에 있는 디렉토리를 생성합니다. +mkdir -p myNewDir/with/intermediate/directories + +# (stdin, stdout, stderr로) 명령어의 입출력을 리디렉션할 수 있습니다. +# stdin의 내용을 ^EOF$까지 읽고 hello.py에 그 내용을 덮어씁니다. +cat > hello.py << EOF +#!/usr/bin/env python +from __future__ import print_function +import sys +print("#stdout", file=sys.stdout) +print("#stderr", file=sys.stderr) +for line in sys.stdin: + print(line, file=sys.stdout) +EOF + +# stdin, stdoutk, stderr을 다양한 방법으로 리디렉션하여 hello.py를 실행합니다. +python hello.py < "input.in" +python hello.py > "output.out" +python hello.py 2> "error.err" +python hello.py > "output-and-error.log" 2>&1 +python hello.py > /dev/null 2>&1 +# 출력 오류는 이미 파일이 있을 경우 덮어쓰지만, +# 덮어쓰는 대신에 내용에 추가하고 싶다면 ">>"를 사용합니다. +python hello.py >> "output.out" 2>> "error.err" + +# output.out에 덮어쓰고, error.err에 추가하고, 줄을 세기 +info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err +wc -l output.out error.err + +# 명령어를 실행하고 그 파일 디스크립터를 출력 (예: /dev/fd/123) +# man fd 참고 +echo <(echo "#helloworld") + +# output.out을 "#helloworld"으로 덮어쓰기 +cat > output.out <(echo "#helloworld") +echo "#helloworld" > output.out +echo "#helloworld" | cat > output.out +echo "#helloworld" | tee output.out >/dev/null + +# 임시 파일을 지울 수 있습니다. ('-i'로 대화식 실행) +# 경고: `rm` 명령어는 되돌릴 수 없습니다. +rm -v output.out error.err output-and-error.log +rm -r tempDir/ # 재귀적으로 삭제 + +# 다른 명령어에서 $()을 이용해 명령어를 치환할 수도 있습니다. +# 다음 명령어는 현재 디렉토리의 파일 및 디렉토리의 수를 표시합니다. +echo "$(ls | wc -l)개 항목이 있습니다." + +# 백틱(``)을 이용할 수도 있지만 이 방식을 이용하면 중첩할 수 없기 때문에 +# $()을 사용하는 것이 더 좋습니다. +echo "`ls | wc -l`개 항목이 있습니다." + +# 자바나 C++의 switch와 비슷하게 동작하는 case 문을 사용할 수 있습니다. +case "$Variable" in + # 충족시킬 조건을 나열 + 0) echo "0입니다.";; + 1) echo "1입니다.";; + *) echo "널이 아닌 값입니다.";; +esac + +# for 반복문은 주어진 인자만큼 반복합니다. +# 다음은 $Variable을 세 번 출력합니다. +for Variable in {1..3} +do + echo "$Variable" +done + +# 혹은 "전통적인 for 반복문" 방식을 쓸 수도 있습니다. +for ((a=1; a <= 3; a++)) +do + echo $a +done + +# 파일에도 적용될 수 있습니다. +# 다음은 file1과 file2에 'cat' 명령어를 실행합니다. +for Variable in file1 file2 +do + cat "$Variable" +done + +# 혹은 명령어의 결과에도 이용할 수 있습니다. +# 다음은 ls의 결과를 cat합니다. +for Output in $(ls) +do + cat "$Output" +done + +# while 반복문 +while [ true ] +do + echo "반복문 몸체" + break +done + +# 함수를 정의할 수도 있습니다. +# 정의: +function foo () +{ + echo "인자는 함수 인자처럼 작동합니다. $@" + echo "그리고 $1 $2..." + echo "함수입니다." + return 0 +} + +# 혹은 단순하게 +bar () +{ + echo "함수를 선언하는 다른 방법" + return 0 +} + +# 함수 호출 +foo "My name is" $Name + +# 몇 가지 유용한 명령어를 알아두면 좋습니다. +# file.txt의 마지막 10줄 출력 +tail -n 10 file.txt +# file.txt의 첫 10줄 출력 +head -n 10 file.txt +# file.txt 줄 별로 정렬 +sort file.txt +# 중복되는 줄을 생략하거나 -d를 이용하여 보고 +uniq -d file.txt +# ',' 문자 이전의 첫 열만 출력 +cut -d ',' -f 1 file.txt +# file.txt에서 'okay'를 모두 'great'로 교체 (정규식 호환) +sed -i 's/okay/great/g' file.txt +# file.txt에서 정규식에 맞는 모든 줄을 stdin에 출력 +# 다음 예시는 "foo"로 시작해 "bar"로 끝나는 줄 출력 +grep "^foo.*bar$" file.txt +# "-c" 옵션을 넘겨 줄 번호를 대신 출력 +grep -c "^foo.*bar$" file.txt +# 다른 유용한 옵션 +grep -r "^foo.*bar$" someDir/ # 재귀적으로 `grep` +grep -n "^foo.*bar$" file.txt # 줄 번호 매기기 +grep -rI "^foo.*bar$" someDir/ # 재귀적으로 `grep`하되 바이너리 파일은 무시 +# 같은 검색으로 시작하여 "baz"를 포함하는 줄만 필터 +grep "^foo.*bar$" file.txt | grep -v "baz" + +# 정규식이 아니라 문자열로 검색하고 싶다면 +# fgrep 혹은 grep -F +fgrep "foobar" file.txt + +# trap 명령어로 스크립트에서 신호를 받을 때 명령어를 실행할 수 있습니다. +# 다음 명령어는 셋 중 한 가지 신호를 받으면 rm 명령어를 실행합니다. +trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM + +# `sudo`를 통해 슈퍼이용자로 명령어를 실행합니다. +NAME1=$(whoami) +NAME2=$(sudo whoami) +echo "$NAME1였다가 더 강한 $NAME2가 되었다" + +# 'help' 명령어로 내장 문서를 읽을 수 있습니다. +help +help help +help for +help return +help source +help . + +# man으로 매뉴얼을 읽을 수도 있습니다. +apropos bash +man 1 bash +man bash + +# info 명령어로 문서를 읽습니다. (?로 도움말) +apropos info | grep '^info.*(' +man info +info info +info 5 info + +# bash의 info 문서를 읽어 보세요. +info bash +info bash 'Bash Features' +info bash 6 +info --apropos bash +``` diff --git a/ko-kr/brainfuck-kr.html.markdown b/ko-kr/bf-kr.html.markdown index c2e4341f..5849d2fd 100644 --- a/ko-kr/brainfuck-kr.html.markdown +++ b/ko-kr/bf-kr.html.markdown @@ -1,5 +1,6 @@ --- -language: brainfuck +language: bf +filename: learnbf-kr.bf contributors: - ["Prajit Ramachandran", "http://prajitr.github.io/"] - ["Mathias Bynens", "http://mathiasbynens.be/"] diff --git a/ko-kr/erlang-kr.html.markdown b/ko-kr/erlang-kr.html.markdown new file mode 100644 index 00000000..b0b1dd2a --- /dev/null +++ b/ko-kr/erlang-kr.html.markdown @@ -0,0 +1,333 @@ +--- +language: erlang +contributors: + - ["Giovanni Cappellotto", "http://www.focustheweb.com/"] +filename: learnerlang-kr.erl +translators: + - ["Taesung Jung", "https://github.com/tsj"] +lang: ko-kr +--- + +```erlang +% 퍼센트 기호는 한 줄 주석을 시작한다. + +%% 두 개의 퍼센트 문자는 함수의 주석에 사용된다. + +%%% 세 개의 퍼센트 문자는 모듈의 주석에 사용된다. + +% Erlang에선 3가지 유형의 문장 부호를 사용한다. +% 쉼표(`,`)는 함수 호출에서 인수, 데이터 생성자(constructors), 패턴을 구분한다. +% 마침표(`.`)(다음에 오는 공백)는 셸에서 함수 전체와 식을 구분한다. +% 세미콜론(`;`)은 절을 구분한다. 몇 가지 문맥(contexts)에서 절이 발견된다: +% 함수 정의와 `case`, `if`, `try..catch`, 그리고 `receive` 식 + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 1. 변수와 패턴 매칭 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Erlang에서 새로운 변수는 `=` 문장에 의해 바인딩 된다. +Num = 42. % 모든 변수 이름은 반드시 대문자로 시작해야 한다. + +% Erlang은 단일 할당 변수(single-assignment variables)를 가진다; +% 만약 다른 값을 `Num` 변수에 할당하려고 시도하면 오류가 발생한다. +Num = 43. % ** 예외 오류: 우변의 값 43과 매칭되지 않음 + +% 대부분 언어에서 `=`는 할당문을 나타낸다. 그러나 Erlang에서 +% `=`는 패턴 매칭 연산자를 나타낸다. 비어 있는 변수가 `=` 연산자의 좌변에 +% 사용되면 바인드(할당) 된다, 그러나 바인드 변수가 좌변에 사용된 경우에 +% 다음 행동은 그 바인드 변수가 관측된다. +% `Lhs = Rhs`의 진짜 의미: 우변(`Rhs`)을 평가하고, 그리고 +% 그 결과를 좌변(`Lhs`)의 패턴과 매치시켜라. +Num = 7 * 6. + +% 부동 소수점 수. +Pi = 3.14159. + +% Atom은 숫자가 아닌 서로 다른 상숫값을 표현하는 데 사용한다. Atom은 +% 소문자로 시작하고, 연속적인 영숫자(alphanumeric) 문자나 밑줄(`_`) 또는 +% 골뱅이(`@`) 기호가 따라온다. +Hello = hello. +OtherNode = example@node. + +% 영숫자 값이 아닌 Atom은 작은따옴표로 묶여서 작성될 수 있다. +AtomWithSpace = 'some atom with space'. + +% Tuple은 C의 struct와 비슷하다. +Point = {point, 10, 45}. + +% Tuple에서 어떤 값을 추출하려면, 패턴 매칭 연산자 `=`를 사용한다. +{point, X, Y} = Point. % X = 10, Y = 45 + +% 관심 없는 변수를 위해 자리 표시자(placeholder) `_`를 사용할 수 있다. +% 기호 `_`는 익명 변수(anonymous variable)라 부른다. 일반적인 변수들과 +% 다르게 같은 패턴에서 여러 번 나오더라도 동일한 값으로 바인드되지 않아도 된다. +Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}. +{_, {_, {_, Who}, _}, _} = Person. % Who = joe + +% List를 만들기 위해서 List의 원소는 대괄호([])로 둘러싸고 쉼표(,)로 구분한다. +% List의 각각의 원소는 어떤 타입도 가능하다. +% List의 첫 번째 원소는 List의 HEAD이다. 만약 List의 HEAD를 제거하면, +% 남은 부분은 List의 TAIL이라 부른다. +ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}]. + +% 만약 `T`가 List이면, `[H|T]`도 HEAD가 `H`이고 TAIL이 `T`인 List이다. +% 세로 막대(`|`)는 List의 HEAD와 TAIL을 분리한다. `[]`는 빈 List다. +% List의 원소들은 패턴 매칭 연산으로 추출할 수 있다. +% 만약 비어있지 않은 List `L`이 있을 때, `[X|Y] = L` 식의 `X`와 `Y`가 +% 바인드되지 않은 변수이면, List의 HEAD는 X에 그리고 TAIL은 Y로 추출된다. +[FirstThing|OtherThingsToBuy] = ThingsToBuy. +% FirstThing = {apples, 10} +% OtherThingsToBuy = [{pears, 6}, {milk, 3}] + +% Erlang에는 문자열(String)이 없다. 문자열은 사실 정수의 List일 뿐이다. +% 문자열은 큰따옴표(`"`)로 묶인다. +Name = "Hello". +[72, 101, 108, 108, 111] = "Hello". + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 2. 순차 프로그래밍 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Erlang에서 Module은 코드의 기본 단위이다. 우리가 작성한 모든 함수는 +% Module에 담긴다. Module은 확장자가 `.erl`인 파일에 저장된다. +% 코드가 실행되기 전에 Module은 컴파일되어야 한다. 컴파일된 Module은 +% `.beam` 확장자를 가진다. +-module(geometry). +-export([area/1]). % Module로부터 내보내진(exported) 함수의 List + +% 함수 `area`는 두 개의 절로 구성된다. 절은 세미콜론(`;`)으로 구분되며, +% 마지막 절은 마침표-공백(dot-whitespace)으로 끝난다. +% 각 절은 서문(head)과 본문(body)을 가진다. 서문은 함수의 이름에 이어서 +% 패턴이(괄호 속에) 따라온다. 본문은 연속적인 식으로 구성되고, +% 연속적인 식은 서문의 패턴과 호출한 인수가 성공적으로 매치되면 평가된다. +% 패턴은 함수 정의가 나타나는 순서대로 매치된다. +area({rectangle, Width, Ht}) -> Width * Ht; +area({circle, R}) -> 3.14159 * R * R. + +% geometry.erl 파일의 코드 컴파일 +c(geometry). % {ok,geometry} + +% 호출하려는 함수를 정확히 알아내기 위해 함수 이름을 Module 이름과 함께 +% 명시하는 것이 필요하다. +geometry:area({rectangle, 10, 5}). % 50 +geometry:area({circle, 1.4}). % 6.15752 + +% Erlang에서, 같은 Module에 이름이 같고 Arity(인수의 갯수)가 다른 +% 두 함수는 전혀 다른 함수를 나타낸다. +-module(lib_misc). +-export([sum/1]). % Arity가 1인 내보내진(export) 함수 `sum` + % 하나의 인수만 받음: 정수의 List +sum(L) -> sum(L, 0). +sum([], N) -> N; +sum([H|T], N) -> sum(T, H+N). + +% Fun은 "익명(anonymous)" 함수다. 이름이 없어서 이렇게 부른다. +% 그러나, 변수에 할당될 수 있다. +Double = fun(X) -> 2 * X end. % `Double`은 익명 함수를 가리킨다: + % #Fun<erl_eval.6.17052888> +Double(2). % 4 + +% 함수는 인수로 Fun을 받거나, Fun을 반환할 수 있다. +Mult = fun(Times) -> ( fun(X) -> X * Times end ) end. +Triple = Mult(3). +Triple(5). % 15 + +% List 해석(List comprehensions)은 Fun, Map, Filter 없이 List를 만드는 식이다. +% 표기법 `[F(X) || X <- L]`은 `F(X)`의 List라는 의미이다. +% 이때 `X`는 List `L`로부터 가져온다. +L = [1,2,3,4,5]. +[2 * X || X <- L]. % [2,4,6,8,10] +% List 해석은 Generator와 생성된 값들의 부분 집합을 선택하는 Filter를 가질 수 있다. +EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4] + +% Guard는 패턴 매칭의 능력을 향상시키는데 사용할 수 있는 구조다. +% Guard를 사용하면, 패턴에 있는 변수에 대해 간단한 검사와 비교를 수행할 수 있다. +% 함수 정의의 서문(head)에 `when` 키워드로 시작되는 Guard를 사용할 수도 있고, +% 또는 식이 허용되는 언어의 어떤 곳에도 사용될 수 있다. +max(X, Y) when X > Y -> X; +max(X, Y) -> Y. + +% Guard는 쉼표(`,`)로 구분된 연속된 Guard 식이다. +% 모든 Guard 식 `GuardExpr1`, `GuardExpr2`, ..., `GuardExprN`이 +% `true`로 평가된다면, Guard `GuardExpr1`, `GuardExpr2`, ..., `GuardExprN`는 +% 참이다. +is_cat(A) when is_atom(A), A =:= cat -> true; +is_cat(A) -> false. +is_dog(A) when is_atom(A), A =:= dog -> true; +is_dog(A) -> false. + +% `=:=` 연산자는 여기서 자세히 다루지 않을 것이다; 두 개의 Erlang 식의 값이 같고 +% *그리고* 같은 타입인지 검사하는 데 사용된다고만 알면 된다. +% `==` 연산자의 작동과 대조할 것: +1 + 2 =:= 3. % true +1 + 2 =:= 3.0. % false +1 + 2 == 3.0. % true + +% 연속적인 Guard는 단일 Guard 또는 세미콜론(`;`)으로 구분된 연속된 Guard다. +% Guard `G1; G2; ...; Gn` 중에 적어도 하나의 Guard가 `true`로 평가된다면, +% 연속적인 Guard `G1; G2; ...; Gn`는 참이다. +is_pet(A) when is_atom(A), (A =:= dog);(A =:= cat) -> true; +is_pet(A) -> false. + +% 주의: 모든 유효한 Erlang 식이 Guard 식으로 사용될 수 있는 것은 아니다; +% 특히, 함수 `is_cat`과 `is_dog`는 `is_pet`의 정의 안에 있는 +% 연속적인 Guard 사이에 사용될 수 없다. +% 연속적인 Guard에 허용되는 식의 자세한 설명은 Erlang 레퍼런스 메뉴얼 +% [section](http://erlang.org/doc/reference_manual/expressions.html#id81912) +% 을 참조하라. + +% Record는 Tuple 안에 이름과 특정 요소를 연결하는 방법을 제공한다. +% Record 정의는 Erlang 소스 코드 파일에 포함되거나 Erlang 소스 코드 파일에 +% 포함될 수 있는 확장자가 `.hrl`인 파일에 집어넣을 수 있다. +-record(todo, { + status = reminder, % 기본 값 + who = joe, + text +}). + +% Record를 사용할 수 있기 전에 Record 정의를 반드시 셸로 읽어 들여야 한다. +% 셸로 읽어 들이기 위해 셸 함수 `rr`(read records의 약자)을 사용한다. +rr("records.hrl"). % [todo] + +% Record 생성과 수정 +X = #todo{}. +% #todo{status = reminder, who = joe, text = undefined} +X1 = #todo{status = urgent, text = "Fix errata in book"}. +% #todo{status = urgent, who = joe, text = "Fix errata in book"} +X2 = X1#todo{status = done}. +% #todo{status = done, who = joe, text = "Fix errata in book"} + +% `case` 식 +% `filter`는 List `L`의 원소 `X` 중에서 `P(X)`가 참인 모든 `X`의 List를 반환한다. +filter(P, [H|T]) -> + case P(H) of + true -> [H|filter(P, T)]; + false -> filter(P, T) + end; +filter(P, []) -> []. +filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4] + +% `if` 식. +max(X, Y) -> + if + X > Y -> X; + X < Y -> Y; + true -> nil + end. + +% 주의: 적어도 if 식의 Guard 중의 하나는 반드시 `true`로 평가되어야 한다. +% 그렇지 않으면 예외가 발생한다. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 3. 예외 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% 예외는 내부에 에러가 생겼거나 명시적으로 `throw(Exception)`, +% `exit(Exception)` 또는 `erlang:error(Exception)`를 호출하면 +% 시스템에 의해 발생한다. +generate_exception(1) -> a; +generate_exception(2) -> throw(a); +generate_exception(3) -> exit(a); +generate_exception(4) -> {'EXIT', a}; +generate_exception(5) -> erlang:error(a). + +% Erlang은 예외를 잡는 두 가지 방법을 가지고 있다. 한 가지는 +% 예외를 발생시키는 함수의 호출 부분을 `try...catch` 식으로 감싸는 것이다. +catcher(N) -> + try generate_exception(N) of + Val -> {N, normal, Val} + catch + throw:X -> {N, caught, thrown, X}; + exit:X -> {N, caught, exited, X}; + error:X -> {N, caught, error, X} + end. + +% 다른 방법은 그 호출 부분을 `catch` 식으로 감싸는 것이다. +% 예외를 잡았을 때, 그 예외는 오류를 설명하는 Tuple로 변환된다. +catcher(N) -> catch generate_exception(N). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 4. 병행성 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Erlang은 병행성을 위해 Actor 모델을 사용한다. Erlang에서 병행 프로그램을 +% 작성하는 데 필요한 모든 것은 3가지 기본 형식(primitivies)이다: +% 프로세스 생성, 메시지 보내기, 메시지 받기 + +% 새로운 프로세스를 시작하기 위해, 함수를 인수로 받는 `spawn` 함수를 사용한다. + +F = fun() -> 2 + 2 end. % #Fun<erl_eval.20.67289768> +spawn(F). % <0.44.0> + +% `spawn`은 pid(프로세스 식별자)를 반환한다. 이 pid를 프로세스로 +% 메시지를 보내는 데 사용할 수 있다. 메시지 전달을 위해, `!` 연산자를 사용한다. +% 위의 기능이 유용하려면, 메시지를 받을 수 있어야 한다. 메시지를 받는 것은 +% `receive` 메커니즘을 사용한다. + +-module(calculateGeometry). +-compile(export_all). +calculateArea() -> + receive + {rectangle, W, H} -> + W * H; + {circle, R} -> + 3.14 * R * R; + _ -> + io:format("We can only calculate area of rectangles or circles.") + end. + +% Module을 컴파일하고 셸에서 `calculateArea`를 평가한 프로세스를 생성한다. +c(calculateGeometry). +CalculateArea = spawn(calculateGeometry, calculateArea, []). +CalculateArea ! {circle, 2}. % 12.56000000000000049738 + +% 셸도 마찬가지로 프로세스이다. 현재 pid를 얻기 위해서 `self`를 사용할 수 있다. +self(). % <0.41.0> + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 5. EUnit과 테스트 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% EUnit의 테스트 생성기(generators)와 assert 매크로를 이용해 +% 단위 테스트를 작성할 수 있다. +-module(fib). +-export([fib/1]). +-include_lib("eunit/include/eunit.hrl"). + +fib(0) -> 1; +fib(1) -> 1; +fib(N) when N > 1 -> fib(N-1) + fib(N-2). + +fib_test_() -> + [?_assert(fib(0) =:= 1), + ?_assert(fib(1) =:= 1), + ?_assert(fib(2) =:= 2), + ?_assert(fib(3) =:= 3), + ?_assert(fib(4) =:= 5), + ?_assert(fib(5) =:= 8), + ?_assertException(error, function_clause, fib(-1)), + ?_assert(fib(31) =:= 2178309) + ]. + +% EUnit은 Erlang 셸에서 테스트를 실행할 수 있게 +% 자동으로 test() 함수를 내보낸다(export). +fib:test() + +% Erlang의 유명한 빌드 툴인 Rebar는 EUnit과 호환된다. +% ``` +% rebar eunit +% ``` + +``` + +## 참조 + +* ["Learn You Some Erlang for great good!"](http://learnyousomeerlang.com/) +* ["Programming Erlang: Software for a Concurrent World" by Joe Armstrong](http://pragprog.com/book/jaerlang/programming-erlang) +* [조 암스트롱, 김석준 역, "프로그래밍 얼랭: Software for a Concurrent World", 인사이트](http://ebook.insightbook.co.kr/book/23) +* [Erlang/OTP Reference Documentation](http://www.erlang.org/doc/) +* [Erlang - Programming Rules and Conventions](http://www.erlang.se/doc/programming_rules.shtml) diff --git a/ko-kr/javascript-kr.html.markdown b/ko-kr/javascript-kr.html.markdown index 4ca3bb5c..9561e80c 100644 --- a/ko-kr/javascript-kr.html.markdown +++ b/ko-kr/javascript-kr.html.markdown @@ -387,9 +387,6 @@ myNumber === myNumberObj // = false if (0){ // 0은 거짓이라서 이 코드는 실행되지 않습니다. } -if (Number(0)){ - // Number(0)은 참이라서 이 코드는 *실행됩니다*. -} // 하지만 래퍼 객체와 일반 내장 함수는 프로토타입을 공유하기 때문에 // 가령 문자열에 실제로 기능을 추가할 수 있습니다. diff --git a/ko-kr/json-kr.html.markdown b/ko-kr/json-kr.html.markdown new file mode 100644 index 00000000..462bf63a --- /dev/null +++ b/ko-kr/json-kr.html.markdown @@ -0,0 +1,80 @@ +--- +language: json +filename: learnjson-kr.json +contributors: + - ["Anna Harren", "https://github.com/iirelu"] + - ["Marco Scannadinari", "https://github.com/marcoms"] + - ["himanshu", "https://github.com/himanshu81494"] + - ["Michael Neth", "https://github.com/infernocloud"] +translators: + - ["Wooseop Kim", "https://github.com/linterpreteur"] +lang: ko-kr +--- + +JSON은 아주 간단한 데이터 교환 포맷입니다. [json.org](http://json.org/json-ko.html)에 의하면, 사람이 읽고 쓰기 쉬우며 기계가 분석하고 생성하기 쉽습니다. + +JSON 한 개는 반드시 이하의 둘 중 하나를 나타내야 합니다. +* 이름과 값 쌍의 모임(`{ }`). 이는 다양한 언어에서 객체, 레코드, 구조체, 딕셔너리, 해시 테이블, 키 리스트, 혹은 연관 배열로 구현됩니다. +* 값에 순서가 있는 리스트 (`[ ]`). 이는 다양한 언어에서 배열, 벡터, 리스트, 시퀀스로 구현됩니다. + +순수한 JSON은 사실 주석이 없지만 대부분의 파서는 C 스타일의 주석(`//`, `/* */`)도 받아들일 겁니다. 일부 파서는 꼬리에 오는 쉼표, 즉 배열의 마지막 원소 혹은 객체의 마지막 속성 다음에 오는 쉼표도 인정하겠지만, 호환성을 위해 쓰지 않는 것이 좋습니다. + +이 튜토리얼의 목적에 따라 모든 것은 100% 유효한 JSON입니다. 다행스럽게도 JSON은 다소 자기서술적입니다. + +지원하는 데이터 형: + +* 문자열: `"안녕"`, `"\"따옴표.\""`, `"\u0abe"`, `"개행 문자.\n"` +* 수: `23`, `0.11`, `12e10`, `3.141e-10`, `1.23e+4` +* 객체: `{ "키": "값" }` +* 배열: `["값 값 값"]` +* 기타: `true`, `false`, `null` + +```json +{ + "키": "값", + + "키는": "반드시 큰따옴표 안에 있어야 합니다.", + "수": 0, + "문자열": "Hellø, wørld. 모든 유니코드와 \"탈출 문자\"가 지원됩니다.", + "부울도 있나?": true, + "아무 것도 없는 건": null, + + "큰 수": 1.2e+100, + + "객체": { + "주석": "문서 구조의 대부분은 객체가 될 것입니다.", + + "배열": [0, 1, 2, 3, "배열 안에는 무엇이든 올 수 있습니다.", 5], + + "다른 객체": { + "주석": "객체는 객체를 포함할 수 있습니다. 아주 유용하죠." + } + }, + + "장난이지롱": [ + { + "칼륨이 풍부한": ["바나나"] + }, + [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, "neo"], + [0, 0, 0, 1] + ] + ], + + "다른 방식": { + "주석": "여기 보세요!" + , "쉼표의 위치는": "상관 없습니다. 다음 키 전에만 온다면 유효합니다." + , "다른 주석": "참 좋죠" + }, + + "공백은": "상관이 없습니다.", + + "짧았죠": "끝입니다. JSON의 모든 것을 터득하셨습니다." +} +``` + +## 더 읽기 + +* [JSON.org](http://json.org/json-ko.html) 플로우차트와 같은 그래픽을 이용해 설명한 JSON의 모든 것. diff --git a/ko-kr/kotlin-kr.html.markdown b/ko-kr/kotlin-kr.html.markdown new file mode 100644 index 00000000..2df4195d --- /dev/null +++ b/ko-kr/kotlin-kr.html.markdown @@ -0,0 +1,376 @@ +--- +language: kotlin +contributors: + - ["S Webber", "https://github.com/s-webber"] +translators: + - ["Alan Jeon", "https://github.com/skyisle"] +lang: ko-kr +filename: LearnKotlin-kr.kt +--- + +Kotlin 은 정적 타입 프로그래밍 언어로 JVM, 안드로이드, 브라우져를 지원하며 Java 와 100% 상호 운용이 가능합니다. +[자세한 내용은 다음을 참고하세요.](https://kotlinlang.org/) + +```kotlin +// 한 줄짜리 주석은 // 로 시작합니다. +/* +여러 줄 주석은 이와 같이 표시합니다. +*/ + +// "package" 예약어는 자바와 동일하게 사용됩니다. +package com.learnxinyminutes.kotlin + +/* +Kotlin 프로그램의 진입점은 main 이라는 함수명으로 지정됩니다. +이 함수에 명령행 인수가 배열로 전달됩니다. +*/ +fun main(args: Array<String>) { + /* + 값을 선언할때는 "var" 또는 "val"이 사용됩니다. + "var"와는 다르게 "val"로 선언된 변수에는 값을 재할당 할 수 없습니다. + */ + val fooVal = 10 // fooVal 에 다른 값을 다시 할당 할 수 없습니다. + var fooVar = 10 + fooVar = 20 // fooVar 에는 선언 이후에도 다른 값을 할당 할 수 있습니다 + + /* + 대부분의 경우, Kotlin 에서는 변수 타입을 판단할 수 있기때문에 명시적으로 지정해 주지 않을 수 있습니다. + 다음과 같이 변수의 타입을 명시적으로 지정할 수 있습니다. + */ + val foo: Int = 7 + + /* + 문자형은 Java와 비슷하게 표시될 수 있습니다. + 이스케이핑에는 백슬래시를 사용합니다. + */ + val fooString = "My String Is Here!" + val barString = "Printing on a new line?\nNo Problem!" + val bazString = "Do you want to add a tab?\tNo Problem!" + println(fooString) + println(barString) + println(bazString) + + /* + Raw 문자열은 쌍따옴표 3개(""")로 표기합니다. + Raw 문자열에는 줄바꿈이나 모든 다른 문자들을 사용할 수 있습니다. + */ + val fooRawString = """ +fun helloWorld(val name : String) { + println("Hello, world!") +} +""" + println(fooRawString) + + /* + 문자열은 템플릿 표현식을 포함할 수 있습니다. + 템플릿은 달러 기호($)로 시작합니다. + */ + val fooTemplateString = "$fooString has ${fooString.length} characters" + println(fooTemplateString) + + /* + 변수가 null 값을 가지려면 이를 명시적으로 선언해야 합니다. + 변수 선언시 타입에 ? 표시를 붙여 nullable 을 표시합니다. + ?. 연산자를 사용해 nullable 변수에 접근합니다. + ?: 연산자를 이용해서 변수 값이 null 일때 사용할 값을 지정합니다. + */ + var fooNullable: String? = "abc" + println(fooNullable?.length) // => 3 + println(fooNullable?.length ?: -1) // => 3 + fooNullable = null + println(fooNullable?.length) // => null + println(fooNullable?.length ?: -1) // => -1 + + /* + 함수는 "fun" 예약어를 사용해 선언합니다. + 함수명 이후 괄호 안에 인자를 기술합니다. + 함수 인자에 기본 값을 지정할 수도 있습니다. + 함수에 리턴값이 있을 때, 필요한 경우 인자 뒤에 타입을 명시합니다. + */ + fun hello(name: String = "world"): String { + return "Hello, $name!" + } + println(hello("foo")) // => Hello, foo! + println(hello(name = "bar")) // => Hello, bar! + println(hello()) // => Hello, world! + + /* + 함수에 가변 인자를 넘기려면 인자에 "vararg" 예약어를 사용합니다. + */ + fun varargExample(vararg names: Int) { + println("Argument has ${names.size} elements") + } + varargExample() // => 인자가 0개 인 경우 + varargExample(1) // => 인자가 1개인 경우 + varargExample(1, 2, 3) // => 인자가 3개인 경우 + + /* + 함수가 단일 표현식으로 이루어진 경우에 중괄호를 생략할 수 있습니다. + 이때 함수 구현부는 = 기호 이후에 기술합니다. + */ + fun odd(x: Int): Boolean = x % 2 == 1 + println(odd(6)) // => false + println(odd(7)) // => true + + // 리턴 타입이 유추 가능한 경우 이를 명시하지 않아도 됩니다. + fun even(x: Int) = x % 2 == 0 + println(even(6)) // => true + println(even(7)) // => false + + // 함수는 함수를 인자를 받을 수 있고 함수를 리턴할 수 있습니다. + fun not(f: (Int) -> Boolean): (Int) -> Boolean { + return {n -> !f.invoke(n)} + } + // 함수는 :: 연산자를 사용해서 다른 함수에 인자로 넘길 수 있습니다. + val notOdd = not(::odd) + val notEven = not(::even) + // 람다식을 인자로 사용할 수 있습니다. + val notZero = not {n -> n == 0} + /* + 하나의 인자를 가지는 람다식의 선언부와 -> 연산자는 생략될 수 있습니다. + 이때 그 인자명은 it로 지정됩니다. + */ + val notPositive = not {it > 0} + for (i in 0..4) { + println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}") + } + + // "class" 예약어는 클래스를 선언할 때 사용됩니다. + class ExampleClass(val x: Int) { + fun memberFunction(y: Int): Int { + return x + y + } + + infix fun infixMemberFunction(y: Int): Int { + return x * y + } + } + /* + 새로운 객체를 생성하기 위해서는 생성자를 바로 호출합니다. + Kotlin 에서는 new 예약어가 없다는 걸 기억하세요. + */ + val fooExampleClass = ExampleClass(7) + // 맴버 함수는 dot 표기로 호출할 수 있습니다. + println(fooExampleClass.memberFunction(4)) // => 11 + /* + 함수 선언에 "infix" 예약어를 사용하면 이 함수를 중위 표현식(infix notation)으로 호출할 수 있습니다 + */ + println(fooExampleClass infixMemberFunction 4) // => 28 + + /* + 데이터 클래스로 데이터만을 가지고 있는 클래스를 손쉽게 선언할 수 있습니다. + "hashCode"/"equals" 와 "toString" 는 자동으로 생성됩니다. + */ + data class DataClassExample (val x: Int, val y: Int, val z: Int) + val fooData = DataClassExample(1, 2, 4) + println(fooData) // => DataClassExample(x=1, y=2, z=4) + + // 데이터 클래스는 copy 함수를 가지고 있습니다. + val fooCopy = fooData.copy(y = 100) + println(fooCopy) // => DataClassExample(x=1, y=100, z=4) + + // 객체를 여러 변수로 분리할 수 있습니다. + val (a, b, c) = fooCopy + println("$a $b $c") // => 1 100 4 + + // "for" 루프에서 변수 분리 하기 + for ((a, b, c) in listOf(fooData)) { + println("$a $b $c") // => 1 100 4 + } + + val mapData = mapOf("a" to 1, "b" to 2) + // Map.Entry 또한 키와 값으로 분리가 가능합니다. + for ((key, value) in mapData) { + println("$key -> $value") + } + + // "with" 함수는 JavaScript 의 "with" 구문과 비슷하게 사용됩니다. + data class MutableDataClassExample (var x: Int, var y: Int, var z: Int) + val fooMutableData = MutableDataClassExample(7, 4, 9) + with (fooMutableData) { + x -= 2 + y += 2 + z-- + } + println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8) + + /* + "listOf" 함수로 리스트를 만들 수 있습니다. + 리스트는 변경 불가능(immutable)하게 만들어져 항목의 추가 삭제가 불가능합니다. + */ + val fooList = listOf("a", "b", "c") + println(fooList.size) // => 3 + println(fooList.first()) // => a + println(fooList.last()) // => c + // 각 항목은 인덱스로 접근이 가능합니다. + println(fooList[1]) // => b + + // 변경가능한(mutable) 리스트는 "mutableListOf" 함수로 만들 수 있습니다. + val fooMutableList = mutableListOf("a", "b", "c") + fooMutableList.add("d") + println(fooMutableList.last()) // => d + println(fooMutableList.size) // => 4 + + // 집합(set)은 "setOf" 함수로 만들 수 있습니다. + val fooSet = setOf("a", "b", "c") + println(fooSet.contains("a")) // => true + println(fooSet.contains("z")) // => false + + // 맵은 "mapOf" 함수로 만들 수 있습니다. + val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9) + // 맵은 키를 통해 그 값에 접근할 수 있습니다. Map values can be accessed by their key. + println(fooMap["a"]) // => 8 + + /* + 시퀀스는 지연 평가되는 컬랙션을 말합니다. Sequences represent lazily-evaluated collections. + "generateSequence" 를 사용해 시퀀스를 만들 수 있습니다. We can create a sequence using the "generateSequence" function. + */ + val fooSequence = generateSequence(1, { it + 1 }) + val x = fooSequence.take(10).toList() + println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + // 다음은 시퀀스를 사용해서 피보나치 수열을 생성하는 예입니다. + fun fibonacciSequence(): Sequence<Long> { + var a = 0L + var b = 1L + + fun next(): Long { + val result = a + b + a = b + b = result + return a + } + + return generateSequence(::next) + } + val y = fibonacciSequence().take(10).toList() + println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] + + // Kotlin 은 컬랙션에서 사용할 수 있는 고차(higher-order)함수를 제공합니다. + val z = (1..9).map {it * 3} + .filter {it < 20} + .groupBy {it % 2 == 0} + .mapKeys {if (it.key) "even" else "odd"} + println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]} + + // "for" 루프는 이터레이터를 제공하는 어떤 것과도 함께 사용할 수 있습니다. + for (c in "hello") { + println(c) + } + + // "while" 루프는 다른 언어들과 동일하게 사용됩니다. + var ctr = 0 + while (ctr < 5) { + println(ctr) + ctr++ + } + do { + println(ctr) + ctr++ + } while (ctr < 10) + + /* + "if"는 값을 리턴하는 표현으로 사용될 수 있습니다. + 그래서 Kotlin 에서는 삼항 ?: 연산자가 필요하지 않습니다. + */ + val num = 5 + val message = if (num % 2 == 0) "even" else "odd" + println("$num is $message") // => 5 is odd + + // "when"은 "if-else if" 를 대체할때 사용할 수 있습니다. + val i = 10 + when { + i < 7 -> println("first block") + fooString.startsWith("hello") -> println("second block") + else -> println("else block") + } + + // "when"은 인수와 함께 사용될 수 있습니다. + when (i) { + 0, 21 -> println("0 or 21") + in 1..20 -> println("in the range 1 to 20") + else -> println("none of the above") + } + + // "when"은 값을 리턴하는 함수처럼 사용될 수 있습니다. + var result = when (i) { + 0, 21 -> "0 or 21" + in 1..20 -> "in the range 1 to 20" + else -> "none of the above" + } + println(result) + + /* + 객체가 어떤 타입인지를 확인하기 위해 "is" 연산자를 사용할 수 있습니다. + 타입 체크를 통과하면 객체의 명시적인 형변환 없이도 그 타입 값으로 사용될 수 있습니다. + 이를 스마트 변환(Smartcast)이라 부릅니다. + */ + fun smartCastExample(x: Any) : Boolean { + if (x is Boolean) { + // x is automatically cast to Boolean + return x + } else if (x is Int) { + // x is automatically cast to Int + return x > 0 + } else if (x is String) { + // x is automatically cast to String + return x.isNotEmpty() + } else { + return false + } + } + println(smartCastExample("Hello, world!")) // => true + println(smartCastExample("")) // => false + println(smartCastExample(5)) // => true + println(smartCastExample(0)) // => false + println(smartCastExample(true)) // => true + + // 스마트 변환은 when 블럭과도 함께 사용됩니다. + fun smartCastWhenExample(x: Any) = when (x) { + is Boolean -> x + is Int -> x > 0 + is String -> x.isNotEmpty() + else -> false + } + + /* + 확장(Extensions)을 이용해 클래스에 새로운 기능을 추가할 수 있습니다. + C#에서의 확장 매서드와 유사합니다. + */ + fun String.remove(c: Char): String { + return this.filter {it != c} + } + println("Hello, world!".remove('l')) // => Heo, word! + + println(EnumExample.A) // => A + println(ObjectExample.hello()) // => hello +} + +// Enum 클래스는 자바의 enum 타입과 유사합니다. +enum class EnumExample { + A, B, C +} + +/* +"object" 예약어는 싱클톤 객체를 생성할 때 사용됩니다. +객체를 새로 생성할 수는 없지만 이름을 가지고 접근해 사용할 수 있습니다. +이는 스칼라의 싱글톤 객체와 유사합니다. +*/ +object ObjectExample { + fun hello(): String { + return "hello" + } +} + +fun useObject() { + ObjectExample.hello() + val someRef: Any = ObjectExample // 객체의 이름을 그대로 사용합니다. +} + +``` + +### 더 알아보기 + +* [Kotlin tutorials (EN)](https://kotlinlang.org/docs/tutorials/) +* [Try Kotlin in your browser (EN)](http://try.kotlinlang.org/) +* [A list of Kotlin resources (EN)](http://kotlin.link/) diff --git a/ko-kr/lua-kr.html.markdown b/ko-kr/lua-kr.html.markdown index b4a018ef..ce3b71cb 100644 --- a/ko-kr/lua-kr.html.markdown +++ b/ko-kr/lua-kr.html.markdown @@ -418,5 +418,5 @@ lua-users.org에 있는 <a href="http://lua-users.org/files/wiki_insecure/users/ learn.lua로 저장한 후 "lua learn.lua"를 실행해 보세요! 이 글은 tylerneylon.com에 처음으로 써본 글이며, -<a href="https://gist.github.com/tylerneylon/5853042">Github의 Gist</a>에서도 확인할 수 있습니다. +<a href="https://gist.github.com/tylerneylon/5853042">GitHub의 Gist</a>에서도 확인할 수 있습니다. 루아로 즐거운 시간을 보내세요! diff --git a/ko-kr/markdown-kr.html.markdown b/ko-kr/markdown-kr.html.markdown new file mode 100644 index 00000000..bfa2a877 --- /dev/null +++ b/ko-kr/markdown-kr.html.markdown @@ -0,0 +1,308 @@ +--- +language: markdown +contributors: + - ["Dan Turkel", "http://danturkel.com/"] + - ["Jacob Ward", "http://github.com/JacobCWard/"] +filename: markdown-kr.md +lang: ko-kr +--- + +마크다운은 2004년에 존 그루버가 창시했습니다. HTML으로 (그리고 이제는 다른 다양한 형식으로도) 쉽게 변환되는 읽고 쓰기 쉬운 문법입니다. + +마크다운은 또한 파서마다 구현이 다양합니다. 본 문서는 어떤 기능이 보편적인지, +혹은 어떤 기능이 특정 파서에 종속되어 있는지 명확히 하고자 합니다. + +- [HTML 요소](#html-elements) +- [제목](#headings) +- [간단한 텍스트 꾸미기](#simple-text-styles) +- [문단](#paragraphs) +- [목록](#lists) +- [코드](#code-blocks) +- [수평선](#horizontal-rule) +- [링크](#links) +- [이미지](#images) +- [기타](#miscellany) + +## HTML 요소 +HTML은 마크다운의 수퍼셋입니다. 모든 HTML 파일은 유효한 마크다운이라는 것입니다. +```markdown +<!--따라서 주석과 같은 HTML 요소들을 마크다운에 사용할 수 있으며, 마크다운 파서에 영향을 +받지 않을 것입니다. 하지만 마크다운 파일에서 HTML 요소를 만든다면 그 요소의 안에서는 +마크다운 문법을 사용할 수 없습니다.--> +``` +## 제목 + +텍스트 앞에 붙이는 우물 정 기호(#)의 갯수에 따라 `<h1>`부터 `<h6>`까지의 HTML 요소를 +손쉽게 작성할 수 있습니다. +```markdown +# <h1>입니다. +## <h2>입니다. +### <h3>입니다. +#### <h4>입니다. +##### <h5>입니다. +###### <h6>입니다. +``` +또한 h1과 h2를 나타내는 다른 방법이 있습니다. +```markdown +h1입니다. +============= + +h2입니다. +------------- +``` +## 간단한 텍스트 꾸미기 + +마크다운으로 쉽게 텍스트를 기울이거나 굵게 할 수 있습니다. +```markdown +*기울인 텍스트입니다.* +_이 텍스트도 같습니다._ + +**굵은 텍스트입니다.** +__이 텍스트도 같습니다.__ + +***기울인 굵은 텍스트입니다.*** +**_이 텍스트도 같습니다._** +*__이것도 같습니다.__* +``` +깃헙 전용 마크다운에는 취소선도 있습니다. +```markdown +~~이 텍스트에는 취소선이 그려집니다.~~ +``` +## 문단 + +문단은 하나 이상의 빈 줄로 구분되는, 한 줄 이상의 인접한 텍스트입니다. + +```markdown +문단입니다. 문단에 글을 쓰다니 재밌지 않나요? + +이제 두 번째 문단입니다. +아직도 두 번째 문단입니다. + +나는 세 번째 문단! +``` +HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어쓰기로 문단을 끝내고 +새 문단을 시작할 수 있습니다. + +```markdown +띄어쓰기 두 개로 끝나는 문단 (마우스로 긁어 보세요). + +이 위에는 `<br />` 태그가 있습니다. +``` + +인용문은 > 문자로 쉽게 쓸 수 있습니다. + +```markdown +> 인용문입니다. 수동으로 개행하고서 +> 줄마다 `>`를 칠 수도 있고 줄을 길게 쓴 다음에 저절로 개행되게 내버려 둘 수도 있습니다. +> `>`로 시작하기만 한다면 차이가 없습니다. + +> 한 단계 이상의 들여쓰기를 +>> 사용할 수도 있습니다. +> 깔끔하죠? +``` + +## 목록 +순서가 없는 목록은 별표, 더하기, 하이픈을 이용해 만들 수 있습니다. +```markdown +* 이거 +* 저거 +* 그거 +``` + +또는 + +```markdown ++ 이거 ++ 저거 ++ 그거 +``` + +또는 + +```markdown +- 이거 +- 저거 +- 그거 +``` + +순서가 있는 목록은 숫자와 마침표입니다. + +```markdown +1. 하나 +2. 둘 +3. 셋 +``` + +숫자를 정확히 붙이지 않더라도 제대로 된 순서로 보여주겠지만, 좋은 생각은 아닙니다. + +```markdown +1. 하나 +1. 둘 +1. 셋 +``` +(위의 예시와 똑같이 나타납니다.) + +목록 안에 목록이 올 수도 있습니다. + +```markdown +1. 하나 +2. 둘 +3. 셋 + * 이거 + * 저거 +4. 넷 +``` + +심지어 할 일 목록도 있습니다. HTML 체크박스가 만들어집니다. + +```markdown +x가 없는 박스들은 체크되지 않은 HTML 체크박스입니다. +- [ ] 첫 번째 할 일 +- [ ] 두 번째 할 일 +이 체크박스는 체크된 HTML 체크박스입니다. +- [x] 완료된 일 +``` + +## 코드 + +띄어쓰기 네 개 혹은 탭 한 개로 줄을 들여씀으로서 (`<code> 요소를 사용하여`) 코드를 +나타낼 수 있습니다. + +```markdown + puts "Hello, world!" +``` + +탭을 더 치거나 띄어쓰기를 네 번 더 함으로써 코드를 들여쓸 수 있습니다. + +```markdown + my_array.each do |item| + puts item + end +``` + +인라인 코드는 백틱 문자를 이용하여 나타냅니다. ` + +```markdown +철수는 `go_to()` 함수가 뭘 했는지도 몰랐어! +``` + +깃헙 전용 마크다운에서는 코드를 나타내기 위해 특별한 문법을 쓸 수 있습니다. + +<pre> +<code class="highlight">```ruby +def foobar + puts "Hello world!" +end +```</code></pre> + +위의 경우에 들여쓰기가 필요없을 뿐 아니라 \`\`\` 뒤에 특정해 준 언어의 문법에 따라 +색을 입혀줄 것입니다. + +## 수평선 + +수평선(`<hr/>`)은 셋 이상의 별표나 하이픈을 이용해 쉽게 나타낼 수 있습니다. +띄어쓰기가 포함될 수 있습니다. +```markdown +*** +--- +- - - +**************** +``` +## 링크 + +마크다운의 장점 중 하나는 링크를 만들기 쉽다는 것입니다. 대괄호 안에 나타낼 텍스트를 쓰고 +괄호 안에 URL을 쓰면 됩니다. + +```markdown +[클릭](http://test.com/) +``` + +괄호 안에 따옴표를 이용해 링크에 제목을 달 수도 있습니다. + +```markdown +[클릭](http://test.com/ "test.com으로 가기") +``` + +상대 경로도 유효합니다. + +```markdown +[music으로 가기](/music/). +``` + +참조하는 식으로 링크를 걸 수도 있습니다. + +<pre><code class="highlight">[<span class="nv">이 </span>][<span class="ss">링크</span>]에서 더 알아보세요! +[<span class="nv">원하신다면 </span>][<span class="ss">foobar</span>]도 참고하세요. + +[<span class="nv">링크</span>]: <span class="sx">http://test.com/</span> <span class="nn">"좋아!"</span> +[<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"됐다!"</span></code></pre> + +제목은 작은 따옴표나 괄호에 들어갈 수도 있고, 완전히 생략할 수도 있습니다. 참조는 문서의 +어느 곳에든 올 수 있고 참조 ID는 유일하다면 무엇이든 될 수 있습니다. + +링크 텍스트를 ID로 사용하는 "묵시적 이름"도 있습니다. + +<pre><code class="highlight">[<span class="nv">이것</span>][]은 링크입니다. + +[<span class="nv">이것</span>]: <span class="sx">http://thisisalink.com/</span></code></pre> + +하지만 보통 그렇게 추천하지는 않습니다. + +## 이미지 +이미지는 링크와 같지만 앞에 느낌표가 붙습니다. + +```markdown +![이미지의 alt 속성](http://imgur.com/myimage.jpg "제목") +``` + +참조 방식도 가능합니다. + +<pre><code class="highlight">![<span class="nv">alt 속성</span>][<span class="ss">이미지</span>] + +[<span class="nv">이미지</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"제목이 필요하다면 여기에"</span></code></pre> + +## 기타 +### 자동 링크 + +```markdown +<http://testwebsite.com/>와 +[http://testwebsite.com/](http://testwebsite.com/)는 동일합니다. +``` + +### 이메일 자동 링크 +```markdown +<foo@bar.com> +``` +### 탈출 문자 + +```markdown +*별표 사이에 이 텍스트*를 치고 싶지만 기울이고 싶지는 않다면 +이렇게 하시면 됩니다. \*별표 사이에 이 텍스트\*. +``` + +### 키보드 키 + +깃헙 전용 마크다운에서는 `<kbd>` 태그를 이용해 키보드 키를 나타낼 수 있습니다. + +```markdown +컴퓨터가 멈췄다면 눌러보세요. +<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> +``` + +### 표 + +표는 깃헙 전용 마크다운에서만 쓸 수 있고 다소 복잡하지만, 정말 쓰고 싶으시다면 +```markdown +| 1열 | 2열 | 3열 | +| :--------| :-------: | --------: | +| 왼쪽 정렬 | 가운데 정렬 | 오른쪽 정렬 | +| 머시기 | 머시기 | 머시기 | +``` +혹은 +```markdown +1열 | 2열 | 3열 +:-- | :-: | --: +으악 너무 못생겼어 | 그만 | 둬 +``` +--- +추가 정보를 위해, 존 그루버의 공식 문법 [(영어) 문서](http://daringfireball.net/projects/markdown/syntax)와 애덤 프릿차드의 훌륭한 [(영어) 치트싯](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)을 확인하세요. diff --git a/ko-kr/vim-kr.html.markdown b/ko-kr/vim-kr.html.markdown new file mode 100644 index 00000000..cd0fa236 --- /dev/null +++ b/ko-kr/vim-kr.html.markdown @@ -0,0 +1,235 @@ +--- +category: tool +tool: vim +contributors: + - ["RadhikaG", "https://github.com/RadhikaG"] +translators: + - ["Wooseop Kim", "https://github.com/linterpreteur"] +filename: LearnVim-kr.txt +lang: ko-kr +--- + +[Vim](http://www.vim.org) +(Vi IMproved)은 유닉스의 인기 있는 vi 에디터의 클론입니다. Vim은 속도와 생산성을 위해 +설계된 텍스트 에디터로, 대부분의 유닉스 기반 시스템에 내장되어 있습니다. 다양한 단축 키를 통해 +파일 안에서 빠르게 이동하고 편집할 수 있습니다. + +## Vim 조작의 기본 + +``` + vim <filename> # vim으로 <filename> 열기 + :q # vim 종료 + :w # 현재 파일 저장 + :wq # 파일 저장 후 종료 + :q! # 저장하지 않고 종료 + # ! *강제로* :q를 실행하여, 저장 없이 종료 + :x # 파일 저장 후 종료 (짧은 :wq) + + u # 동작 취소 + CTRL+R # 되돌리기 + + h # 한 글자 왼쪽으로 이동 + j # 아래로 한 줄 이동 + k # 위로 한 줄 이동 + l # 한 글자 오른쪽으로 이동 + + # 줄 안에서의 이동 + + 0 # 줄 시작으로 이동 + $ # 줄 끝으로 이동 + ^ # 줄의 공백이 아닌 첫 문자로 이동 + + # 텍스트 검색 + + /word # 커서 뒤에 나타나는 해당 단어를 모두 하이라이트 + ?word # 커서 앞에 나타나는 해당 단어를 모두 하이라이트 + n # 해당 단어를 검색 후 다음으로 나타나는 위치로 이동 + N # 이전에 나타나는 위치로 이동 + + :%s/foo/bar/g # 파일 모든 줄에 있는 'foo'를 'bar'로 치환 + :s/foo/bar/g # 현재 줄에 있는 'foo'를 'bar'로 치환 + + # 문자로 이동 + + f<character> # <character>로 건너뛰기 + t<character> # <character>의 바로 뒤로 건너뛰기 + + # 예를 들어, + f< # <로 건너뛰기 + t< # <의 바로 뒤로 건너뛰기 + + # 단어 단위로 이동 + + w # 한 단어 오른쪽으로 이동 + b # 한 단어 왼쪽으로 이동 + e # 현재 단어의 끝으로 이동 + + # 기타 이동 명령어 + + gg # 파일 맨 위로 이동 + G # 파일 맨 아래로 이동 + :NUM # 줄 수 NUM(숫자)로 가기 + H # 화면 꼭대기로 이동 + M # 화면 중간으로 이동 + L # 화면 바닥으로 이동 +``` + +## 모드 + +Vim은 **모드**의 개념에 기초를 두고 있습니다. + +명령어 모드 - vim을 시작하면 처음에 이 모드입니다. 이동과 명령어 입력에 사용합니다. +삽입 모드 - 파일을 수정합니다. +비주얼 모드 - 텍스트를 하이라이트하고 그 텍스트에 대한 작업을 합니다. +실행 모드 - ':' 이후 명령어를 입력합니다. + +``` + i # 커서 위치 앞에서 삽입 모드로 변경 + a # 커서 위치 뒤에서 삽입 모드로 변경 + v # 비주얼 모드로 변경 + : # 실행 모드로 변경 + <esc> # 현재 모드를 벗어나 명령어 모드로 변경 + + # 복사와 붙여넣기 + + y # 선택한 객체 복사(Yank) + yy # 현재 줄 복사 + d # 선택한 객체 삭제 + dd # 현재 줄 삭제 + p # 커서 위치 뒤에 복사한 텍스트 붙여넣기 + P # 커서 위치 뒤에 복사한 텍스트 붙여넣기 + x # 현재 커서 위치의 문자 삭제 +``` + +## vim의 문법 + +Vim의 명령어는 '서술어-수식어-목적어'로 생각할 수 있습니다. + +서술어 - 취할 동작 +수식어 - 동작을 취할 방식 +목적어 - 동작을 취할 객체 + +'서술어', '수식어', '목적어'의 예시는 다음과 같습니다. + +``` + # '서술어' + + d # 지운다 + c # 바꾼다 + y # 복사한다 + v # 선택한다 + + # '수식어' + + i # 안에 + a # 근처에 + NUM # (숫자) + f # 찾아서 그곳에 + t # 찾아서 그 앞에 + / # 문자열을 커서 뒤로 찾아서 + ? # 문자열을 커서 앞으로 찾아서 + + # '목적어' + + w # 단어를 + s # 문장을 + p # 문단을 + b # 블락을 + + # 예시 '문장' (명령어) + + d2w # 단어 2개를 지운다 + cis # 문장 안을 바꾼다 + yip # 문단 안을 복사한다 + ct< # 여는 괄호까지 바꾼다 + # 현재 위치에서 다음 여는 괄호까지의 텍스트를 바꾼다 + d$ # 줄 끝까지 지운다 +``` + +## 몇 가지 트릭 + + <!--TODO: Add more!--> +``` + > # 선택한 영역 한 칸 들여쓰기 + < # 선택한 영역 한 칸 내어쓰기 + :earlier 15m # 15분 전의 상태로 되돌리기 + :later 15m # 위의 명령어를 취소 + ddp # 이어지는 줄과 위치 맞바꾸기 (dd 후 p) + . # 이전 동작 반복 + :w !sudo tee % # 현재 파일을 루트 권한으로 저장 +``` + +## 매크로 + +매크로는 기본적으로 녹화할 수 있는 동작을 말합니다. +매크로를 녹화하기 시작하면, 끝날 때까지 **모든** 동작과 명령어가 녹화됩니다. +매크로를 호출하면 선택한 텍스트에 대해 정확히 같은 순서의 동작과 명령어가 실행됩니다. + +``` + qa # 'a'라는 이름의 매크로 녹화 시작 + q # 녹화 중지 + @a # 매크로 실행 +``` + +### ~/.vimrc 설정 + +.vimrc 파일은 Vim이 시작할 때의 설정을 결정합니다. + +다음은 ~/.vimrc 파일의 예시입니다. + +``` +" ~/.vimrc 예시 +" 2015.10 + +" vim이 iMprove 되려면 필요 +set nocompatible + +" 자동 들여쓰기 등을 위해 파일 명으로부터 타입 결정 +filetype indent plugin on + +" 신택스 하이라이팅 켜기 +syntax on + +" 커맨드 라인 완성 향상 +set wildmenu + +" 대문자를 썼을 때가 아니면 대소문자 구분하지 않고 검색 +set ignorecase +set smartcase + +" 줄넘김을 했을 때 파일에 따른 들여쓰기가 켜져 있지 않다면 +" 현재 줄과 같은 들여쓰기를 유지 +set autoindent + +" 좌측에 줄 번호 표시 +set number + +" 들여쓰기 설정 (개인 기호에 따라 변경) + +" 탭 하나와 시각적으로 같을 스페이스 개수 +set tabstop=4 + +" 편집할 때 탭 하나에 들어갈 스페이스 수 +set softtabstop=4 + +" 들여쓰기 혹은 내어쓰기 작업(>>, <<)을 했을 때 움직일 스페이스 개수 +set shiftwidth=4 + +" 탭을 스페이스로 변환 +set expandtab + +" 들여쓰기와 정렬에 자동 탭 및 스페이스 사용 +set smarttab +``` + +### 참고 자료 + +[(영어) Vim 홈페이지](http://www.vim.org/index.php) + +`$ vimtutor` + +[(영어) vim 입문과 기초](https://danielmiessler.com/study/vim/) + +[(영어) 엄마가 말해주지 않은 Vim의 어두운 구석들 (Stack Overflow 게시물)](http://stackoverflow.com/questions/726894/what-are-the-dark-corners-of-vim-your-mom-never-told-you-about) + +[(영어) 아치 리눅스 위키](https://wiki.archlinux.org/index.php/Vim) diff --git a/ko-kr/xml-kr.html.markdown b/ko-kr/xml-kr.html.markdown new file mode 100644 index 00000000..9beef581 --- /dev/null +++ b/ko-kr/xml-kr.html.markdown @@ -0,0 +1,168 @@ +--- +language: xml +filename: learnxml-kr.xml +contributors: + - ["João Farias", "https://github.com/JoaoGFarias"] + - ["Rachel Stiyer", "https://github.com/rstiyer"] + - ["Deepanshu Utkarsh", "https://github.com/duci9y"] +translators: + - ["Wooseop Kim", "https://github.com/linterpreteur"] +lang: ko-kr +--- + +XML은 데이터를 저장하고 전송하기 위해 설계된 마크업 언어입니다. 인간과 기계 모두가 읽을 수 있도록 만들어졌습니다. + +XML은 HTML과는 달리 데이터를 보여주는 방법이나 그 형식을 특정하지 않습니다. 단지 데이터를 담을 뿐입니다. + +차이는 **내용**과 **마크업**에 있습니다. 내용은 무엇이든 될 수 있지만, 마크업은 정의되어 있습니다. + +## 기초 정의 및 도입 + +XML 문서는 기본적으로 자신을 설명하는 *속성*을 가질 수 있으며 자식으로서 텍스트 혹은 다른 요소를 가질 수 있는 *요소*들로 이루어집니다. 모든 XML 문서는 반드시 루트 요소를 가져야 합니다. 루트 요소는 문서에 있는 모든 다른 요소들의 조상입니다. + +XML 파서는 매우 엄격하게 설계되어 있으므로 문서의 형식이 틀렸다면 파싱을 멈출 것입니다. 그러므로 모든 XML 문서는 [(영어) XML 문법 규칙](http://www.w3schools.com/xml/xml_syntax.asp)을 따른다고 보장할 수 있습니다. + +```xml +<!-- 주석에는 두 개의 연속된 하이픈(-)이 들어갈 수 없습니다. --> +<!-- 주석은 여러 줄로 + 이어질 수 있습니다. --> + +<!-- 요소 --> +<!-- 요소는 XML의 기본적 구성품입니다. 요소에는 두 개의 유형이 있습니다. --> +<element1 attribute="value" /> <!-- 빈 요소는 내용을 담지 않습니다. --> +<!-- 그리고 비지 않은 요소가 있습니다. --> +<element2 attribute="value">내용</element2> +<!-- 요소 이름에는 알파벳과 숫자만이 허용됩니다. --> + +<empty /> <!-- 요소는 어떠한 내용도 없이 순수한 마크업인 --> +<!-- 빈 요소 태그로 구성될 수 있습니다. --> + +<notempty> <!-- 혹은 여는 태그와 --> + <!-- 내용, --> +</notempty> <!-- 그리고 닫는 태그로 구성될 수도 잇습니다. --> + +<!-- 요소 이름은 대소문자를 구별합니다. --> +<element /> +<eLEMENT /> +<!-- 둘은 같지 않습니다. --> + +<!-- 속성 --> +<!-- 속성은 요소 안에 존재하는 키와 값의 쌍입니다. --> +<element attribute="value" another="anotherValue" many="space-separated list" /> +<!-- 속성은 원소에서 단 한 번만 나타날 수 있습니다. 속성은 단 하나의 값만 갖습니다. + 이에 대한 흔한 해결책은 공백으로 구분된 리스트를 포함하는 것입니다. --> + +<!-- 중첩 요소 --> +<!-- 한 요소의 내용은 다른 요소들을 포함할 수 있습니다. --> +<parent> + <child>Text</child> + <emptysibling /> +</parent> +<!-- 표준적인 트리 명칭이 사용됩니다. 각각의 요소는 노드라고 부릅니다. + 한 단계 위의 조상은 부모이며, 한 단계 아래의 후손은 자식입니다. + 같은 부모 요소를 가진 요소들은 자매입니다. --> + +<!-- XML은 공백을 보존합니다. --> +<child> + Text +</child> +<child>Text</child> +<!-- 둘은 같지 않습니다. --> +``` + +## XML 문서 + +XML이 유용한 것은 인간도 읽을 수 있다는 것입니다. 다음의 문서는 에릭 레이의 XML 배우기를 포함해 세 권의 책을 파는 서점을 정의한다는 것을 알 수 있습니다. XML 파서 없이도 이렇게 쉽습니다. + +```xml +<?xml version="1.0" encoding="UTF-8"?> +<!-- XML 프롤로그라는 것입니다. 필수는 아니지만, 권장됩니다. --> +<bookstore> + <book category="COOKING"> + <title lang="ko">매일 이탈리아 요리</title> + <author>지아다 데 라우렌티스</author> + <year>2005</year> + <price>30.00</price> + </book> + <book category="CHILDREN"> + <title lang="ko">해리 포터</title> + <author>J K 롤링</author> + <year>2005</year> + <price>29.99</price> + </book> + <book category="WEB"> + <title lang="ko">XML 배우기</title> + <author>에릭 레이</author> + <year>2003</year> + <price>39.95</price> + </book> +</bookstore> +``` + +## 적격성과 유효성 + +XML 문서는 문법적으로 정확할 경우 *적격*합니다. 하지만 문서 유형 정의(DTD)를 이용하여 문서에 제약을 더 추가할 수 있습니다. 한 문서의 요소와 속성이 DTD 안에 정의되어 있고 그 파일에 특정된 문법을 따른다면 *적격*할 뿐만 아니라 그 DTD에 대하여 *유효*하다고 말합니다. + +```xml +<!-- DTD를 외부에 선언: --> +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE bookstore SYSTEM "Bookstore.dtd"> +<!-- bookstore가 루트 요소이며 'Bookstore.dtd'가 DTD 파일의 + 경로임을 선언합니다. --> +<bookstore> + <book category="COOKING"> + <title lang="en">Everyday Italian</title> + <author>Giada De Laurentiis</author> + <year>2005</year> + <price>30.00</price> + </book> +</bookstore> + +<!-- DTD 파일 --> +<!ELEMENT bookstore (book+)> +<!-- bookstore 요소는 하나 이상의 book 요소를 자식으로 가질 수 있습니다. --> +<!ELEMENT book (title, price)> +<!-- 각각의 book은 title과 price를 자식으로 반드시 갖습니다. --> +<!ATTLIST book category CDATA "Literature"> +<!-- book은 category 속성을 가져야 합니다. 그렇지 않다면 그 기본값은 'Literature'입니다. --> +<!ELEMENT title (#PCDATA)> +<!-- title 요소는 반드시 PCDATA만 포함해야 합니다. 즉, + 파서가 읽을 텍스트만을 포함해야 하며 자식을 포함할 수 없습니다. + CDATA와 비교해 보세요. --> +<!ELEMENT price (#PCDATA)> +]> + +<!-- DTD는 XML 파일 안에 선언될 수도 있습니다. --> + +<?xml version="1.0" encoding="UTF-8"?> + +<!DOCTYPE bookstore [ +<!ELEMENT bookstore (book+)> +<!ELEMENT book (title, price)> +<!ATTLIST book category CDATA "Literature"> +<!ELEMENT title (#PCDATA)> +<!ELEMENT price (#PCDATA)> +]> + +<bookstore> + <book category="COOKING"> + <title>Everyday Italian</title> + <price>30.00</price> + </book> +</bookstore> +``` + +## DTD 호환성과 XML 스키마 정의 + +DTD는 오래되었기 때문에 지원이 광범위합니다. 불행히도 네임스페이스와 같은 현대적 XML 기능은 DTD에서 지원하지 않습니다. XML 스키마 정의(XSD)가 XML 문서의 문법을 정의하기 위한 DTD의 대체재입니다. + +## Resources + +* [(영어) Validate your XML](http://www.xmlvalidation.com) + +## Further Reading + +* [(영어) XML 스키마 정의 튜토리얼](http://www.w3schools.com/xml/xml_schema.asp) +* [(영어) DTD 튜토리얼](http://www.w3schools.com/xml/xml_dtd_intro.asp) +* [(영어) XML 튜토리얼](http://www.w3schools.com/xml/default.asp) +* [(영어) XPath 쿼리로 XML 파싱하기](http://www.w3schools.com/xml/xml_xpath.asp) diff --git a/ko-kr/yaml-kr.html.markdown b/ko-kr/yaml-kr.html.markdown new file mode 100644 index 00000000..b6d1de41 --- /dev/null +++ b/ko-kr/yaml-kr.html.markdown @@ -0,0 +1,172 @@ +--- +language: yaml +filename: learnyaml-kr.yaml +contributors: + - ["Adam Brenecki", "https://github.com/adambrenecki"] + - ["Suhas SG", "https://github.com/jargnar"] +translators: + - ["Wooseop Kim", "https://github.com/linterpreteur"] +lang: ko-kr +--- + +YAML은 인간이 직접 쓰고 읽을 수 있도록 설계된 데이터 직렬화 언어입니다. + +YAML은 마치 파이썬처럼 개행과 들여쓰기에 문법적으로 의미를 준 JSON의 엄격한 수퍼셋입니다. +하지만 파이썬과는 달리 YAML은 탭 문자를 전혀 허용하지 않습니다. + +```yaml +# YAML의 주석은 이런 식입니다. + +############ +# 스칼라 형 # +############ + +# 문서 내내 이어질 루트 객체는 맵입니다. +# 맵은 다른 언어의 딕셔너리, 해시, 혹은 객체에 해당됩니다. +키: 값 +다른_키: 다른 값이 여기 옵니다. +숫자_값: 100 +# 숫자 1을 값으로 가지기 위해서는 따옴표에 담아야 합니다. +# 그러지 않는다면 YAML 파서는 그것을 참 값을 가지는 불리언으로 해석할 것입니다. +과학적_표기법: 1e+12 +불리언: true +널_값: null +띄어서 쓴 키: 값 +# 문자열에 따옴표를 칠 필요는 없습니다. 하지만 칠 수도 있습니다. +하지만: "따옴표에 담은 문자열" +"키도 따옴표에 담을 수 있습니다.": "키에 ':'을 넣고 싶다면 유용합니다." + +# 여러 줄의 문자열은 (|을 이용한) '리터럴 블락' 혹은 (>을 이용한) '접은 블락'으로 +# 쓸 수 있습니다. +리터럴_블락: | + 개행을 포함한 이 모든 덩어리가 '리터럴_블락' 키에 대응하는 값이 될 것입니다. + + 리터럴 값은 들여쓰기가 끝날 때까지 계속되며 들여쓰기는 문자열에 포함되지 + 않습니다. + + '들여쓰기를 더 한' 줄은 나머지 들여쓰기를 유지합니다. + 이 줄은 띄어쓰기 4개만큼 들여쓰기 됩니다. +접는_방식: > + 이 텍스트 덩어리가 전부 '접는_방식' 키의 값이 되지만, 이번에는 모든 개행 문자가 + 띄어쓰기 하나로 대체됩니다. + + 위와 같이 텅 빈 줄은 개행 문자로 바뀝니다. + + '더 들여쓴' 줄 역시 개행 문자를 유지합니다. + 이 텍스트는 두 줄에 걸쳐 나타날 것입니다. + +########## +# 모임 형 # +########## + +# 중첩은 들여쓰기로 가능합니다. +중첩된_맵: + 키: 값 + 다른_키: 다른 값 + 다른_중첩된_맵: + 안녕: 안녕 + +# 맵은 반드시 문자열 키를 가지는 것은 아닙니다. +0.25: 실수형 키 + +# 키는 여러 줄에 걸친 객체와 같이 복합적일 수도 있습니다. +# ?와 그 뒤의 띄어쓰기로 복합 키의 시작을 나타냅니다. +? | + 여러 줄짜리 + 키 +: 그리고 그 값 + +# YAML은 복합 키 문법으로 연속열 간의 매핑을 지원합니다. +# 일부 파서는 지원하지 않을 수 있습니다. +# 예시 +? - 맨체스터 유나이티드 + - 레알 마드리드 +: [ 2001-01-01, 2002-02-02 ] + +# 리스트 혹은 배열에 대응되는 연속열은 다음과 같습니다. +연속열: + - 하나 + - 둘 + - 0.5 # 연속열은 다른 형을 포함 가능 + - 넷 + - 키: 값 + 다른_키: 다른_값 + - + - 연속열 안의 + - 또 다른 연속열 + +# YAML은 JSON의 수퍼셋이기 때문에, JSON식으로 맵과 연속열을 작성할 수도 +# 있습니다. +제이슨_맵: {"키": "값"} +제이슨_열: [3, 2, 1, "발사"] + +################# +# 기타 YAML 기능 # +################# + +# YAML은 '앵커'라는 편리한 기능이 있습니다. 앵커를 이용하면 문서에서 +# 손쉽게 내용을 복제할 수 있습니다. 이 키들은 같은 값을 갖습니다. +앵커된_내용: &앵커_이름 이 문자열은 두 키의 값으로 나타납니다. +다른_앵커: *앵커_이름 + +# 앵커는 속성을 복제하거나 상속할 수 있습니다. +기반: &기반 + 이름: 모두 이름이 같다 + +멍멍: &멍멍 + <<: *기반 + 나이: 10 + +야옹: &야옹 + <<: *기반 + 나이: 20 + +# 멍멍이와 야옹이는 같은 이름, '모두 이름이 같다'를 같습니다. + +# 또한 YAML에는 명시적으로 형을 선언할 수 있는 태그가 있습니다. +명시적_문자열: !!str 0.5 +# 파이썬의 복소수 형을 나타내는 다음 태그처럼, 일부 파서는 언어에 종속된 태그를 +# 구현합니다. +파이썬_복소수: !!python/complex 1+2j + +# YAML 복합 키를 언어 종속 태그와 함께 사용할 수도 있습니다. +? !!python/tuple [5, 7] +: 오십칠 +# 파이썬에서의 {(5, 7): '오십칠'} 객체 + +############### +# 기타 YAML 형 # +############### + +# Strings and numbers aren't the only scalars that YAML can understand. +# YAML이 이해할 수 있는 스칼라는 문자열과 수만 있는 것은 아닙니다. +# ISO 형식 날짜와 시간 리터럴 또한 해석됩니다. +시간: 2001-12-15T02:59:43.1Z +띄어쓰기_한_시간: 2001-12-14 21:59:43.10 -5 +날짜: 2002-12-14 + +# !!binary 태그는 문자열이 실제로는 base64로 인코딩된 +# 이진수 객체(BLOB)라는 것을 나타냅니다. +이미지_파일: !!binary | + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= + +# YAML에는 다음과 같은 집합도 있습니다. +집합: + ? 하나 + ? 둘 + ? 셋 + +# 파이썬과 마찬가지로 집합은 단지 널 값을 갖는 맵입니다. 위는 다음과 같습니다. +집합2: + 하나: null + 둘: null + 셋: null +``` + +### 더 읽기 + ++ [(영어) YAML 공식 사이트](http://yaml.org/) ++ [(영어) 온라인 YAML 검사기](http://codebeautify.org/yaml-validator) |