# Chapter6. 표준 타입

## 6.1 숫자

* 루비는 정수, 부동소수점, 유리수, 복소수 등을 지원한다.
* 정수의 길이는 정해지지 않는다.
  * 최대 길이는 사용하는 시스템의 메모리 크기에 의해 결정된다.
  * 특정 범위의 정수는 `Fixnum` 객체로, 매우 큰 정수는 `Bignum` 객체로 저장된다.
  * 값의 변화에 따라 수시로 변경된다.

### 숫자는 어떻게 상호 작용하는가?

* 두 숫자가 서로 다른 클래스라면 좀 더 일반적인 클래스로 숫자가 변환된다.

```ruby
1 + 2 # => 3
1 + 2.0 # => 3.0
1.0 + Complex(1,2) # => (2.0 + 2i)
```

### 숫자를  사용한 반복

* 정수는 몇 가지 유용한 반복자를 지원한다.

```ruby
3.times { print "haha "}
1.upto(5) { ~~ }
99.downto(50) { ~~ }
50.step(80, 5) { ~~ }
```

* 다른 반복자들과 마찬가지로 블록을 넘기지 않으면 `Enumerator` 객체를 반환한다.

## 6.2 문자열

* 루비 문자열은 문자열의 시퀀스다. 보통 출력 가능한 문자를 저장하지만, 반드시 그래야만 하는 것은 아니다.
* 문자열에는 이진(binary) 데이터를 저장할 수 있다.
* 문자열은 `String` 클래스의 객체다. 문자열은 주로 문자열 리터럴을 통해 생성된다.
* 문자열 리터럴은 구분 문자(`delemiter`) 사이에 문자 시퀀스를 쓰는 것이다.
  * 이진데이터는 다른 문자처럼 프로그램의 소스 안에 표현하기가 어렵기 때문에 문자열 리터럴에는 이스케이프 시퀀스를 함께 사용할 수 있도록 했다.
  * 문자열 리터럴 각각은 프로그램이 컴파일 될 때 해당 이진 값으로 변환된다.
* 작은 따옴표와 큰 따옴표 둘 다 사용할 수 있지만, 큰 따옴표가 지원하는 기능이 더 많다.
* 따옴표가 아닌 `%q/문자열/`, `%Q!문자열!`, `Q{문자열}` 등의 스트링 리터럴로도 문자열을 만들 수 있다.
* 또한 `here` 도큐먼트로도 만들 수 있다.
  * `<<~END_OF_STRING`으로 시작해서 `END_OF_STRING`로 끝내면 된다

```ruby
class Test
  attr_accessor :str
  def initialize(a)
    @str = <<~END_OF_STRING
      Input value: #{a}
    END_OF_STRING
  end
end

a = Test.new(123)
puts a.str

s2 = <<~END_OF_STRING
The Body of string is here!!!
  END_OF_STRING
```

### 문자열 다루기

* `String` 클래스는 루비 전체 내장 클래스 중에서 가장 크다. 100개 이상의 표준 메서드가 정의되어 있다. 따라서 나중에 공부하도록 하자...

## 6.3 범위

* 범위는 주로 시퀀스, 조건, 간격을 구현하는데 사용된다.
  * 루비는 이 범위 부분에서도 막강한 기능을 자랑함.

### 범위로 시퀀스 표현하기

* 범위의 가장 자연스러운 사용법은 시퀀스를 표현하는 것이다.
* 시퀀스는 시작값, 종료값을 비롯해 차례로 값을 만들어 내는 방법으로 이루어진다.
* 루비에서 시퀀스는 `..` 과 `...` 범위 연산자를 이용해 만든다.
  * `..`: 양쪽 경계 모두 포함
  * `...`: `[)` - 왼쪽 포함, 오른쪽 경계 미포함
* 범위는 `to_a` 메서드를 사용해 배열로 변환하거나 `to_enum` 메서드를 사용해 `Enumerator` 객체로 변환할 수 있다.

```ruby
(1..10).to_a # => 배열
(1..5).to_enum # => Enumerator
```

* 지금까지 본 것은 우리가 루비의 내장 클래스였고, 우리가 직접 구현한 클래스에서 범위연산자를 사용하기 위해서는 어떻게 해야할까?
  * 이를 위해서는 객체가 ***순서대로 다음 객체*** 를 반환하는 `succ` 메서드를 구현해야하고
  * `<=>`를 이용해서 비교 가능해야 한다. (즉 `Comparable` 모듈을 `include` 해야함)

### 범위로 조건 표현하기

* 범위를 시퀀스로 사용하기도 하지만 조건절에 사용할 수도 있다.
* 아래의 예시는 표준입력으로 입력을 했을 때 `start`가 출력의 토글 스위치가 된다. `start`가 들어온 순간부터 입력이 에코잉됨

```ruby
while line = gets
  puts line if line =~ /start/ .. line =~ /end/
end
```

### 범위로 간격 표현하기

* 범위의 마지막 용도는 어떤 값이 범위에 포함되는지 따지는 인터벌 테스트다.
* 이를 위해 `case` 문에서 사용하는 동등 연산자 `===`를 이용한다.

```ruby
(1..10) === 5 # => true
(1..10) === 15 # => false
(1..10) === 3.141592 # => true
('a'..'z')  === 'c' # => true
```

* 간격 테스트는 `case` 문에서 자주 사용된다.
  * `case`에서는 `...`를 사용하는 것이 좋다.

```ruby
case car_age
when 0...1
  puts "Mmm Its new!"
when 1...3
  puts "Mmm zz"
else
  puts "aaa"
end
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://simian114.gitbook.io/blog/undefined/ruby/1/chapter6..md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
