Ruby基礎文法

# Ruby基礎文法


## **概要**

- [公式サイト](https://www.ruby-lang.org/ja/)
- [純オブジェクト指向プログラミング言語](https://www.ruby-lang.org/ja/about/)
- [Ruby on Rails](https://railstutorial.jp/)で採用されて人気。

## __データを表示する。__  


```rb
print  "hello world!" 終わった後に改行がない
puts "hello world" 改行がある
p "hello world(p)" データの形式がわかるように表示する。
```

## __便利なコマンド__

- **irb**:インタラクティブにRubyを記述できる。exitで抜ける]

- **ri**: [知りたい命令とかオブジェクトを見る。 qで抜ける]




### **長いコメント**

ex: コメントアウト

```rb

=begin
コメント
コメント
=end

```

## **変数と定数の違い。**

- **変数**:データにつける
  - (小文字から始まる)
- **定数**:変更されないデータになる。
  - (全て大文字となるABCDEGG)
  - **大文字から始まれば定数**

````
msg = "Hello world"
p msg
````

- **定数は上書きできるが警告がでる!**

````
ADMIN_EMAIL ="endo@yahoo.co.jp"  
ADMIN_EMAIL ="endo@yahoo.co.jp"  //怒られる
````

## __Rubyにおけオブジェクト、メソッド、クラス__

- `データ(ocject)`:色々な便利な命令が詰まった **データ型**であると認識する
-  メソッド(クラスで定義されている。)
  - __objectの設計図__  
  - 文字列だったら`StringClass`
  - Rubyでリテラルを使って簡単にオブジェクを作成する事ができる。

したがってRubyはオブジェクトに適するクラスとそのメソッドを書いていくことでプログラマーにとって書いてて気持ちの良い言語であると理解できる。　

- `"Hello wold".length`
これは`文字列オブジェク`.`length`と理解する。  
`"Helloworld"`とは文字列のデータ型であると同時に文字列のオブジェクトでもあると考えられる。  




ex:どのクラスに属して、どのメソッドを使えるのかを把握する。

```rb

#このobjがどんなクラスに属しているのか
p 4.8.class
#このobjがどんなmethodを使えるのか
8 p 3.8.methods


# result 

Float
[:%, :*, :+, :-, :/, :<, :>, :-@, :**, :<=>, :<=, :>=, :==,
:===, :eql?, :inspect, :to_int, :to_s, :to_i, :to_f, :hash,
:coerce, :divmod, :fdiv, :modulo, :abs, :magnitude, :zero?,
:floor, :ceil, :round, :truncate, :positive?, :negative?,
:quo, :nan?, :infinite?, :finite?, :next_float, :prev_float,
:to_r, :numerator, :denominator, :rationalize, :arg, :angle,
:phase, :+@, :singleton_method_added, :div, :i, :remainder,
:real?, :integer?, :nonzero?, :step, :rectangular, :rect,
:polar, :real, :imaginary, :imag, :abs2, :conjugate, :conj,
:to_c, :between?, :instance_of?, :public_send,
:instance_variable_get, :instance_variable_set,
:instance_variable_defined?, :remove_instance_variable,
:private_methods, :kind_of?, :instance_variables, :tap,
:singleton_method, :is_a?, :define_singleton_method,
:extend, :method, :public_method, :to_enum, :enum_for, :=~,
:!~, :respond_to?, :freeze, :display, :object_id, :send,
:nil?, :class, :singleton_class, :clone, :dup, :itself,
:taint, :tainted?, :untaint, :untrust, :trust, :untrusted?,
:methods, :protected_methods, :frozen?, :public_methods,
:singleton_methods, :!, :!=, :__send__, :equal?,
:instance_eval, :instance_exec, :__id__]

```


## **数値記号**

- + - *  / % **

ex:基本演算記号

```rb
p x%3 #1
p x**3 #1000
p z*2 #2/3
```

### **Float型**


- **整数も浮動小数もオブジェクトなので便利なメソッドを使える。**

ex:Floa型

```rb

#Floatクラス

#5分の2
puts Rational(2,5)
puts 2/5r


#p y.round(四捨五入)　

p 52.6.round#四捨五入
p 52.6.floor#小数点以下切り捨て
p 52.6.ceil #小数点以上、切り上げ

```


### __自己代入!__

ex:自己代入

```rb

x= x+5  
x += 5

```

## __文字列オブジェクト__
- _""で囲む文字列object_
  - 変数展開,特殊文字が浸かる
-  ''で囲む文字列object
  - 変数展開はできない。
- `#{}`で変数の中身が評価される。


ex:文字列オブジェクト

```rb

price = 1400
#  #{}はさむ事で式が評価される
puts "price #{3000*4}"  #ちゃんと評価される
puts "price {3000*4}" #評価されない
puts 'price #{3000*4}'#そもそも''だから、変数が評価されず展開されない。

name="Endo Futoshi"
puts " Hello My nama is #{name}!"

#文字列でよく使うオブジェクトメソッド

puts "hello "+"wold"
puts "hello "*3


# result

price 12000
price {3000*4}
price #{3000*4}
 Hello My nama is Endo Futoshi!
hello wold
hello hello hello

```

## __破壊的メソッド(!),真偽値を返すメソッド(?)__

- ! 破壊的メソッド  
  - `upcase`  文字列を大きくして返す。
  - `upcase!`  文字列を大きくして、元の文字列も書き換える。

ex:破壊的メソッド

```rb

#! 破壊的メソッド

name="endo"
puts name.upcase
puts name

#破壊的メソッドが実行された。
puts name.upcase!
#元の値自体が変わってしまった。
puts name

# result
ENDO
endo
ENDO
ENDO

```


- 真偽値を返すメソッド

- ?:真偽値を返すメソッド  
  - true,false で結果を返す。

ex:真偽値を返すメソッド

```rb

#　?真偽値オブジェクト
p name.empty? #返却値はtrue か false 今回はFalse

p name.include?("e") #false なぜなら破壊されているから
p name.include?("E")

# result

false
false
true
```

## __配列オブジェクト__

ex: 配列オブジェクト

```rb

colors = ["red","blue","Yellow"]
p colors[0]
p colors[-1] #末尾


# result
"red"
"Yellow"
```

### **配列の範囲指定**

ex:配列での範囲してい。

```rb

p sales[0..2] # 0 1 2 (0~2以上)
p sales[0...2] #0 1のみ (0~2未満)

numbers = [1,2,3,4,5,6,7,8,9,10]

p numbers[0..2]
p numbers[0...2]
p numbers[10] # nil

# result

[1, 2, 3]
[1, 2]
nil
```

### **末尾の要素を指定する**

ex:末尾の要素を指定する。

```rb
colors = ["red","blue","Yellow"]

p sales[-1]

# result

"Yellow"
```

### **置き換える**

ex:値の置き換える

```rb
sales = [5,8,4]
#//置き換え #0から2未満(0,1)
sales[0...2] = [1,2] 

p sales 

#rsult
[1,2,4]

```

### **追加する**

ex:配列オブジェクト[0,1,3]に[10,11,12]を入れる。

```rb
#添字の1から0個分=sales[1]の部分から[10,11,12]を追加する。
numbers = [1,2,3]
p numbers

#要素を追加する。
numbers[1,0] = [10,11,12]
p numbers


# result
[1, 2, 3]
[1, 10, 11, 12, 2, 3]
```

配列オブジェクトの中に配列オブジェクトを埋め込む


ex:配列オブジェクト[0,1,3]に配列オブジェクト[10,11,12]を入れる。

```rb

numbers = [1,2,3]
p numbers

#配列オブジェクト自体を追加する。
numbers[1.0] = [10,11,12]
p numbers

# result
[1, 2, 3]
[1, [10, 11, 12], 3]
```


### **削除する。**

ex:要素を消去する。

```rb
#sales[0,2]=[] #0から2未満なのでsalse[0],sales[1]が空になる。
numbers = [1,2,3]
p numbers

#要素を消去する。
numbers[0,2] = [ ]

p numbers

# result
[1, 2, 3]
[3] # 1,2が消える。

```


### **配列オブジェクトで使えるメソッド**

ex:配列オブジェクトで使えるメソッド

- **size**:要素数
- **sort**:ソートする。
- **reverse**:逆にする。(sort.revrseで逆順にソートする。)

```rb
p sales .size #要素の数
p sales.sort #ソートする。
p sales.sort.reverse #メソッドはピリオドでつなげていく
```

### **pushメソッド**

- **push**:配列の末尾に要素を付け加える

ex:pushメソッド

```rb

animals = ["dog","cat","mous"]
p animals
animals.push("pig")
p animals

# result
["dog", "cat", "mous"]
["dog", "cat", "mous", "pig"]
```

## __hashオブジェクト__

>改めて配列とハッシュの違いを確認しておくと、配列は複数のオブジェクトを順に並べて先頭から番号を割り当てたものです。それに対して**ハッシュはバラバラの位置に配置したオブジェクトに目印となるキーが付いていると考えて下さい。ハッシュでは要素の順番というものがありませんので、何番目の要素という形式では参照できません。**対応するキーを指定することで値を取得します。



```rb

#ハッシュオブジェクトを創る (キーが文字列)
scores_1={"endo"=>200,"takahasihi"=>400}

#シンボル名で書く(動作が高速である)
scores_2={:taguchi =>200,:watanabe => 150}

#シンボル名は以下の様に短くできるし、読みやすい。
scores_3={iida: 200,saeki: 320}

```


ex1:hashObj

```rb
sales ={"taguch":200,"endo":400,"tanaka":300}
p sales
p sales[:endo]
```

ex2:hashObj キーがシンボルオブジェクト(識別子)

```rb
sales = {:taguchi =>200,:endo=>400,:tanaka=>300}
p sales
p sales[:endo]
```

ex3:シンボルオブジェクトの省略形。

```rb
sales = {taguchi: 200,endo: 400,tanaka :300}
p sales
p sales[:endo]

# resultは全て同じ
{:taguch=>200, :endo=>400, :tanaka=>300}
400
```



### __hashオブジェクトで使えるメソッド__


- p sales.size :要素数
- p sales.key :キー
- p sales.value :値
- p sales.has_key?(:endo) :`:endo`(キー)と紐付いた値はあるのか?


ex:HashObj

```rb

scores_3={iida: 200,saeki: 320}

p scores_3[:iida]
p scores_3[:saeki]

scores_3[:iida]=600
scores_3[:iida]

p scores_3.size
p scores_3.keys
p scores_3.values #中に値があるか確認する。
p scores_3.has_key?(:iida)

# result

200
320
2
[:iida, :saeki]
[600, 320]
true

```


## **オブジェクトを相互に変換する。**

ex:数値Objと文字列Objをそのまま変換しようとするとエラーになる例。

```rb
a=10
b="5"
p a+b`

#result
#Errorが起きる  

```


### **文字列を数字として扱う。**

- **to_i**:int型に変換する。
- **to_f**:float(浮動小数型)に変換する。

ex:intとfloatの変換

```rb

a=10
b="10"

if  a == b.to_i
    puts "true"
else
    puts "false"
end

# result
True

```

ex2:文字列と数値型を総合変換する。

```rb

a=10 #数値
b="5" #文字列

p a+b.to_i 
p a+b.to_f 

# result

#15  (整数)(int)
#15.0 (実数)(float)
```



### **数字を文字列として扱いたい**

- **to_s**:文字列型に変換する。

ex:数値型と文字列型の相互変換

```rb

a=10 #数値
b="5" #文字列
p a.to_s+b #105

```

### **HashとArrayを相互変換する**

- **to_a**:Arrayに変換する。
- **to_h**:Hashに変換する。

ex:Hash→Array

```rb
score = {taguchi:200, endo:300}
puts score
puts score.class
# Convert to Arrau
puts score.to_a
puts score.class

# result

{:taguchi=>200, :endo=>300}
Hash

taguchi
200
endo
300
Array
```


ex2:Array->Hash

```rb
score = [[:taguchi,200], [:endo,300]]
puts score
puts score.class
#配列として表示させられる。
puts score.to_h
puts score.to_h.class

# result

taguchi
200
endo
300
Array
{:taguchi=>200, :endo=>300}
Hash

```

ex3:HashとArrayの相互変換

```rb
h={taguchi: 100,Endo: 200}
#(to Array)
p h.to_a
#(to Hasj)
p h.to_a.to_h 

# result
[[:taguchi, 100], [:Endo, 200]]
{:taguchi=>100, :Endo=>200}
```


## **％記法**

参考
>- [Rubyで%記法（パーセント記法）を使う](http://qiita.com/mogulla3/items/46bb876391be07921743)

- %記法は""や''などの特殊文字を表したいときに使う。
  - **%Q()**:`" "`で囲んだ事同じ意味になる。 
  - **%q()**:`' '`で囲んだ事同じ意味になる。
  - _あんまり使わない。_

ex:%q,%Qを使った例。

```rb

name="endo"

puts "hello#{name} !"+"なますて"
puts %Q(hello#{name}!)+%Q(なますて)

puts 'hell #{name}'
puts %q(hello #{name})

# result

helloendo !なますて
helloendo!なますて
hell #{name}
hello #{name}
```

ex2:特殊文字を表示する。

```rb

puts "\"\"は文字列ですが特殊文字を評価します"
puts %Q(""は文字列ですが特殊文字を評価します)

# result

""は文字列ですが特殊文字を評価します
""は文字列ですが特殊文字を評価します
```


### **%配列(Array)記法**

- **%w**(小文字) 配列を作る。配列の要素はスペース区切りで指定する。**式の展開はされない。**
- **%W**(大文字) 配列を作る。%w()と違い、**式が展開がされる。**

ex1:%wを使った例。

```rb
a=["a","b","c"]
p a
b=%w(a b c)
p b

# result
["a", "b", "c"]
["a", "b", "c"]
```

ex2:%Wを使った例。

```rb
#変数
apple='red'
banana='yellow'

array=%W(#{apple} #{banana} PHP)
p array

# result
["red", "yellow", "PHP"]
```

## __書式付きで文字列に値を埋め込む__

- **%S**:文字列
- **%d**:整数
- **$f**浮動小数点

この文法を使う時のメリットとしては、文字の幅や小数点2桁切り捨てなどと言った事が出来る点である。


```rb
p "name: %s" % "taguchi"

#10桁分の幅を開ける
p "name: %10s" % "taguchi"

#10桁を幅を空けつつ左寄せ(-を入れる)にする。
p"name: %-10s" % "taguchi"

#10.3fは小数点前が10桁、小数点以下が3桁という意味
#05dは5桁にしたいが、5桁にみたない場合は0を入れてくれという意味
p "id: %05d, rate: %10.3f:" %[355,3.84]

#これが2fだから小数点以下は2桁となる。
p "id: %05d, rate: %10.2f:" %[355,3.84]

# printf 書式付きで文字列を表示できる。
# sprintf 文字列を返すだけ

printf("name: %10s \n","endo")
printf("id:%05d, rate:%10.2f \n",355,3.284)

#文字列を返す。
p sprintf("id:%05d, rate:%10.2f \n",355,3.284)

# result
"name: taguchi"
"name:    taguchi"
"name: taguchi   "
"id: 00355, rate:      3.840:"
"id: 00355, rate:       3.84:"
name:       endo
id:00355, rate:      3.28
"id:00355, rate:      3.28 \n"
```


## **if文の条件分岐**

最期は必ずendを入れる。

基本形

```rb
if 条件
    真
else
    偽
end
```

### **elsif**

```rb

score = 80

if score > 60
    puts "ok"
elsif score >40
    puts "SOSO"
else
    pus "NG!"
```

### **1行でif文。**

ex:if文を1行で書く。

```rb

score = 100
puts "OK" if score >60

# result
OK!
```



### **真偽値と条件演算子**

Rubyの条件式の判定は以下の通りである。

|結果|条件|
|:----|:---|
|真|trueとnil 以外のオブジェクト(0,""を含む))全て|
|偽|**falseとnil(オブジェクトが存在しない)**| 



### **三項演算子**

三項演算子(条件演算子）を使用することによって

```
if 条件
　a=b(式1)
else
  a=c(式2)
end

```

このようなif文を

```
条件 ? 式１ : 式２
a=条件 ? b : c
```

と記述する事ができる。

>- [Ruby・Rails】三項演算子(条件演算子）を使ってif文をスリムに書こう！](http://qiita.com/lasershow/items/160c854e4256ba596ec5)


ex:三項演算子

```rb

a=10
b=20

a=b>c?:b:c 
puts a

# result
20
```

## **多重代入**

基本例 

```rb
foo, bar = [1, 2]       # foo = 1; bar = 2
foo, bar = 1, 2         # foo = 1; bar = 2
foo, bar = 1            # foo = 1; bar = nil

foo, bar, baz = 1, 2    # foo = 1; bar = 2; baz = nil
foo, bar = 1, 2, 3      # foo = 1; bar = 2

#Array

foo      = 1, 2, 3      # foo = [1, 2, 3]
*foo     = 1, 2, 3      # foo = [1, 2, 3]
foo,*bar = 1, 2, 3      # foo = 1; bar = [2, 3]
```

ex:多重代入

```rb

#右辺が , 区切りで複数ある場合には配列に変換される
a=1,2,3,4
#左辺も , 区切りで複数ある場合には配列に変換された上で、左辺の各変数に右辺の各要素が代入される
b,c="apple","banana"
p a
p b
p c

#result
[1, 2, 3, 4]
"apple"
"banana"
```

#### 参考資料

>
- [Ruby 2.4.0 リファレンスマニュアル > 演算子式](https://docs.ruby-lang.org/ja/latest/doc/spec=2foperator.html#multiassign)
- [Rubyの多重代入あれこれまとめ](http://qiita.com/yancya/items/c557864f307d429bbde4)



## **case文で条件分岐**

ex:case文

```rb
# case分chomp

#chomp:最後の改行コードを取り除く。
#CLから値を受け取る。

signal=gets.chomp

   
case signal
when "red" then
    puts "stop!"
when "green","blue" then
    puts "go!"
when "yellow" then
    puts "caution!"
else
    puts "wrong signal!"

end #最後はendで占める


# result
[vagrant@localhost RubyStudy_2.3.0]ruby case.rb
red
stop!
[vagrant@localhost RubyStudy_2.3.0]ruby case.rb
bllue
wrong signal!
[vagrant@localhost RubyStudy_2.3.0]ruby case.rb
blue
go!

```

## **繰り返し処理。**

### **timeメソッド**

>「times」メソッドは、変数に「0」から「対象のオブジェクトが持つ数値 - 1」を順に代入しながら「{」から「}」までの処理(又は「do」から「end」までの処理)を実行します*1回繰り返す毎に1ずつ数値は増加します。(「|変数|」の部分は省略可能です)。

基本形

```
オブジェクト.times do |変数|
  実行する処理1
  実行する処理2
end
```


- [timesメソッドを使ってFizzBuzz問題](http://qiita.com/Fendo181/items/425293e8e638d7fd7cea)

ex:FizzBuzz

```rb

#FizzBuzz問題
i=0

#0から30まで繰り返す
31.times do |i|

if (i%15==0 && i!=0)
    puts "FizzBuzz!"
elsif(i%3==0 && i!=0)
    puts "Fizz!"
elsif(i%5==0 && i!=0)
    puts "Buzz!"
else
    puts "#{i}"
    end
end

# result
0
1
2
Fizz!
4
Buzz!
Fizz!
7
8
Fizz!
Buzz!
11
Fizz!
13
14
FizzBuzz!
16
17
Fizz!
19
Buzz!
Fizz!
22
23
Fizz!
Buzz!
26
Fizz!
28
29
FizzBuzz!
```


#### 参考資料

>- [timesメソッド、uptoメソッド、downtoメソッド](http://www.rubylife.jp/ini/for/index6.html)

### **1行でtimesメソッドを書く**

- timesを使うと**必ず0から始まる**ので、そこだけ注意する。


ex:1行times


```rb

j=0
10.times{ |j| puts "#{j}:hello" }

#result

0:hello
1:hello
2:hello
3:hello
4:hello
5:hello
6:hello
7:hello
8:hello
9:hello
```


### **while文**

```rb
i=0
while i < 3 do
    puts "#{i} hello"
    #i =i+1
    i +=1
end
````

### **break文**

- **break**:roopを抜けます
- **nexe**:ループを1回スキップ

ex1:1の時にループを抜ける

```rb
3.times do |i|
    if i == 1
        break
    end
    puts "#{i}: hello"
end
```


ex2:1の時にnextでスキップする。

```rb

3.times do |i|
    if i == 1
        next
    end
    puts "#{i}: hello"
end
```


## **for文**

基本形

```rb

for 変数 in 配列オブジェクト do
  実行する処理1
  実行する処理2
end
```


ex:for文によるくり返し。

```rb
#for
#inにはobjectが入る

#..は"18から20まで"を表わす:(18~20)
for i in 18..20 do #doは省略できる
    p i
end

#...は"18から20以下"を表わす:(18~19)
for i in 18...20 do
    p i
end


# result

#"18..20は"15から20まで"を表わす"

18
19
20

#"18...20は"15から20以下"を表わす"

18
19
```

### **配列オブジェクトをforを回す。**

配列オブジェクトの要素数だけ回してくれる。

```rb
for color in ["red""blue"]
    p color
end

# result
red blue
```

### **hashオブジェクトでforを回す。**

hashオブジェクトの中身を全て取り出すして表示シてくれる。

```rb

for name,score in {"taguchi":200,"endo":400}
    puts "#{name}:#{score}"
end

# result
taguchi:200
endo:400
```

## **eachメソッド**

基本

```rb
配列オブジェクト.each |i|
  実行する処理1
  実行する処理2
end
```

>Arrayクラスにも「each」メソッドは用意されています。配列オブジェクトに対して「each」メソッドを実行すると、配列に含まれる要素を順に取り出して繰り返し処理が行われます。(eachメソッドについては[eachメソッド](http://www.rubylife.jp/ini/for/index5.html)を参照して下さい)。

>「for」文では繰り返しが1回行われるたびにオブジェクトに対して「each」メソッドが実行し取得した要素などを変数に代入します。

### **for文と違い**

- forではループ構文の**内外で変数のスコープは変わらない！**
- eachでは**ブロックの内外でスコープが変わる！**
  - each文の方がスコープが狭くて安心だ。 

ex1:for文とeachメソッド

```rb

colors =["red","blue","yellow"]

## ここのcolorsはどこからでもアクセスできる。
for color in colors
    p "color:#{color}"
end

# ## ここのcはeachメソッド内でしか使えない。
colors.each do |c|
    p "color:#{c}"
end

#result
"color:red"
"color:blue"
"color:yellow"

"color:red"
"color:blue"
"color:yellow"

```


### **範囲オブジェクト(Range)をeachメソッドで処理する。**

>範囲オブジェクトは実際にはRangeクラスのオブジェクトです。「..」演算子や「...」演算子によって範囲オブジェクトを作成できますが、Rangeクラスのクラスメソッドである「new」メソッドでも作成できます。

```rb

(18..20).each |i|
    p i
end

# result
18
19
20
```


### **配列オブジェクトをeachメソッドで処理する。**

```rb

["red","blue"].each do |color|
    p color
end

# result
"red"
"blue"

```


### **Hashオブジェクトにeachメソッドで処理する。**

```rb
{taguchi:200,end:400}.each do |name,score|
    puts "#{name}: #{score}"
end

# result
taguchi: 200
end: 400
```

#### 参考資料

>- [for式とeachメソッドのスコープの違いについて](http://qiita.com/kanpou_/items/8156c76a5723f4b48e3b)
- [for文](http://www.rubylife.jp/ini/for/index3.html)

## **メソッド。**

- メソッドは最後位評価された値をそのまま返す。
- メソッド内で定義されや変数には外からアクセスできないというルールがあるので注意する。

基本構文

ex:sayHiメソッド

```rb

#引数は,区切りで複数与えられる
def sayHi(name)
    puts "#{name} hi!"
end

sayHi("endo")

#result
endo hi!

```

### **デフォルト値の設定**


ex:メソッド内にデフォルト値を入れる。

```rb
def sayHo(name="endo")
    puts "#{name} ho yo!"
end

sayHo("takahashi")
sayHo 

#result
takahashi ho yo!
endo ho yo!
```

## __クラス__

- クラス名は必ず最初の文字は**大文字。**
- インスタンス生成時に呼ばれるメソッドは`def initialize`と定義する。この時にクラス外から渡される値をインスタンス内で使うようにするためにインスタンス変数を作る(**@インスタンス変数**)


ex:クラス

```rb

class User
    #インスタンス時に呼ばれる処理
    def initialize(name) #仮引数に"endo"を入れる
        #インスタンス変数(インスタンス内で保持する事ができる。)
        @name =name
    end
    #@nameはこのインスタンスはクラス内ではどこでも利用できる。
    def sayHi
        puts "Hi! i am #{@name}"
    end
end


#インスタンスを生成する。
#tomはインスタンスオブジェクトです。

tom= User.new("tom")
tom.sayHi
endo= User.new("endo")
endo.sayHi

# result
Hi! i am tom
Hi! i am endo
```


## **アクセサメソッド。**


- インスタンス変数にクラス外からアクセスする為のメソッドです。
- アクセサメソッド(ゲッター+セッター)
- **attr_accessor**で呼び出すことができます。

ex:アクセサメソッド

```rb

class Book

   #アクセサメソッド(getter+setter)
   attr_accessor :title,:price

   def initialize(title,price)
       #@の名前は一致させる
       @title=title 
       @price=price
   end

   def sayPrice
       puts "Price is #{@price}"
        #selfオブジェクト=そのメソッドを受け取っているインスタンス自身を指します。この場合だとbook.sayPrice(レシーバ)が相当する。
       puts "price is #{self.price}"

       #self演算子は以下の様に省略可能。
       #puts "price is #{price}"

    end
end



book = Book.new("EndoBook",2389)#インスタンス生成
puts book.title
puts "#{book.price}円"

book.sayPrice #

#インスタンス変数の名前を変えずに値を変えたい時にアクセッサが便利
book.title="TakahashiBooks"
book.price=2050

puts book.title
book.sayPrice

#別の名前にしたい
book_bob=Book.new("BobBobAdventure",1980)
puts book_bob.title
puts book_bob.price

book_bob.sayPrice

#インスタンス変数bookのタイトル名はこれで固定された
puts  book.title

#result 

#最初のインスタンス精製
EndoBook
2389円
Price is 2389

#アクセサを使って最初のインスタンス変数名を変えずにpriceとtitleを変える。
TakahashiBooks
Price is 2050

#インスタンス2回目
BobBobAdventure
1980
Price is 1980

TakahashiBooks
```


## **クラスメソッド、クラス変数。**

- クラスメソッド=クラスから直接呼び出せるメソッド(インスタンス変数を呼び出さなくて良い。)
- クラス定数=(一文字が大文字)個々のインスタンスではなくインスタンス全てで値を共有することができます。
- `@@name`:クラス変数

ex:

```rb

class User

    #@@がクラス変数
    @@count = 0 #初期化

    def initialize(name)
        @@count += 1
        @name = name
    end

    def sayHi
        puts "Hi! i am #{@name}"
    end

    #クラスメソッド①
    def self.sayHo
        puts "Say Ho!"
        puts "Count is #{@@count} insyatance"
    end


    #クラスで定数①
    VERSION = "これはクラス定数です。" #これもクラス外からアクセスできる。

end

#インスタンスを使わずにメソッドを呼び出します。


tom = User.new("tom")
bob = User.new("bob")
steave = User.new("Steave")

#クラスメソッド呼び出し
User.sayHo

#クラス定数呼び出し
puts User::VERSION

# result

Say Ho!
Count is 3 insyatance
これはクラス定数です。

```



## **継承クラス**

- 継承クラスは子クラスとも呼ばれ、親クラスのメソッド、変数を宣言なしに使えます(継承する。)
- また、親クラスのメソッドの上書きも可能であり、その際にはOverrideされる為、継承クラスのインスタンス時には子クラス内でoverrideされたメソッドが優先される。
- 親クラス < 子クラス:これで継承する。


ex:継承クラスの基本構文。

```rb
#継承クラスについて

class User
    def initialize(name)
        @name = name
    end

    def sayHi
        puts "Hi! i am #{@name}"
    end

end

#User:親クラス,SuperClass
#AdminUser:子クラス,SubClass
#継承クラスは親クラスのメソッドや変数を使える。

#子やクラス
class AdminUser < User
    def sayHo
        #親クラスの変数をそのまま使える。
        puts "ho! from #{@name}"
    end
    #親クラスのメソッドの上書きをするOverride
    def sayHi
        puts "Hi! Yo! "
    end
end

#あくまでここで呼び出しているのは子クラス(継承のみ)
#従って優先されるのは継承クラスでoverrideされたメソッドのみ

tom =AdminUser.new("tom")

tom.sayHi
tom.sayHo

#result

Hi! Yo!
ho! from tom
```

### **アクセス権。**

- public どこからでも
- private:レシーバを指定できない。 子クラスまでは使える。
- protected 外部から隠ぺいしたい


>つまり，privateは自分からしか見えないメソッドであるのに対し
>て，protectedは一般の人からは見られたくないが，仲間(クラスが
>同じオブジェクト)からは見えるメソッドです。protectedは例えば2項演算子の実装にもう一方のオブジェクトの状態を知る必要があるか調べる必要があるが，そのメソッドをpublicにして，広く公開するのは避けたいというような時に使います．

- 例外として、new したときに呼ばれる initialize メソッドと、クラスの外に書いたメソッドは自動的に private になるので、覚えておきましょう  
- Ruby の private 指定は他の言語のオブジェクト指向プログラミングと動作が異なっていて、Sub Class から呼び出せたり、オーバーライドすることができたりするので、十分注意して使う

ex:

```rb

class User

    def sayHi
        puts "hi1"
        puts "ここは親クラス内のメソッドです!"
        sayPrivate
        #意味的には self.sayPrivate なのですが、privateではレシーバーを指定できないので必ず self は省略してあげてsayPrivate のように書いてあげてください。
    end

    private#クラス内ならば使える

        def sayPrivate
            puts "これはプライドメソッドです。"
        end
end

##クラスが継承されるのでprivateメソッドは子クラス内で呼び出すことが可能。

class AdminUser < User

    def sayHo
        puts "hello!これは継承クラス内のメソッドです!"
        sayPrivate #privateメソッド
    end

    #なおかつ同名のメソッドの上書きも可能となる。

    def sayPrivate
        puts "privateメソッドをOverrideした"
        puts "private from Admnin"
    end



end

#User.new.sayPrivace NG privareアクセス権かかっているので

User.new.sayHi #こここで始めてprivateメソッドが呼ばれる。
AdminUser.new.sayHo

#over rideの呼び出し
AdminUser.new.sayPrivate

# result

hi1
ここは親クラス内のメソッドです!
これはプライドメソッドです。
hello!これは継承クラス内のメソッドです!
privateメソッドをOverrideした
private from Admnin
privateメソッドをOverrideした
private from Admnin
```

## **モジュールで名前空間を使う。**

- 同じメソッド名が同じファイル内に重複されると、衝突がおきる。
- 従ってモジュールを使って自分だけの名前空間を作ってあげれば衝突を回避する事ができる。


```rb
=begin

def movie_encode

end

def movie_export
end

これらのメソッド名は他の人も使って衝突が起きやすくなる。

=end
```

ex基礎構文

```rb
module Movie

    VERSION = 1.1

    #クラスメソッドの様に書けばいい
    def self.encode
        puts "encodeing.."
    end


    def self.export
        puts "exporting.."
    end
end

Movie.encode
Movie.export

puts Movie::VERSION


#別のモジュールを作る(名前空間的な)
module Movie2

    VERSION = 1.1

    #クラスメソッドの様に書けばいい
    def self.encode
        puts "encodeing.."
    end


    def self.export
        puts "exporting.."
    end
end

Movie2.encode
Movie2.export

puts Movie2::VERSION


# esult

encodeing..
exporting..
1.1
encodeing..
exporting..
1.1

```


## **ミックスイン(モジュールの応用)**


- ミックスインに関してはもっと複雑なこともできるのですが、継承関係にない複数のクラスに共通の機能を提供する場合に便利なので慣れておくといいかと思います。
- ミックスインのメインの機能として継承関係にない複数のクラスに共通の機能を提供する場合に便利である

ex:ミックスイン

```rb

module Debug

    def info
        puts "#{self.class} debug"
    end
end

class Player
    #ミックスイン
    include Debug
end

class Monster
    #ミックイン
    include Debug
end

Player.new.info
Monster.new.info

```

result

```rb
Player debug
Monster debug
```


## __例外処理__

ex:例外処理


```rb

x=gets.to_i
#自分で例外クラスを作る
class MyError < StandardError end

#p 100/x #0を入れるとErrorが発生します。
#例外処理の書き方
begin
    if x == 3
        raise MyError #自分が作った例外処理を発生させる
    end
    p 100/x

#例外クラスで発生したオブジェクトMyErrorを作る。
rescue MyError
        puts "noy 3!"#独自のメッセージを作る

rescue => ex #発生した例外をexに入れる。
    p "エラメッセージ"+"#{ex.message}" #予めた用意されたメッセージを表示する
    p "エラー起こしたクラス"+"#{ex.class}" #このオブジェクト名のクラス名
    puts "例外が"+"発生しましたよ!"
    puts "stopped!"

ensure#例外が発生しよがしまいが、最後に絶対実行したい処理
    puts " __END__"
end

# resultの検証

0を入力した時

0
"エラメッセージdivided by 0"
"エラー起こしたクラスZeroDivisionError"
例外が発生しましたよ!
stopped!
 __END__

3を入力した時
3
noy 3!
```