Programming in Sala 책으로 스칼라 스터디하면서 정리했던 내용이다. 지금은 3판 번역본도 나왔지만, 약간 앞서서 스터디를 시작해서 2판으로 진행하고 있다.


5장

기본 타입

  • Byte / Short / Int / Long : 8 / 16 / 32 / 64 bits 부호 있는 정수(2의 보수)
  • Char : 16 bits 유니코드 문자
  • String : Char 시퀀스
  • Float / Double : 32 / 64 bits IEEE 754 단정도/배정도 부동소수점 수
  • Boolean : true / false

리터럴

정수

  • 10진 : 5, 7, ..
  • 16진 : 0x5, 0x00FF
  • Long : 35L, 31l

부동소수점

  • 1.2345
  • 1,2345e1
  • 123E45
  • Float : 1.2345F, 3e5f
  • Double(기본) : 3e5D

문자

  • 'A'
  • '\101'
  • '\u0041'

이스케이프 시퀀스(escape sequence)

  • \n : 줄바꿈(\u000A)
  • \b : 백스페이스(\u0008)
  • \t : 탭(\u0009)
  • \f : 페이지 넘김(\u000C)
  • \r : 줄 맨 앞으로(\u000D)
  • " : 큰따옴표(\u0022)
  • ' : 작은따옴표(\u0027)
  • \ : 역슬래스(\u005C)

문자열

  • "hello"
  • """Welcome ... """
  • stripMargin
println("""|Welcome to Ultamix 3000.
           |Type "HELP" for help.""".stripMargin)

심볼

  • 작은따옴표 뒤에 오는 식별자(알파벳,숫자) : 'ident
  • 'ident -> 내부에서 Symbol("ident") 호출됨
  • intern. 같은 심볼 리터럴은 동일한 객체를 참조.

불리언

  • true / false

연산자

  • 어떤 메소드든지 연산자가 될 수 있음
s.indexOf('o', 5)
s indexOf ('o', 5) // 동일함
  • 연산자는 메소드
    • 중위 연산자 : 1 + 2 == (1).+(2)
    • 전위 연산자 : -2.0 == (2.0).unary_-
    • 후위 연산자 : s toLowerCase == s.toLowerCase()

산술 연산자

  • +, -, *, /, %

관계, 논리 연산자

  • , <, >=, <=, !

  • &&, ||

비트 연산자

  • &, |, ^

객체 동일성

  • ==, != 사용하여 두 객체가 동일한지 여부를 확인
  • null을 포함한 어떤 객체라도 사용 가능
  • 내부적으로 null인지 확인하고, null 이 아닌 경우 equals 메소드를 수행함

연산자 우선순위

  • 연산자 시작하는 문자에 따라서 아래와 같은 순서로 우선 순위 판단
  1. (all other special characters)
  2. */%
  3. +-
  4. :
  5. =! <> &
  6. ˆ
  7. |
  8. (all letters)
  9. (all assignment operators)
  • 메소드가 ':'로 끝나면 오른쪽에서 왼쪽으로 연산되고, 다른 경우는 왼쪽에서 오른쪽으로 연산

리치 래퍼

  • 묵시적 변환(implicit conversion)으로 기본 타입에 더 많은 메소드를 실행 가능
0 max 5             // 5
0 min 5             // 0
-2.7 abs            // 2.7
-2.7 round          // -3L
1.5 isInfinity      // false
(1.0/0) isInfinity  // true
4 to 6              // Range(4,5,6)
"bob" capitalize    // "Bob"
"robert" drop 2     // "bert"
  • 위와 같은 메소드는 다음과 같은 레퍼 타입에 정의되어 있음
    • Byte - scala.runtime.RichByte
    • Short - scala.runtime.RichShort
    • Int - scala.runtime.RichInt
    • Char - scala.runtime.RichChar
    • Float - scala.runtime.RichFloat
    • Double - scala.runtime.RichDouble


Programming in Sala 책으로 스칼라 스터디하면서 정리했던 내용이다. 지금은 3판 번역본도 나왔지만, 약간 앞서서 스터디를 시작해서 2판으로 진행하고 있다.


4장

클래스

  • 클래스 정의
class ChecksumAccumulator {
    // 클래스 정의
}
  • 객체 생성 : new
new ChecksumAccumulator
  • 필드, 메소드는 멤버

필드

  • 필드 정의 : val, var
  • 인스턴스 변수라고도 함
  • 기본 접근 수준은 전체 공개
  • 비공개 필드 : private
class ChecksumAccumulator {
    private var sum = 0
}

메소드

  • 메소드 정의 : def
  • 메소드 파라미터는 val
  • 권장 스타일
    • return을 명시적으로 사용하지 않는 것 -> 메소드는 한 값을 계산하는 표현식
    • 하나의 표현식만 있으면 중괄호 생략
    • 결과식이 짧으면 def 문 줄에 함께 쓰기
class ChecksumAccumulator {
    private var sum = 0
    def add(b: Byte): Unit = sum += b
    def checksum(): Int = ~(sum & 0xFF) + 1
}
  • 결과 타입이 Unit 인 경우
    • 부수 효과를 위해 사용
    • = 생략하고 {}로 감싸는 것으로 표현 가능
    def add(b:Byte) { sum += b }

세미콜론 추론

다음 세가지 경우가 아니면 줄의 끝은 세미콜론으로 취급된다.

  1. 줄이 명령을 끝낼 수 있는 단어로 끝나지 않는다. 마침표(.)나 중위 연산자 등의 줄의 맨 끝에 있는 경우
  2. 다음 줄의 맨 앞이 문장을 시작할 수 없는 단어로 시작한다.
  3. 줄이 () 사이나 [] 사이에서 끝난다.

싱글톤 객체

  • 클래스 정의와 비슷하나 object 키워드 사용
object ChecksumAccumulator {
    // ...
}
  • 싱글톤 객체는 1급 계층
  • 파라미터를 전달할 방법 없음
  • 클래스를 확장(extend)하거나 트레이트를 믹스인(mix in) 가능
  • 자체 타입을 정의하지는 않음

동반 객체와 동반 클래스

  • 동반 객체(companion object) : 어떤 클래스 이름과 동일한 이름의 싱글톤 객체
  • 동반 클래스(companion class) : 어떤 싱글톤 객체와 동일한 이름의 클래스
  • 독립 객체(standalone object) : 동반 클래스가 없는 싱글톤 객체
  • 클래스와 동반 객체는 서로의 비공개 멤버에 접근할 수 있다.

스칼라 애플리케이션

  • 다음과 같은 main 메소드를 가진 독립 싱글톤 객체가 애플리케이션의 시작점
    • 인자 : Array[String]
    • 반환값 : Unit
object Summer {
    def main(args: Array[String]) {
        // ...
    }
}
  • 클래스 이름과 파일이름을 동일하게 만드는 것이 강제 사항은 아님.
  • 컴파일 : scalac, fsc

Application 트레이트

object FallWinterSpringSummer extends Application {
    // main 메소드 내용
}
  • scala.Application -> scala.App


Programming in Sala 책으로 스칼라 스터디하면서 정리했던 내용이다. 지금은 3판 번역본도 나왔지만, 약간 앞서서 스터디를 시작해서 2판으로 진행하고 있다.


3장

배열

  • 파라미터화(parameterization) : new를 사용해 객체를 인스턴스화 할때에 값과 타입을 파라미터로 전달하는 것
val greetStrings: Array[String] = new Array[String](3)
  • 인스턴스 타입은 타입 파라미터 까지만 포함됨 : (3) 은 제외
val greetStrings = new Array[String](3)
greetStrings(0) = "Hello"
greetStrings(1) = ", "
greetStrings(2) = "World!\n"
for (i <- 0 to 2)
  print(greetStrings(i))
  • 메소드가 파라미터를 하나만 요구하는 경우, 그 메소드를 점(.)과 괄호 없이 호출할 수 있다. 단, 호출 대상 객체가 명시적으로 지정되어 있는 경우에 가능 0 to 2 === (0).to(2)
  • 스칼라는 전통적인 의미의 연산자가 없으므로 연산자 오버로드를 제공하지 않으며, 대신 +, -, *, / 등의 문자를 메소드 이름으로 사용 가능 1 + 2 === (1).+(2)
  • 배열도 평범한 인스턴스 : 변수 뒤에 하나 이상의 값을 괄호로 둘러싸서 호출하면, 스칼라는 변수에 대해 apply 메소드 호출 greetStrings(i) === greetStrings.apply(i)
  • 변수 뒤에 괄호로 둘러싼 인자들이 있는 표현식에 할당을 하면, 스칼라는 update 메소드를 호출 greeStrings(0) = "Hello" === greetStrings.update(0, "Hello")
val numNames = Array("zero", "one", "two")
  • Array의 동반 객체에 정의된 apply라는 팩토리 메소드 호출

리스트

같은 타입의 변경 불가능한 시퀀스

val oneTwo = List(1,2)
val threeFour = List(3,4)
val oneTwoThreeFour = oneTwo ::: threeFour
  • 리스트 자체를 변환하지 않고 새 값을 갖는 리스트를 만든다.
val twoThree = List(2,3)
val oneTwoThree = 1 :: twoThree
  • : 로 이름이 끝나는 메소드는 오른쪽 피연산자에 대해 호출한다.
val oneTwoThree = 1 :: 2 :: 3 :: Nil
  • List() === Nil

리스트 메소드

  • List() / Nill : 빈 리스트
  • List(1,2,3) / 1 :: 2 :: 3 :: Nill : 원소들로 구성된 리스트
  • List(1, 2) ::: List(3, 4) : 두 리스트를 연결한 리스트
  • thrill(2) : thrill 리스트의 세번째 원소
  • thrill.count(s => s.length == 4) : 길이가 4인 것의 갯수
  • thrill.drop(2) : 처음 두 원소를 뺀 리스트
  • thrill.dropRight(2) : 마지막 두 원소를 뺀 리스트
  • thrill.exists(s => s == "until") : "until"이 리스트에 있는지 여부
  • thrill.filter(s => s.length == 4) : 길이가 4인 것들의 리스트
  • thrill.forall(s => s.endsWith("l")) : 모든 원소가 끝이 "l"로 끝나는지 여부
  • thrill.foreach(s => print(s)) : 리스트의 모든 원소에 대해서 print 실행
  • thrill.foreach(print) : 상동
  • thrill.head : 첫번째 원소
  • thrill.init : 마지막 원소 제외한 나머지
  • thrill.isEmpty : 리스트가 비어있는지 여부
  • thrill.last : 마지막 원소
  • thrill.length : 리스트의 길이
  • thrill.map(s => s + "y") : 각 원소 뒤에 "y"를 추가한 리스트
  • thrill.mkString(", ") : 원소들을 ", "로 연결한 문자열
  • thrill.remove(s => s.length == 4) : 길이가 4인 것을 제외한 리스트
  • thrill.reverse : 원소를 역순으로 한 리스트
  • thrill.sort((s, t) => s.charAt(0).toLower < t.charAt(0).toLower) : 알파벳 순서 정렬한 리스트
  • thrill.tail : 첫번째 원소를 제외한 리스트

튜플

다른 타입의 원소들을 갖는 변경 불가능한 시퀀스

val pair = (99, "Luftballons")
println(pair._1) // 99
println(pair._2) // Luftballons
  • apply 메소드는 항상 동일한 타입 객체를 반환하기 때문에 pair(0)과 같이 할 수 없음.
  • 하스켈, ML 등의 영향으로 인덱스가 1부터 시작

집합과 맵

변경가능 / 불가능 모두 제공

변경 불가능 Set

var jetSet = Set("Boeing", "Airbus")
jetSet += "Lear"

변경 가능 Set

import scala.collection.mutable.Set
val movieSet = Set("Hitch", "Poltergeist")
movieSet += "Shrek"

변경 불가능 Map

val romanNumeral = Map(
    1 -> "I", 2 -> "II", 3 -> "III", 4 -> "IV", 5 -> "V"
)
  • -> 메소드를 호출하면 해당 객체를 키로하고 인자를 값으로 하는 원소가 2개인 튜플을 생성

변경 가능 Map

import scala.collection.mutable.Map
val treasureMap = Map[Int, String]()
treasureMap += (1 -> "Go to Island.")

함수형 스타일

  • 코드에 var가 있으면 명령형 스타일, 아니면 함수형 스타일
  • val, 불변객체, 부수 효과 없는 메소드를 먼저 사용해보고, 꼭 필요한 경우에만 var, 가변객체, 부수 효과 있는 메소드를 사용하라

파일

import scala.io.Source
if (args.length > 0) {
    for (line <- Source.fromFile(args(0)).getLines())
        println(line.length + " " + line)
}
else
    Console.err.println("Please enter filename")


Programming in Sala 책으로 스칼라 스터디하면서 정리했던 내용이다. 지금은 3판 번역본도 나왔지만, 약간 앞서서 스터디를 시작해서 2판으로 진행하고 있다.

2장

인터프리터 사용법

  • 대화형 셸 $ scala
  • res번호 식별자는 변수 처럼 사용 가능 ex> res0 * 3
  • println("Hello, world!")

변수 정의

  • val : 재할당 불가능
  • var : 재할당 가능
  • 타입 추론으로 타입을 지정하지 않아도 됨
val msg = "Hello"
val msg2: java.lang.String = "Hello"
val msg3: String = "Hello"

var msg4 = "Hello"
msg4 = "World"

함수 정의

def max(x: Int, y: Int): Int = {
    if (x < y) x
    else y
}
  • def : 함수 정의 시작
  • max : 함수 이름
  • (x: Int, y: Int) : 인자 항목
  • Int : 함수 결과 타입
  • = : 등호
  • { } : 함수 본문

Unit 결과 타입은 함수가 의미있는 결과를 반환하지 않는다는 의미

스칼라 스크립트

  • 실행 방법 예 $ scala hello.scala
  • 명령행 인자 접근 : args args(0), args(1), ...

반복 / 분기

  • while while (i < args.length)
  • if if (i != 0) print(" ")
  • foreach args.foreach(arg => println(arg)) args.foreach(println)
  • for for (arg <- args) println(arg)

함수 리터럴

(x: Int, y: Int) => x + y
  • (x: Int, y: Int) : 인자 항목
  • => : 오른쪽 화살표
  • x + y : 함수 본문

함수 리터럴이 인자를 하나만 받는 문장인 경우에는 해당 인자에 이름을 붙일 필요가 없다 (8.6절)


Programming in Sala 책으로 스칼라 스터디하면서 정리했던 내용이다. 지금은 3판 번역본도 나왔지만, 약간 앞서서 스터디를 시작해서 2판으로 진행하고 있다.


1장

스칼라

  • 확장 가능 언어
  • 객체지향과 함수형 프로그래밍 개념을 정적 타입 언어에 합쳐 놓은 언어

확장성

타입

  • 언어가 기본 지원하는 것처럼 느껴지는 스칼라 표준 라이브러리로 타입을 제공
  • 라이브러리로 새로운 타입을 만들어 내장 타입처럼 편하게 사용할 수 있음

제어구조

  • 액터 모델을 구현하는 라이브러리를 제공하여 스칼라 내장 구성요소처럼 사용함
  • 새로운 분야에 대한 추상화를 설계/구현하고 언어가 원래 지원하는 것처럼 사용 가능

확장성의 이유

객체지향적

  • 스칼라는 순수한 형태의 객체지향 언어 : 모든 값은 객체, 모든 연산은 메소드
  • Trait : 끼워넣기 좋은 구성 요소

함수형

  • 함수는 1급 계층 값 : 인자로 넘길 수 있고, 변수에 저장 가능하고, 함수에서 반환 가능
  • 메소드에는 부수 효과가 없어야 함

스칼라 장점

  • 호환성 : 자바 메소드 호출, 필드 접근, 클래스 상속, 인터페이스 구현 가능
  • 간결함 : 적은 얼개 코드 사용, 타입 추론, 라이브러리 정의 도구
  • 고수준 : 높은 수준 추상화 가능
  • 정적타입
    • 타입 추론으로 장황함 회피, 패턴 매치와 타입을 쓰고 합성하는 방법으로 유연성 확보
    • 프로퍼티 검증, 안전한 리펙토링, 문서화

스칼라의 뿌리

  • 문법 : 자바, C#
  • 일관성 있는 객체 모델 : 스몰토크, 루비
  • 보편적인 내포 : 알골, 시뮬라, Beta, gbeta
  • 메소드 호출, 필드 선택을 통일하게 처리하는 단일 접근 원칙 : Eiffel
  • 함수형 프로그래밍 접근 방식 : SML, OCaml, F#
  • 스칼라 표준 라이브러리의 고차 함수 중 다수 : ML, 하스켈
  • 암시적 파라미터 : 하스켈의 타입 클래스
  • 액터 기반 동시성 라이브러리 : 얼랑


개발 중에 필요한 테스트 환경을 쉽게 구성해주는 도구인 Laravel Homestead를 Linux나 Mac에서 사용하는 방법을 정리해보았다. 공식 문서는 개발자들의 표준 컴퓨터인 Mac을 기준으로 되어있기 때문에 그 내용에서 크게 다를 것은 없다. Windows에서 사용하는 방법은 다음 글을 참고하자.

vagrant 기반으로 만들어진 Laravel Homestead는 다음 환경으로 구성되어 있다.

이와 같이 복잡해 보이는 운영 스택을 명령어 4개 입력하고 파일 2개 편집하는 것으로 간단히 구성할 수 있다.


1. 필요한 것

vagrantVirtualBox 설치가 필요하다. 공식 사이트에서 내려받아서 설치해도 되고, 패키지 시스템에 있다면 그걸 설치해도 되겠다. Mac이나 Linux를 쓸 정도라면 git은 이미 설치가 되어있겠지만, 혹시 없다면 이것도 설치한다.


2. Homestead 프로젝트 받기

아래와 같이 github에서 Homestead 프로젝트 저장소를 내려받는다.

git clone https://github.com/laravel/homestead.git Homestead

PHP7을 사용하고 싶다면 아래와 같이 프로젝트를 받는다.

git clone -b php-7 https://github.com/laravel/homestead.git Homestead


3. SSH 키 생성

가상환경에서 사용할 SSH 키 생성이 필요한데, 이미 생성해둔 것이 없다면 아래 명령어로 생성한다.

ssh-keygen -t rsa -C "you@homestead"


4. 설정

프로젝트 저장소를 내려받은 곳으로 이동한 뒤에 다음을 실행한다.

bash init.sh

실행하고 나면, ~/.homestead 디렉토리가 만들어지고, 그 안에 아래와 같은 내용의 Homestead.yaml 파일이 생성된다.

---
ip: "192.168.10.10"
memory: 2048
cpus: 1
provider: virtualbox

authorize: ~/.ssh/id_rsa.pub

keys:
    - ~/.ssh/id_rsa

folders:
    - map: ~/Projects
      to: /home/vagrant/Code

sites:
    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public

databases:
    - homestead

variables:
    - key: APP_ENV
      value: local

# blackfire:
#     - id: foo
#       token: bar
#       client-id: foo
#       client-token: bar

# ports:
#     - send: 93000
#       to: 9300
#     - send: 7777
#       to: 777
#       protocol: udp

위의 내용에서 굵게 표시한 내용이 확인이 필요한 내용으로, 설명은 아래와 같다.

  • ip : 가상환경에서 사용할 ip. 별 문제없으면 기본값을 사용하면 된다.
  • authorize : 공개키 파일 위치
  • keys : 개인키 파일 위치
  • folders : VirtualMachine과 공유할 디렉토리 설정
  • sites : 가상 환경에서 연결할 프로젝트 경로. folders에서 연결한 경로 하위 디렉토리를 도메인으로 연결할 수 있다.


5. hosts 파일 수정

sites - map 항목에 연결한 도메인을 /etc/hosts 파일에 추가한다.

192.168.10.10    homestead.app


6. Homestead 실행

아래 명령어로 Homestead를 실행한다.

vagrant up

처음 실행하는 것이면, box(vagrant에서 사용하는 이리 생성된 가상 머신 템플릿)를 다운로드 받는데 시간이 좀 걸린다.


7. 사용

여기까지 모두 끝났으면, 브라우저를 띄워서 위에서 설정한 도메인(위의 경우 homestead.app)을 입력하면 프로젝트 화면이 나올 것이다. 공유 폴더로 연결되어 있기 때문에 프로젝트 디렉토리의 변경사항은 바로 반영된다.

가상 머신에 SSH를 사용하여 접속하는 것도 가능한데, 생성해둔 SSH 개인키를 사용하지 않을 경우에는 아이디/패스워드 모두 "vagrant" 를 입력하여 접속할 수 있다.


명령어 한줄로 SSH 키를 만들 수 있는 *NIX 운영체제와는 달리, 윈도우에서는 키를 만들기 위해서 별도의 도구가 필요하다. 보통은 PuTTY를 설치하면 같이 설치되는 PuTTYgen을 사용한다.


1. 준비


PuTTY를 설치했다면 보통 PuTTYgen도 같이 설치되어있지만, 혹시 없다면 puttygen.exe 파일을 내려받는다.



2. 개인키 생성


PuTTYgen을 실행하면 아래와 같은 화면이 나온다.



이 화면에서 "Generate" 버튼을 누르면 아래와 같은 화면을 볼 수 있다.



진행 막대 아래에 있는 공간에서 마우스 포인터를 움직여주면, 키 생성 작업이 진행된다. 키 생성이 끝나면 아래 화면으로 바뀌게 된다.



3. 저장



이 화면에서 "Save private key" 버튼을 누르면 개인키를 저장하는데, Key passphrase 가 없다는 메시지가 나온다. 대부분의 경우 비밀번호 입력 대신에 사용할 용도로 키를 만들기 때문에 무시하고 저장하면 된다. 공개키는 "Save public key" 버튼도 눌러서 저장하거나, 화면에 나온 내용을 복사해서 사용해도 된다.

Laravel HomesteadLaravel 개발 시에 테스트를 위한 가상환경을 편리하게 구성할 수 있도록 도와주는 도구이다. 하지만, 기본적으로 PHP 프로젝트를 위한 환경 구성이기 때문에, Laravel만 아니라, PHP로 개발하면서 테스트 환경이 필요할 때에도 유용하게 사용할 수 있다. Homestead는 아래와 같은 환경으로 구성되어 있다.

Laravel Homestead는 vagrant로 만들어져 있으며, (Mac OS X를 포함한) *NIX 계열 OS에서는 사용하기 편리하게 만들어져 있지만, 공식 문서의 설명도 Windows 사용자는 배려하지 않고 있다. 하지만, Windows에서도 아래와 같은 순서대로 따라하면, 그다지 어렵지 않게 사용할 수 있다.


1. 필요한 것

  • vagrant 설치 : 에서 설치 파일을 다운로드 받아서 설치한다.
  • Oracle VirtualBox 설치 : 역시 에서 설치파일을 다운로드 받아서 설치한다. VMWare를 사용할 수도 있지만, VMWare를 사용하는 경우에는 PlugIn도 설치해야 해서, 게다가 유료이고, Virtual Box만 테스트해보았다.
  • git 설치 : 간단하게 zip파일을 다운로드하는 방법도 있지만, git을 설치하면 쉘스크립트를 실행하기 위해서 필요한 bash도 같이 설치되어 설치 절차가 간편해진다. 개발자라면 대부분 설치했겠지만, 아직 설치하지 않았다면 git 에서 Windows 용 설치파일을 다운로드 받아서 설치한다.
  • BIOS 설정 확인 : 하드웨어 가상화(VT-x)가 켜져 있는지 확인한다.


2. Homestead 프로젝트 받기

아래와 같이 github에서 Homestead 프로젝트 저장소를 내려받는다.

git clone https://github.com/laravel/homestead.git Homestead

PHP7을 사용하고 싶다면 아래와 같이 프로젝트를 받는다.

git clone -b php-7 https://github.com/laravel/homestead.git Homestead


3. SSH 키 생성

가상환경에서 사용할 SSH 키 생성이 필요하다. 의 설명을 참고해서 공개키/개인키 파일을 만든다. 키 파일을 저장힐때, 사용자 폴더(이하 %HOME%) 밑에 .ssh 라는 폴더를 만들어서 각각 아래 이름으로 만들면, 설정에서 키 관련한 설정은 신경쓸 필요가 없다.

  • 공개키 : id_rsa.pub
  • 개인키 : id_rsa


4. 설정

Git을 설치했다면, Git Bash라는 것도 함께 설치되었을텐데, 이것을 실행한 뒤에 프로젝트 저장소를 내려받은 곳으로 이동한 뒤에 다음을 실행한다.

bash init.sh

그러면, 사용자 폴더(이하 %HOME%)에 .homestead 라는 폴더가 생성된다.

%HOME%\.homestead\Homestead.yaml 파일을 에디터로 열면 대략 아래와 같은 내용이 있을 것이다.

---
ip: "192.168.10.10"
memory: 2048
cpus: 1
provider: virtualbox

authorize: ~/.ssh/id_rsa.pub

keys:
    - ~/.ssh/id_rsa

folders:
    - map: ~/Projects
      to: /home/vagrant/Code

sites:
    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public

databases:
    - homestead

variables:
    - key: APP_ENV
      value: local

# blackfire:
#     - id: foo
#       token: bar
#       client-id: foo
#       client-token: bar

# ports:
#     - send: 93000
#       to: 9300
#     - send: 7777
#       to: 777
#       protocol: udp

위의 내용에서 굵게 표시한 내용이 확인이 필요한 내용으로, 설명은 아래와 같다.

  • ip : 가상환경에서 사용할 ip. 별 문제없으면 기본값을 사용하면 된다.
  • authorize : 공개키 파일 위치
  • keys : 개인키 파일 위치
  • folders : VirtualMachine과 공유할 폴더 설정
  • sites : 가상 환경에서 연결할 프로젝트 경로. folders에서 연결한 경로 하위 폴더를 도메인으로 연결할 수 있다.


5. hosts 파일 수정

sites - map 항목에 연결한 도메인을 Windows\system32\drivers\etc\hosts 파일에 추가한다. (관리자 권한 필요)

192.168.10.10    homestead.app


6. Homestead 실행

커맨드라인 창을 띄우고(git bash도 무관) 아래 명령어를 실행한다.

vagrant up

처음 실행하는 것이면, box(vagrant에서 사용하는 이리 생성된 가상 머신 템플릿)를 다운로드 받는데 시간이 좀 걸린다.


7. 사용

여기까지 모두 끝났으면, 브라우저를 띄워서 위에서 설정한 도메인(위의 경우 homestead.app)을 입력하면 프로젝트 화면이 나올 것이다. 공유 폴더로 연결되어 있기 때문에 프로젝트 폴더의 변경사항은 바로 반영된다.

가상 머신에 SSH를 사용하여 접속하는 것도 가능한데, 생성해둔 SSH 개인키를 사용하지 않을 경우에는 아이디/패스워드 모두 "vagrant" 를 입력하여 접속할 수 있다.


이 책을 보기 전에 "프로그래밍 수수계끼 모음집"이라는 소개만 보고 자바로 해결하는 알고리즘 문제를 담은 책이라고 생각했는데, 예상이 빗나갔다. 이 책은 자바 언어의 특성을 잘 모르면 발생할 수 있는 문제점을 다루고 있었다.

무거울 것 같은 내용과는 달리 "세상에서 가장 재미있는 자바 책"이라는 수식어를 달아놨는데, 실제로 가벼운 퍼즐 책과 같은 형식이라서 부담없이 읽기 좋았다. 알고리즘 문제처럼 많은 시간을 들여서 문제를 반드시 풀어봐야하는 것도 아니라서, 어떤 함정이 있을지 예상해보면서 문제를 풀어보기도 하고, 좀 어려울 것 같다 싶으면 바로 답을 볼 수 있도록 문제와 답이 바로 붙어 있다.

이 책의 원서는 자바 5 시절에 만들어졌지만, 자바 8에서도 이 책에서 다루고 있는 내용이 여전히 유효하다고 하니, 고전이라고 부를만한 것 같다. 재미있게 읽으면서 주요 내용을 머릿 속에 잘 기억해두면, 자바로 프로그램을 작성할때 알 수 없는 오류로 골치아플 일을 많이 덜게 될 것 같다.


자바 퍼즐러

저자
조슈아 블로크, 닐 개프터 지음
출판사
한빛미디어 | 2014-12-04 출간
카테고리
컴퓨터/IT
책소개
단언컨대 이 책은 세상에서 가장 재미있는 자바 책입니다. 왜냐하...
가격비교


'Etc' 카테고리의 다른 글

Pencil  (0) 2017.11.29
자바 퍼즐러  (0) 2015.06.25
Ship it 성공적인 소프트웨어 개발 프로젝트를 위한 실용 가이드  (0) 2015.06.24
프로그래머 그 다음 이야기  (0) 2015.06.23

소프트웨어 개발을 잘 하기위한 실용적인 조언들과 "예광탄 개발"이라는 개발 방법론을 소개하고 있다.

저자들이 고안했다는 예광탄 개발 방법은 일종의 점진적 개발 방법이다. 소프트웨어를 한 사람, 혹은 한 팀이 일정기간 일할 수 있을 정도로 객체/계층으로 나누고 각 계층의 인터페이스를 정의한 다음에 Mock/Stub을 먼저 개발해 전체 동작을 확인할 수 있도록 만든 다음에 내용을 채우는 것으로 개발을 진행하는 방식이다. 점진적 개발 방식은 다 그렇겠지만, 개발 초기에 요구 사항을 재확인하고, 설계의 결함을 발견하기 좋은 개발 방식으로 보인다.

그리고 책 전체에 걸쳐서 다음과 같은 조언들을 담고 있다.

  1. (의식적으로, 신중하게 좋은) 습관을 선택하세요.
  2. 모래 상자 안에서 노세요.
  3. (빌드를 위해서) 필요한 거라면 체크인(커밋) 하세요.
  4. 첫날에 빌드를 스크립트화 하세요.
  5. 어떤 컴퓨터에서라도 빌드가 되어야 합니다.
  6. 지속적으로 빌드하세요.
  7. 지속적으로 테스트하세요.
  8. (이슈 추적 시스템 등을 사용해서) 모두가 잊어버리는 사태는 피해야 합니다.
  9. 제품을 작동시켜보세요 - 테스트를 자동화하세요.
  10. 유연하고 많은 사람이 사용하는 테스트 장비를 사용하세요.
  11. 업무에 가장 적합한 도구를 사용하세요.
  12. 공개된 포맷을 사용해서 여러 도구를 통합하세요.
  13. (프로젝트 진행에 영향을 줄 수있는 SCM이나 빌드 스크립트 등의) 임계 경로 기술에 친숙해지세요.
  14. 목록에 따라 일하세요.
  15. 기술 리더가 알아서 하게 놔두세요.
  16. 일일 회의를 해서 진행 방향을 수시로 바로 잡으세요.
  17. (집중하고 있을때에는) "나중에"라고 말해도 됩니다.
  18. 항상 모든 코드를 검토하세요.
  19. 소프트웨어가 목표지, (업무 처리 기법에) 순응이 목표는 아닙니다.
  20. 그룹 전체가 (전체 시스템을 개선할 수 있는) 아키텍트입니다.
  21. (실제 환경의) 제품에서 사용하는 거라면, (개발 환경에서) 여러분도 사용해야 합니다.
  22. (핵심 기능인) 가장 어려운 문제부터 해결하세요.
  23. 캡슐화된 아키텍처야말로 확장성 있는 아키텍처입니다.
  24. 보트가 움직이기 전엔 보트를 조정할 수가 없습니다.
  25. 테스트하기 전에는 다른 사람이 물려준 코드를 변경하지 마세요.
  26. 테스트 주도 리펙토링으로 테스트할 수 없는 코드를 깨끗이 정리하세요.
  27. 가짜 클라이언트로 최소한의 노력으로 최대의 성과를 거둘 수 있습니다.
  28. 변경되는 코드를 지속적으로 테스트하세요.
  29. (버그를 수정하는 것은) 모두에게 통하는 방법이어야 합니다.
  30. (CI 시스템을 사용하여) 자주 통합하고, 지속적으로 빌드하고 테스트하세요.
  31. (고객에게) 동작하는 데모를 일찍 그리고 자주 전달하세요.
  32. (불만스러워하는 관리자를 위해서) 여러분이 무엇을, 왜 하고 있는지 (목록을 만들어) 공개하세요.
  33. 얼굴을 많이 마주칠수록 팀워크가 단단해집니다.
  34. (새로운 실천방법 등의 도입보다는) 고쳐야 하는 것만 고치세요.
  35. 파괴적인 '우수한 업무처리기법'은 진정한 의미의 업무처리기법이라 할 수 없습니다.
  36. (새로운 실천방법의 도입은) 밑에서부터 혁신해야 합니다.
  37. (새로운 실천방법은) 말만하지 말고 보여주세요.
  38. (새로운 실천방법 도입에) 관리층의 지지를 이끌어내세요.
  39. (현재 발견된) 버그가 있는 곳을 테스트하세요.
  40. 목록은 살아있는 문서입니다. 변화가 목록의 생명입니다.
  41. (관리자로서) 목록이 없다면, 그것은 프로젝트의 일부가 아닙니다.
  42. (고객은) 항상 피드백을 빨리 해주세요.

위에서 괄호와 강조 표시는 내가 추가했다.

개발자도 아니고 관리자도 아닌 어정쩡한 위치라고 생각했던 기술 리더를 모든 개발자는 적어도 한번쯤 되기를 꿈꿔야한다고까지 이야기하는 것이 새로웠다. 기술 리더는 시간을 쪼개 기술 업무와 관리 업무를 한다고는 하지만, 책에서 다룬 아래와 같은 기술 리더의 체크리스트를 보면 개발자라기보다는 관리자에 가깝다는 생각이 들었다.

기술리더로서 여러분은 다음 질문에 긍정적인 대답을 내놓을 수 있어야 합니다.

  • 팀 구성원 각자가 무슨 일을 하고 있는지 알고 있습니까?
  • 5분 이내에 프로젝트의 현 상황에 대한 개요를 작성해낼 수 있습니까?
  • 다음에 추가해야 할 기능이 무엇인지 5개 내지 10개 정도를 댈 수 있습니까?
  • 우선순위가 가장 높은 결함을 서슴없이 열거할 수 있습니까?
  • 팀 구성원을 위해 여러분이 해결한 가장 최근의 문제는 무엇이었습니까?
  • 해결해야 할 중요한 이슈가 있을 때 팀 구성원이 여러분을 찾아옵니까?

기술리더가 비효율적이거나 과중한 업무를 맡고 있다는 신호입니다.

  • 팀 구성원 각자가 업무 방향에 대해 큰 그림을 갖고 있지 않습니다.
  • 기술 리더가 나타나면 일이 중단됩니다.
  • 팀의 성과를 가로챕니다.
  • 문제를 해결하는 데 실패합니다. 더 심한 경우에는 문제를 일으킵니다.
  • 업무 일정을 부정확하게 예측합니다.
  • 팀 구성원이 어떤 기술에 능숙한지 또는 팀 구성원이 배우길 원하는 기술이 무엇인지 알지 못합니다.
  • 팀 구성원 간의 충돌을 감지하지 못합니다.


성공적인 소프트웨어 개발 프로젝트를 위한 실용 가이드

저자
자레드 리차드슨, 윌 그월트니 주니어 지음
출판사
위키북스 | 2007-08-09 출간
카테고리
컴퓨터/IT
책소개
소프트웨어 개발에 관한 내용을 담은 가이드북. 이 책은 소프트웨...
가격비교


+ Recent posts