rubyコツコツメモ

## このメモについて

- 知らない関数がいろいろあるので、メモ的な内容です。時々追記する形で進めます。
- 全てirbで結果を確認できるくらいのボリュームです。

### true / false

rubyの世界では、nilとfalse以外は全てtrue。
0もtrueと判断される。

```
[36] pry(main)> puts "True" if true
True
=> nil

# 0でもtrue
[37] pry(main)> puts "True" if 0
True
=> nil
[38] pry(main)> puts "True" if 1
True
=> nil
[39] pry(main)> puts "True" if nil
=> nil
```

true / false はTrueClass / FalseClassに属している。

```
[42] pry(main)> true.class
=> TrueClass
[43] pry(main)> false.class
=> FalseClass
```

### nilについての注意

nilもNilClassに属する。
nilもNilClassのオブジェクトなので、Objectクラスのメソッドを利用することができる。

to_sやto_i, to_aで変換ができるが、変換した値はnil (false) の値にはならないので注意。

```
[44] pry(main)> nil.class
=> NilClass

[45] pry(main)> nil.class.to_s
=> "NilClass"
[46] pry(main)> nil.to_s
=> ""
[47] pry(main)> nil.to_i
=> 0
[48] pry(main)> nil.to_f
=> 0.0
[49] pry(main)> nil.to_a
=> []
```

#### nilなオブジェクトかもしれないことに気をつける

rubyの型のシステムの構造上、わたされたオブジェクトがnilかもしれない可能性はつねにある。
関数を作ったり関数を利用する場合、引数がnilかどうか、nilだったらどう扱うのが良いかを考慮しておくこと。

nilの場合は “”(空文字) / 0に読み替えるので良ければ、nil.to_s, nil.to_i で型変換するとよい。

また、メソッドを呼び出すことを期待しているなら、respond_to? でチェックすること。

```
[51] pry(main)> nil.respond_to?("to_s")
=> true
[52] pry(main)> nil.respond_to?("class")
=> true
[53] pry(main)> nil.respond_to?("exists?")
=> false
[54] pry(main)> nil.respond_to?("keys")
=> false

```

### 文字の入力

よくある系。「入力された値を使って云々...」用。
行末の改行は取り除く必要がある。

こちらの記事が大変よくまとまっています、ありがとうございます。

- [Ruby 標準入力から複数行読み取りたい](http://nnnamani.hateblo.jp/entry/2016/08/14/150900) (「んなまにのメモ帳」さま)

```
irb(main):130:0> input_lines = gets
This is a pen.
=> "This is a pen.\n"

irb(main):131:0> input_lines.chomp!
=> "This is a pen."

irb(main):132:0> input_lines
=> "This is a pen."
```

複数行の場合。

```
# readlines を使う
# EOF (Ctrl-D) まで受け付ける
irb(main):138:0> $stdin.readlines
A
B
C
D
E
=> ["A\n", "B\n", "C\n", "D\n", "E\n"] # 各行で改行を抜かないといけない！

# 改行を取り除く
irb(main):139:0> lines = $stdin.readlines.map{ |l| l.chomp }
A
B
C
D
E
=> ["A", "B", "C", "D", "E"]

```



### 文字列 / 配列

- split, pop, shoft, push....

```
irb(main):061:0> s = "a 1 2 3 4 5 10 15"
=> "a 1 2 3 4 5 10 15"

# 配列に区切る
irb(main):070:0> record = s.split
=> ["a", "1", "2", "3", "4", "5", "10", "15"]

# shiftで最初を取り出す / 先頭と残りに分割
irb(main):089:0> (moji, suji) = [record.shift, record]
=> ["a", ["1", "2", "3", "4", "5", "10", "15"]]

irb(main):090:0> moji
=> "a"

irb(main):091:0> suji
=> ["1", "2", "3", "4", "5", "10", "15"]
```

### max, min

```
[51] pry(main)> ip = [192, 168, 0, 1]
=> [192, 168, 0, 1]
[52] pry(main)> ip.max
=> 192
[53] pry(main)> ip.min
=> 0
```

### map

- mapは要素の数だけ繰り返しブロックを実行し、ブロックの戻り値を集めた配列を作成して返す
- collectでも同じ
 
```
#  数値に変換
irb(main):114:0> suji.map {|n| n.to_i}
=> [1, 2, 3, 4, 5, 10, 15]

# collectでも同じ
irb(main):115:0> suji.collect {|n| n.to_i}
=> [1, 2, 3, 4, 5, 10, 15]

```
### map! / collect!

```
# 変更前 / stringの配列
irb(main):122:0> suji
=> ["1", "2", "3", "4", "5", "10", "15"]

# map! は元のブロックと置き換えてしまう
irb(main):123:0> suji.map! {|n| n.to_i}
=> [1, 2, 3, 4, 5, 10, 15]

# suji がintに変わっている
irb(main):124:0> suji
=> [1, 2, 3, 4, 5, 10, 15]
```

### count / scan

- 特定の文字の出現回数をチェック

```
[62] pry(main)> ip = [192, 168, 0, 1]
=> [192, 168, 0, 1]
[63] pry(main)> ip = ip.map {|i| i.to_s }.join('.')
=> "192.168.0.1"
[64] pry(main)> ip
=> "192.168.0.1"
[65] pry(main)> ip.count('.')
=> 3

```

### inject

配列のブロックから取り出して操作。

```
# 配列の要素がstringの場合
irb(main):127:0> suji  = ["1", "2", "3", "4", "5", "10", "15"]
=> ["1", "2", "3", "4", "5", "10", "15"]

# injectでの連結の結果は「文字列」（文字の結合）
irb(main):128:0> suji.inject(:+)
=> "123451015"

# to_i してからinjectだと合計
irb(main):129:0> suji.map {|n| n.to_i}.inject(:+)
=> 40

```

もちろん、加算だけではなくて他にも色々。

```
# 掛け算
irb(main):097:0> suji.map {|n| n.to_i}.inject(:*)
=> 18000

irb(main):107:0> kazu = ["one", "two", "three", "four", "five"]
=> ["one", "two", "three", "four", "five"]

# 初期値をmax = 0として配列を比較、長さが大きいものを取り出す
irb(main):108:0> kazu.inject(0) { |max, s| s.length > max ? s.length : max }
=> 5

# フィボナッチ数列
irb(main):113:0> (0..5).inject([1, 1]) { |fib, i| fib << fib[i] + fib[i+1] }
=> [1, 1, 2, 3, 5, 8, 13, 21]

```

## print / puts 基本のキ

printとputsはどちらも端末に文字を表示するけれど、改行ないかあるかの違いがあるので注意。

```
# printは改行なし
[14] pry(main)> print "hoge"
hoge=> nil

# putsはあり
[15] pry(main)> puts "hoge"
hoge
=> nil
```

putsの場合、カンマ区切りで複数で引数が渡っていたら、それぞれ改行されて出力される。

```
[27] pry(main)> puts "a" "b" "c"
abc
=> nil
[28] pry(main)> puts "a","b","c"
a
b
c
=> nil

# printの場合は複数の引数が渡されていても、連結されてしまう
[29] pry(main)> print "a","b","c"
abc=> nil
```

## 実行オプション

```
$ ruby -h
Usage: ruby [switches] [--] [programfile] [arguments]
  -c      　　　　　構文チェックだけ実施（実行しない）        
  -Cdirectory     ワーキングディレクトリを指定 (ruby test/hoo.rb と ruby -C test hoo.rb は一緒）
```

## 学習サイト：

- [dotinstall](http://dotinstall.com)
 - 手を動かせない場合（通勤で立っているようなシーン）では、流しっぱなしで学習がありがたいです
 - とにかくコースの数が多いです！
- [ミニツク](http://www.minituku.net)
 - 実際に手を動かすためのチェック形式でのドリルがあるのが良いです
 - 演習もあります
- [Progate](http://prog-8.com/)
 - スライドが綺麗、図解も分かりやすい！サイトの作りもみているだけで勉強になります
 - オンラインで手を動かして問題を解くことができるのが良いです！
 - 中級、上級コースは有料になります
- [paiza](https://paiza.jp/challenges/info) / スキルチェックの問題を解く
 - 意外と問題を解く前に入力文字列をパースするところで「あれ？どうするんだっけ...」と考えたり...