Rubyメモ

# 一般

```ruby
include モジュール名  # Mix-in(モジュール内のメソッドや定数を、現在の名前空間に取り込む)
require ファイル名    # 引数のファイルを読み込む
```

# コメント

```ruby
# 一行コメント

=begin
複数行
コメント
=end
```

# 条件判断

- すべて、then は省略可能
- 値の部分には、正規表現や、クラス名なども使える

```ruby
if 条件 then
  # ...
elsif then
  # ...
else
  # ...
end

unless 条件 then
  # ...
else
  # ...
end

case 比較したいオブジェクト
when 値1 then
  文1
when 値2 then
  文2
else
  文3
end
```

# 修飾子

```ruby
式 if 条件
式 unless 条件
式 rescue 式(例外処理)
```

# 繰り返し

- すべて、do は省略可能

```ruby
# [構文]

while 継続条件 do
  # ...
end

until 終了条件 do # while の逆
  # ...
end

for 変数 in オブジェクト do
  # ...
end

# [メソッド]

100.times do
  # ...
end

配列.each do |変数|
  # ...
end

ハッシュ.each do |キー, 値|
  # ...
end

loop do # 無限ループ
  # ...
end
```

# 繰り返し制御
- break: C/C++のbreakと同じ
- next : C/C++のcontinueと同じ
- redo : 同じ条件で繰り返しをやり直す

# ブロック

- do ～ end もしくは { ～ }
- 慣例としては、
    - 複数行にまたがるとき: do ～ end
    - １行にまとめるとき  : { ～ }

# メソッド

```ruby
def メソッド名(引数1, 引数2, ...)
  # ...
end

def メソッド名(引数1, 引数2=デフォルト値, ...)
  # デフォルト引数を設定可能
end

def メソッド名
  # 引数無しの場合、()は省略可能
end
```

# 文字列

```ruby
'xxx' # こちらはエスケープされない
"xxx" # "... #{var} ..." という形で、式を評価した結果を埋め込める
```

# 名前

- Ruby では、以下は単なる慣習ではなく、名前によりスコープが決定
    - ローカル変数    : 先頭が小文字 or _
    - グローバル変数  : 先頭が $
    - インスタンス変数: 先頭が @
    - クラス変数      : 先頭が @@
    - 定数            : 先頭が大文字

- 以下は慣習
    - 変数名、メソッド名は、xxx_xxx_xxx のような、小文字を _ でつなぐ形
    - クラス名、モジュール名は、キャメルケース
    - ?で終わるメソッドは、真偽値を返す
    - !で終わるメソッドは、破壊的メソッド

# スコープ

- Ruby1.9ではブロックスコープはある
- Ruby1.8では、ブロックローカルな変数は外に取り出せないが、ブロック外と同名の変数をブロック内で使うと上書きになる

# オブジェクト同一性

- equal? メソッドは、同一インスタンスかどうかの比較
- == は、値の同一性の比較

```ruby
a = "abc"
b = "abc"
a.equal?(b) # => false
a == b      # => true
```

# 真偽値

- false, nil のみが偽
- それ以外はすべて真

# クラス
- Ruby1.8では、Objectクラスがすべてのクラスの先祖
- Ruby1.9では、Objectのさらに親の BasicObject が存在

```ruby  
 # [基本]

 class クラス名 < 親クラス
   Version = "1.0" # 定数
   @@count = 0     # クラス変数

   def initialize(name = "Ruby") # new でオブジェクトが生成される際に呼ばれる
     @name = name  # インスタンス変数
     self.xxx()    # C++ の this に相当するのは self
   end
 end

# [インスタンスメソッド]

class クラス名
  def メソッド名(引数)
    # インスタンスメソッド
  end
      
  def name
    @name              # ゲッター
  end
     
  def xxx=(value)
    @name = value      # セッター
  end
      
  attr_reader :name    # 上記ゲッターを定義したのと同じ
  attr_writer :name    # 上記セッターを定義したのと同じ
  attr_accessor : name # attr_reader, attr_writer を両方定義
end

# [クラスメソッド]

class クラス名
  def クラス名.メソッド名(引数) # def self.メソッド名(引数) でもよい。
    # クラスメソッド
  end
      
  class << クラス名   # class << self でもよい
    # クラス名より self を使ったほうが、重複が少なく、クラス名の変更時に柔軟。
    def メソッド名(引数)
      # クラスメソッド
    end
  end
end

    
# [アクセス制御]
# 何も指定しなければ public (ただし initialize は常に private)

class クラス名
  def priv
    # ...
  end

  private :priv # public, private, protected が指定できる
end

class クラス名
  public        # 以降すべて public

  def pub
    # ...
  end
      
  private       # 以降すべて private

  def priv
    # ...
  end
end
```

# モジュール

クラスと異なり、
- メソッド(モジュール関数)と定数だけをまとめたもの
- インスタンスを持つことができない
- 継承できない

```ruby
module モジュール名
  Version = "1.0"        # 定数
    
  def hello(name)
    # ...
  end
  module_function :hello # モジュール関数として公開
end
```

# 例外

```ruby
begin
  # 例外を投げるのは、raise メッセージ(or クラス)
rescue => 変数
  # 例外時の処理
ensure
  # 必ず実行される
end

# 処理全体を begin ～ end で括る場合は、begin, end は省略できる
def foo
  begin
    # ...
  rescue => ex
    # ...
  end
end

# ↓

def foo
  # ...
rescue => ex
  # ...
end

# throw, catch キーワードは、例外ではなく、複数のループを脱出するのに使われる
catch (:exit) do
  # ...
  throw :exit # catch ブロックを抜ける
  # 実行されない
end
```

# その他
- インデントは、スペース2つが慣習