Ruby めも


# クラスの継承

```sample.rb
>> class Word
>>   def palindrome?(string)
>>     string == string.reverse
>>   end
>> end

>> w = Word.new              # Wordオブジェクトを作成する
=> #<Word:0x22d0b20>
>> w.palindrome?("foobar")
=> false
>> w.palindrome?("level")
=> true

```
文字列を引数に取るメソッドを作るためだけに、わざわざ新しいクラスを作るのは変です。
単語は文字列なので、Wordクラスは Stringクラスを継承するのが自然です。

```sample.rb
>> class Word < String             # WordクラスはStringクラスを継承する。
>>   # 文字列が鏡文字であればtrueを返す。
>>   def palindrome?
>>     self == self.reverse        # selfは文字列自身を表す。
>>   end
>> end
=> nil

>> s = Word.new("level")    # 新しいWordを作成し、"level" で初期化する
=> "level"
>> s.palindrome?            # Wordが鏡文字かどうかmethod.
=> true
>> s.length                 # Wordがstringのすべてのメソッドも継承している
=> 5

```
組込みクラスの拡張

```sample.rb
>> class String
>>   # 文字列が回文であればtrueを返す
>>   def palindrome?
>>     self == self.reverse
>>   end
>> end
=> nil
>> "deified".palindrome?
=> true
```
# リファクタリング
## メソッド一覧を表示する
```
user.methods
user.methods.sort
user.methods.grep(/create/)
```

![image](https://qiita-image-store.s3.amazonaws.com/0/33237/60d047c1-7c55-ec0c-c8c7-5a6eec6837fa.png)

# 制御構造
## unlessの使い方
```rb

string = "foobar"
puts "The string '#{string}' is nonempty." unless string.empty?
```


## 条件演算子
```rb
n = 2
printf "I have %d kid%s.\n", n, (n == 1) ? "" : "s"
=> I have 2 kids.

n = 1
printf "I have %d kid%s.\n", n, (n == 1) ? "" : "s"
=> I have 1 kid.
```
## for
```rb
for i in [1,2,3]
 print i, "\n"
end
=> 1
=> 2
=> 3
```
## return
複数の戻り値を返す

```rb
def multi(n)
 return n, n*2, n*4
end
v1, v2, v3 = multi(3)
=> [3, 6, 12]

```
# 文字
## メタ文字
![image](https://qiita-image-store.s3.amazonaws.com/0/33237/ab4578f4-6bb3-b8a5-03e0-81fc97175ca6.png)

# イテレータ

```
IO.foreach("/etc/passwd") do |line|
　# /etc/passwdのうち Kerberosを含む行を出力
  print line if line =~ /Kerberos/
end
```
gsubは引数として渡した正規表現にマッチした部分を、指定した文字列を置換するメソッドですが、文字列を指定せず、ブロックを渡すとマッチした部分をブロックを評価した値で置き換えます

```rb

str = "This is a test.\n"

print str.gsub(/[A-Za-z]/, "foo")
#=> foo foo foo foo.

print str.gsub(/[A-Za-z]+/)
#=> #<Enumerator:0x007f829b9a83a8>

print str.gsub(/[A-Za-z]+/) { |match|
        "<" + match + ">"
}
#=> <This> <is> <a> <test>.
```
## イテレータのつくりかた
* yieldをよぶ
* 手続きオブジェクトを生成する
* ブロック引数でブロックを手続きオブジェクトとして受け取る

### yield
[参考URL]
[Ruby の yield って結局なんなの？](http://d.hatena.ne.jp/yoshidaa/20090511/1241967137)

```rb
# ブロックを何度でも呼び出せる
def callBlock
  yield
  yield
end

callBlock{puts "In the block"}

#=>In the block
#=>In the block

# 複数の値を引数を受け取れる
def callBlock2
  yield "hello", 2
end

callBlock2{|str, num| p "#{str}!! #{num}"}
#=> "hello!! 2"
```

```rb
# hashをキーでソートして受け取るブロックを実行する
def each_sort_by_key(hash)
  hash.keys.sort.each do |x|
    yield x, hash[x]
  end
end

hash ={3=>2, 2=>4}
each_sort_by_key(hash) {|key, val|
  print "hash[", key, "]=", val, "\n"
}
#=> hash[2]=4
#=> hash[3]=2
```

```
# 入れ子になった配列の要素をすべて取り除く
def flatten(array)
  for item in array
    if item.kind_of?(Array)
      flatten(item){|x| yield x}
    else
      yield item
    end
  end
end

flatten([0,[1,2]]){|x| p x}
#=> 0
#=> 1
#=> 2
```
## Procオブジェクトと　& と　call
call は Procオブジェクトを呼び出し
&　は　Procオブジェクトをブロックに変換する

```rb
@count = 0
proc = Proc.new do 
  puts "proc do !! count = #{@count += 1}"
end
 

3.times do
  proc.call
end
 
# 上と同じ処理をしている

3.times(&proc)

[実行結果]
proc do !! count = 1
proc do !! count = 2
proc do !! count = 3
proc do !! count = 4
proc do !! count = 5
proc do !! count = 6
```
他の例

```rb
(byebug) pp @today_tasks
[#<Task id: 1, name: "Buy some droids", due_at: "2015-05-10 11:50:00", created_at: "2015-05-10 05:48:24", updated_at: "2015-05-10 05:48:24">, #<Task id: 2, name: "Meet Obi-Wan", due_at: "2015-05-10 14:20:00", created_at: "2015-05-10 05:48:24", updated_at: "2015-05-10 05:48:24">]

(byebug) pp @today_tasks.map(&:due_at)
[Sun, 10 May 2015 11:50:00 UTC +00:00, Sun, 10 May 2015 14:20:00 UTC +00:00]

```

# リフレクション
## inspectオブジェクトidとインスタンス変数をダンプ出力する
```rb
class Song
  def initialize(name, artist, duration)
    @name = name
    @artist = artist
    @duration = duration
  end
end

aSong = Song.new("Bicylops", "Fleck", 260)
#=> "#<Song:0x007f9f74936460 @name=\"Bicylops\", @artist=\"Fleck\", @duration=260>"
```
## オブジェクトの中身を見やすくカスタマイズする
```rb

class Song
  def to_s
    "Song: #{@name}-#{@artist} (#{@duration})"
  end
end

aSong.to_s
#=> "Song: Bicylops-Fleck (260)"
```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```

```