Ruby 2.1入門のまとめ

こちらruby説明が良かったですが読み辛いのでまとめてみた。

若手エンジニア／初心者のためのRuby 2.1入門：
http://www.atmarkit.co.jp/ait/kw/ruby_nyumon.html

他入門に参照になるもの：
Ruby 2.1 / Rails4.1 の意外に忘れられている便利なメソッド：
http://ruby-rails.hatenadiary.com/entry/20150101/1420049679
Ruby基礎文法最速マスター：
http://route477.net/d/?date=20100125


## 2.Ruby 2.1の基本構文／基本文法
### 定数
大文字から始まれば「定数だ」と認識される

```ruby
QUEEN = 42
#or 
#Queen = 12
```

freezeを入れることでjavaのfinal的役割をする認識は間違い。
なので
Stringなど定数はfreezeをつけるべきだが
int定数はfreezeしなくでもいい
冗長になりがち

```ruby
TEAPOT = "tea".freeze
#TEAPOT = "coffee"は警告があるだけで変更ができてしまう。
#TEAPOT.capitalize!のようなことができないようにするだけだ。
```

### ifも戻り値がある

```ruby
teapot = if ARGV[0].to_i == 42
  "tea"
else
  "coffee"
end
puts teapot
```

### case 
最後のelseで他の場合に実行するが、javaのdefaultに似ている

```ruby
case ARGV[0].to_i
when 0
  puts "zero"
when 1
  puts "one"
when 2, 3
  puts "two or three"
else
  puts "other"
end
```

###コメント

```ruby
# コメント
=begin
こちらもコメント
=end
```

## 3.Rubyの配列、ハッシュテーブル
Array

```ruby
#オブジェクト作成
array = []
array = Array.new

#追加,push,<<
array.push(1)
array << 2
array << "3"

#逆参照
array[-1]

#範囲指定
array[1..2]
# => [2,"3"]

#削除
array.delete(1) #指定した値を検索して削除
array.delete_at(0)  #指定した位置の要素を削除
array.clear #全部削除

#pop,push,shift,rotate省略

#arrayを逆順にする
array.reverse #swift言語のreverse()と同じ
array.reverse! #自身も変更

#sort,sort_by,できれば高速なsort_byを使おう
array.sort_by

#「宇宙船演算子」
1 <=> 2
# -1など

#配列をランダムに
array.shuffle

#ランダムに二つの要素を取り出す
array.samle(2)

#要素を検索して位置を返す
array.index(3)
array.rindex(3) #後ろから数得る

#重複要素取り除く
array.uniq # or array.uniq!

#nilを取り除く
array.compact #or compact!

#二つの配列を結合
#push,<<はそのまま結合されてしまうが、こっちがほうがarrayのflat化できる->平滑化
array1.concat(array2)

#zip省略

#map あとで説明

```
上記 !が付いたメソッドを「破壊的メソッド」と呼ぶ


Hash

```ruby
#初期化
hash = {}
hash = Hash.new

#hashオブジェクト作成
hash = {"jack" => 11, "queen" => 12, :king => 13}
#シンタックスシュガー」（糖衣構文、プログラミング言語において、読み書きのしやすさのために導入される構文）
#これで =>が省略できる
hash = {jack: 11, queen: 12, king: 13}

#アクセス
hash["queen"]
hash[:king]

#キー、値一覧
hash.keys
hash.values

#追加
hash[:ace] = 1
hash["child"] = 12

#削除
hash.delete["jack"]

#clear
hash.clear

#hashを配列に
hash.to_a #[[:jack, 11], [:queen, 12], [:king, 13]]

```

## 4.RubyのRangeクラスと範囲オブジェクト、範囲演算子、イテレーター
Array

```ruby
puts ".."
# 5を含む、すなわち<= 5
for i in 1..5
  p i
end
puts "..."
# 5を含まない、すなわち < 5
for i in 1...5
  p i
end
```

Range

```ruby
Range.new(1, 3) #=> 1..3
```

文字範囲

```ruby
# a, b, c, d
puts "alphabets"
for alphabet in "a".."d"
  puts alphabet
end
# $, %, &
puts "symbols"
for symbol in "$".."&"
  puts symbol
end
# 0, 1, 2, 3
puts "numbers"
for number in "0".."3"
  puts number
end
# あ, ぃ, い, ぅ, う
puts "hiragana"
for hiragana in "あ".."う"
  puts hiragana
end
```

出力結果が面白！！！

```
alphabets
a
b
c
d
symbols
$
%
&
numbers
0 
1
2
3
hiragana
あ
ぃ
い
ぅ
う
```


```ruby
for string in "aa".."cc"
  puts string
end
```


```
$ ruby range_04.rb
aa
ab
ac
: （中略）
az
ba
bb
bc
: （中略）
bz
ca
cb
cc
```

検索

```ruby
(0..5).include?(5) #true

#cover省略
```

要素

```ruby
(1...5).first #1
(1...5).first(2) # [1,2]

#lastは同じ
#他step,n個おきに処理
(0..10).step(3) {|i| puts i}
```

loop

```ruby
#配列
["alice", "in", "wonderland"].each do |term|
  puts term
end

# index付き
["alice", "in", "wonderland"].each_with_index do |term, index|
  puts "#{index}: #{term}"
end

#逆
["alice", "in", "wonderland"].reverse_each do |term|
  puts term
end


# Hash
{jack: 11, queen: 12, king: 13}.each do |key, value|
  puts "key: #{key}, value: #{value}"
end
```


##5.RubyのString／Regexpクラスによる強力な文字列操作／正規表現

```ruby
teapot = "tea"
#先頭文字だけ大文字に,他は小文字
teapot.capitalize #=> "Tea"

#大文字,小文字
teapot.upcase
teapot.downcase

#大文字・小文字を入れ替え
teapot.capitalize.swapcase
#=> "tEA"

#String#strip／#lstrip／#rstripで空白文字の除去
[1] pry(main)> teapot = "   tea   "
=> "   tea   "
[2] pry(main)> teapot.strip
=> "tea"
[3] pry(main)> teapot.lstrip
=> "tea   "
[4] pry(main)> teapot.rstrip
=> "   tea"

#each_char,一文字ずつしょる
#each_line, 一行ずつ処理

#分解して配列にする
"Alice".chars
#行ごと分解して配列にする
"Alice found\na bottle".lines


#結合
#+,効率悪い
str = "111" + "headers"
#代わりに効率の良いconcat,<<効率良い

teapot.concat("coffee")
teapot << "juice"

#insert挿入省略

#reverse逆転省略

#正規表現省略

```

##6.RubyのNumericとTimeで数値と時間をさまざまな操作・演算・判定
[省略]

##7. Rubyのオブジェクト指向におけるクラスとモジュール、継承、Mixin、アクセス制御の使い方

コンストラクター、インスタンス変数、キーワード引数

```ruby
class Rabbit
  attr_accessor :name #外からread,write可能
  attr_reader :color, :length_of_ears #外からreadだけ
 
  #コンストラクター
  #name:などはキーワード引数である、デフォルト値を設定しているので、引数を省略できます。
  #また引数の順番に関係ない
  def initialize(name: "usachan", color: :white, length_of_ears: 10)
    @name = name
    @color = color
    @length_of_ears = length_of_ears
  end
 
  def jump
    puts "pyon! pyon!"
  end
 
  def pound_steamed_rice_into_rice_cake
    puts "pettan! pettan!"
  end
  
  def say_name
    puts "Hello, I'm #{@name}!"
  end

  def print_ears
    puts "∩_∩"
  end

  #クラスObjectクラスを継承していますのでそのto_sをoverrideすることも可能
  def to_s
    "名前: #{@name}, 毛の色: #{@color}, 耳の長さ: #{@length_of_ears}"
  end
end
```

継承,override


```ruby
class LopEar < Rabbit
  def print_ears #メソッドをうわ書きしている
    puts "∪￣∪"
  end
end
```

アクセス制御
public: どこからでもアクセス可能
protected: クラス内、同一パッケージ、サブクラスからアクセス可
private: クラス内のみアクセス可能

private破れることが簡単

```ruby
A.new.send(:private_method)
```


### Comparable　moduleによるオブジェクト比較
Comparableモジュールは、ComparableモジュールをMixinするクラスに「<=>」メソッドが定義されていることを期待しています。

```ruby
class Rabbit
  include Comparable
  def <=>(other)
    @length_of_ears <=> other.length_of_ears
  end
end
```

継承とMixin(module)の使い分け――is-a関係とhas-a関係
is-a:「ウサギやアヒルは動物である、ニンジンは野菜である」
has-a: 何らかの共通点

## 8.Rubyの面白さを理解するためのメソッド、ブロック、Proc、lambda、クロージャの基本

### メソッドにdefault値を入れることができる

```ruby
def parrot(word="yack-yack")
  puts word
end
```

### かっこが省略できる、ただ推奨しない

```ruby
def parrot2 word
  puts word
end

parrot2 "oink"
```

### メソッドはreturnを書かないのが基本

```ruby
def sum(x, y)
  x + y
end
```

### 可変長引数は[*（アスタリスク,asterisk）」を

```ruby
def sum(*args)
  puts args.class
  args.inject(:+)
end
 
p sum(1, 2, 3, 4, 5)
p sum(1)
p sum
```

### キーワード引数
引数は順番を守らなくでもいい

```ruby
def basic_form(a: "a", b: ["b", "b", "b"], c: :c)
  puts "a(#{a.class}): #{a}"
  puts "b(#{b.class}): #{b}"
  puts "c(#{c.class}): #{c}"
end
 
def complex_form(a, *b, c: "c", d:)
  puts "a(#{a.class}): #{a}"
  puts "b(#{b.class}): #{b}"
  puts "c(#{c.class}): #{c}"
  puts "d(#{d.class}): #{d}"
end
 
basic_form(a: "meow", b: "oink", c: :bowwow)
basic_form(a: "meow")
complex_form("oink", "bowwow", d: "meow", c: "quack")
complex_form
```

### block
{ puts "pyonpyon" }はブロック、yieldはそのブロックを実行するだけ

```ruby
def repeat(n)
  for i in 1..n
    puts "#{i} =>"
    yield
  end
end
repeat(3) { puts "pyonpyon" } 
```

```ruby
def sum_and_exec_block(x, y)
  z = x + y
  z = yield z if block_given?
  z
end
sum_and_exec_block(10, 20) do |value|
  value + 10
end
```
結果は50

### 分かりにくいが便利なProcとlambda（ラムダ）
どちらもブロックを実行するだが "&" 付きでそのブロックが取得できる
手続きそのものをオブジェクト化して引き回す

```ruby
def repeat2(n, &procedure)
  procedure.call
end
```

### クロージャ

例１：
do...endの間はクロージャになる

```ruby
prefix = "@"
["a", "b", "c"].each do |s|
  puts prefix + s
end
```

出力

```
$ ruby block06.rb
@a
@b
@c
```

例２：

```ruby
def increase
  n = 0
  -> { n += 5 }
end
 
3.times { p increase.call } #実行のたびにProcオブジェクトが生成されている
 
puts "=================="
 
increase_proc = increase
3.times { p increase_proc.call } #生成したProcオブジェクトを変数increase_procに代入し、3回callしています。
```

出力

```
$ ruby block06.rb
5
5
5
==================
5
10
15
```

##9.Rubyの例外とその捕捉――基本のbegin～rescue～endからensure、else、retry、後置rescueまで

基本的StandardErrorのエラーメインである
RuntimeException発生させる

```ruby
raise "something wrong"
```

カスタムerrorとNotImplementedError

```ruby
class UnacceptableRequidError < StandardError
  attr_reader :obj
 
  def initialize(obj)
    @obj = obj
  end
end
 
class Vessel
  def pour_out
    requid = @requid
    @requid = nil
    requid
  end
 
  def pour_in(requid)
    if requid.to_s == acceptance
      @requid = requid
    else
      raise UnacceptableRequidError.new(requid), "unacceptable"
    end
  end
 
  def acceptance
    raise NotImplementedError.new, "#acceptance is not implemented!"
  end
end
 
class Teapot < Vessel
  def initialize(requid)
    pour_in(requid)
  end
 
  def acceptance
    "tea"
  end
end
 
class Decanter < Vessel
  def initialize(requid)
    pour_in(requid)
  end
 
  def acceptance
    "wine"
  end
end
 
class Kettle < Vessel
  def initialize(requid)
    pour_in(requid)
  end
end
```


例外catch

```ruby
begin
  raise "something wrong"
rescue => e
  puts "An exception is occurd!"
  p e
  p $!
end
```


- 例外クラスを指定して捕捉する,javaと同じくerrorはできれば細く分割して処理する仕組みですね。
- まずカスタムrescueに引っかかりか
- どの例外クラスにも合致しない場合プログラムはその場で停止し、エラーメッセージが出力されますので最終的に処理するrescue StandardError => e (rescue => eと同じ)でcatchする
- 例外の有無にかかわらず処理する「ensure」と例外が発生しなかった場合の「else」
- ensureはjavaのfinallyに似ている。



```ruby
require_relative "exception01"
 
begin
  teapot = Teapot.new("coffee")
  puts teapot.pour_out
rescue UnacceptableRequidError => e
  puts "Rescued in 'UnacceptableRequiedError => e'"
  p e
  p e.obj
rescue NoMethodError, ZeroDivisionError => e
  puts "Rescued in 'rescue NoMethodError, ZeroDivisionError => e'"
  p e

# 上記catchできない場合はこっちで全部catch
rescue StandardError => e # rescue => e でもOK
  puts "Rescued in 'rescue StandardError => e'"
  p e
else
  puts "There are no errors."
ensure
  puts "Ensure"
end
```

###例外が発生してもリトライする「retry」
「省略」

###後置rescue
minimumに使えそう

```ruby
Teapot.new("coffee") rescue nil
```

##10.RubyのFile／IOクラスで入力と出力、ファイルの読み取りと書き込み、フィルター作成

putsで標準出力で流したものをrabbit.txtにファイル書き込む

```
$ ruby -e "puts 'pyon'" > rabbit.txt
$ cat rabbit.txt
```

書式付き出力を行うメソッド「printf」


```
print "fsdaf" 
puts "fsadfasff"　#printより改行が後ろに付く

[4] pry(main)> printf("%.2f", 3.14159)
3.14=> nil
[5] pry(main)> printf("%#b", 42)
0b101010=> nil
[6] pry(main)> printf("%+d %d", 42, 42)
+42 42=> nil
```


キーボードから入力された文字列を得るメソッド「gets」

```ruby:io01.rb
print "please input a string here > "
p gets
#p gets.chompにすると改行をなくしてくれるので嬉しい
```
結果

```
$ ruby io01.rb 
please input a string here > Alice↵
"Alice\n"
```

テキストファイルを標準入力として使った場合のgetsの動作
[略]


###ファイル読み込む
```ruby
file = File.open("wonderland.txt", "r")
 
file.each do |line|
  puts "** #{line.chomp} **"
end
 
file.close
```

もしくはopenはブロックを引数として使えるので下記の方法もできる
この場合**プログラマーは明示的に「close」メソッドを呼ぶなどの作業をしなくてもよくなります。**

```ruby
File.open("wonderland.txt", "r") do |file|
  file.each do |line|
    puts "** #{line.chomp} **"
  end
end
```

###Fileクラスを使ってファイルに書き込む

```ruby
File.open("teapot.txt", "w") do |file|
  file.print("darjeeling tea\n")
  file.puts("assam tea")
  file.printf("%s\n", "ceylon tea")
end
```

###他STDOUT,STDIN
[省略]

##11.RubyのThread、Fiber、Kernel、forkで並列処理やプロセスの深淵
[省略]

##12.Rubyのメタプログラミング、self、特異クラス／メソッド、オープンクラスとモンキーパッチ 
[省略]

実行時までわからないdefine_method

```ruby
method_name = ARGV[0]
 
define_method method_name do
  puts "This method is named #{method_name}."
end
 
alice
```

###オブジェクト固有のメソッド「特異メソッド」

```ruby
array = []
 
def array.append_randomized_number
  self << rand(10)
end
 
p array.respond_to?(:append_randomized_number)
p Array.new.respond_to?(:append_randomized_number)
 
10.times { array.append_rondomized_number }
p array
```

```
$ ruby meta_programming_05.rb                                                                                                                     
true
false
[1, 6, 7, 6, 4, 9, 7, 7, 1, 3]
```

###クラスメソッドと「特異クラス」

```ruby
class Rabbit; end
 
def Rabbit.colors
  [:black, :brown, :white, :mixed]
end
 
p Rabbit.colors
```
上記、実際はよく使う下記と同じことをやっています
下記のやり方が良いと思います。

```ruby
class Rabbit
  def self.colors
    [:black, :brown, :white, :mixed]
  end
end
 
p Rabbit.colors
```
また、同じく下記のような下記書き方もできるますよね

```ruby
class Rabbit
  class << self
    def colors
      [:black, :brown, :white, :mixed]
    end
  end
end
```


オープンクラスとモンキーパッチ
+ *を再定義しているが何が特別なのか？

```ruby
class Fixnum
  def +(v)
    self - v
  end
  def *(v)
    self / v
  end
end
puts 42 + 42
puts 42 * 42
```

```ruby
$ ruby pattern_01.rb 
0 
1
```


###ruby で動的にクラスを作る

```ruby
self.class.const_set :'Creature', Class.new
=> Creature
Creature
=> Creature

```
以下と同じ

```ruby
class Creature
end

```

もう1つの例：Hashをloopして動的にクラスを作成するとともにdefine_methodでmethodを追加する

```ruby
{Cat: "meow", Dog: "woof", Owl: "hoot-hoot", Rabbit: "boo"}.each do |animal, roar|
  Object.const_set animal, Class.new
 
  Object.const_get(animal).class_eval do
    define_method :speak do |count|
      count.times { puts roar }
    end
  end
end
 
Cat.new.speak(2)
Dog.new.speak(2)
Owl.new.speak(2)
Rabbit.new.speak(2)
```

###他メタプログラミング
「send」メソッド
「eval」メソッド
「instance_eval」メソッド
「method_missing」メソッド
「alias_method」メソッド
遅延評価のための「Proc」オブジェクト

##13.Rubyで逆ポーランド変換機を作りgem作成＆コマンドの使い方
省略