YAML 사용하기

Reference

YAML은 XML에 비해 눈으로 데이터 확인이 용이하며, 해당 데이터를 쉽게 직렬화할 수 있다.

다음은 YAML의 hello program이다.

-
  name: Tom
  age: 32
-
  name: Dick
  age: 19  
EOS

config = YAML.load(yaml_string)    # from yaml_string

puts config[0]['age']  # 32
puts config[1]['name'] # Dick

YAML을 구성하기 위해서는 Array 로 할것인가, Hash로 할것인가로 결정해주면 된다. 물론 중첩도 가능하다.

arry = <<EOS
- [Tom, 32] # Array
- [Dick, 19] # Array
EOS

hash = <<EOS
{ name: Tom, age:32 } # Hash
EOS

다음은 기본적인 사용법을 정리한 hello_yaml.rb 이다.

# 필요한 파일
require 'yaml'

# 변환
str = "Hello, Yaml!"
puts str.to_yaml # y(str)


arr = ["one", "two", "three"]
puts arr.to_yaml # y(arr)

# 파일 저장
fileName = File.open('counting.yml', 'w')
    YAML.dump(arr, fileName)
fileName.close

# 파일 읽기
fileName = File.open('counting.yml', "r")
    newArr = YAML.load(fileName) # to array
fileName.close

puts newArr.to_yaml # y(newArr)

'Ruby' 카테고리의 다른 글

Koan - Methods  (0) 2014.03.01
Koan - Regular Expressions  (0) 2014.02.28
Koans - Symbols  (0) 2014.02.27
Ruby에서의 TDD  (0) 2014.02.22
Windows 환경에서 Shotgun이 실행되지 않을때  (0) 2014.02.21

2.2 헤더 파일 만들기

헤더 파일에 포함되는 내용은 다음과 같다

  • 외부에 공개할 매크로의 정의(함수형 매크로)
  • 외부에 공개할 상수의 정의(#define, enum 등의 정의)
  • 외부에 공개할 구조체, 공용체의 정의
  • 외부에 공개할 자료형의 정의 (typedef를 이용한 자료형의 정의)
  • 외부에 공개할 함수의 원형 선언
  • 외부에 공개할 전역 변수의 extern 선언
  • 이 라이브러리를 이용할 때 필요한 다른 헤더 파일의 인클루드문(예를 들어 함수의 인자나 반환값으로 FILE *형을 이용한다면 stdio.h를 인클루드해야 한다.)
2.2.1 매크로 정의

보통 매크로 함수는 일반적인 함수와 구분해주기 위해 이름을 모두 대문자로 기술하는 것이 관례이다. 꼭 외부에 공개할 필요가 있는 매크로만을 헤더 파일에 기술한다.

매크로가 중복 정의된 경우 gcc는 다음과 같이 처리한다.

  • 두 정의가 같은 내용인 경우, 에러를 발생하지 않고 통과한다.
  • 두 정의가 서로 다른 경우, 컴파일 시에 “redefined”를 알리는 경고가 발생하고, 나중에 정의된 값을 취한다.

매크로 이름의 충돌을 확실히 방지하고 싶다면 아래와 같이 경고를 발생시키는 편이 낫다.

#ifndef MAX
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#else
#warning Duplicated definition of MAX
#endif
2.2.2 상수 정의
2.2.3 구조체, 공용체 정의

헤더 파일에서 구조체를 정의하는 경우, “이 구조체는 라이브러리의 사용자가 멤버 변수를 자유롭게 조작해도 무방하다.”는 의사를 암시적으로 포함하는 셈이 되므로 이에 유의해야 한다.

2.2.4 자료형 정의
2.2.5 함수의 원형 선언

함수 원형은 반드시 명시적으로 선언하고, 컴파일시에 -Wall 옵션을 주어 관련 경고를 모두 출력하도록 하자.

2.2.6 전역 변수의 extern 선언
2.2.7 다른 라이브러리 헤더 파일의 인클루드

원칙적으로는, 라이브러리를 컴파일할 때에만 필요한 경우라면, .c에, 라이브러리를 이용할 때 필요한 경우라면 .h에 인클루드하는 것으로 정해두면 된다.

2.2.8 다중 인클루드 문제

인클루드의 중첩은 다중 인클루드를 유발한다. 다중 인클루드가 발생하면 같은 단어에 대해 #define의 정의나 typedef의 정의가 여러 번 등장하게 된다.

#define의 재정의
  • 같은 단어에 대해 같은 정의를 내리는 경우, 오류나 경고로 처리하지 않는다.
  • 같은 단어에 대해 다른 정의를 내리는 경우, 경고를 출력하고, 나중에 정의된 뜻을 따른다.
typedef의 재정의
  • 같은 자료형에 대해 중복된 정의를 내리면 무조건 에러로 처리한다.

이러한 문제들을 회피하기 위해, #ifndef#endif로 묶어서 같은 헤더 파일 본문이 여러 번 반복되지 않도록 해둔다.

#ifndef    _STRING_H_INCLUDED_
#define    _STRING_H_INCLUDED_
/* header file 본문 */
#endif

'C' 카테고리의 다른 글

Unity를 이용한 TDD - 2  (0) 2014.04.13
volatile  (0) 2014.04.09
Unity를 이용한 TDD  (0) 2014.04.02
[도서] 쉽게 배우는 C프로그래밍 테크닉 - 1.4 헤더 파일 만들기  (0) 2014.03.04
gdb 사용법  (0) 2014.03.03
1.4.7 const 활용

포인터를 const로 정의하면, 그 포인터가 가리키는 값을 변경할 수 없다.

int test(void)
{
    char s[] = "test";
    const char * p = s;
    p[0] = 'T';    /* const 포인터가 가리키는 주소의 값을 변경하려고 시도    */

    return 0;
}
1.4.8 const를 인자로 활용
void strcopy(char * dst, const char * src)
{
    while (*src != '\0')
        *(dst++) = *(src++);
    *dst = '\0';
}
  • const char *로 정의한 포인터가 가리키는 값은 변경할 수 없다. (경고)
  • const char * 포인터를 char *로 형변환 하는 것은 허용되지 않는다. (경고)

const를 반환하는 함수의 활용 예

typedef enum { Black, White, Blue, Red, Green } Color;

const char * ColorName(Color c)
{
    const char * s;
    switch(c)
    {
        case Black: s = "Black" break;
        case White: s = "White" break;
        case Blue : s = "Blue"  break;
        case Red  : s = "Red"   break;
        case Green: s = "Green" break;
        default   : s = "Unknown";
    }

    return s;
}
1.4.9 const를 사용할 때 주의사항

const로 선언할 수 있는 것은 모두 const로 선언하는 것이 좋을 것처럼 여겨진다. 하지만 실제로는 그렇지 않다. 특히 함수가 깊게 중첩되는 경우에는 const를 사용하지 않는 것이 좋다.

'C' 카테고리의 다른 글

Unity를 이용한 TDD - 2  (0) 2014.04.13
volatile  (0) 2014.04.09
Unity를 이용한 TDD  (0) 2014.04.02
[도서] 쉽게 배우는 C프로그래밍 테크닉 - 2.2 헤더 파일 만들기  (0) 2014.03.04
gdb 사용법  (0) 2014.03.03

+ Recent posts