Ruby.学習その7

#### 投稿目的
- 個人の学習目的で投稿していきます。
- Rubyの入門を読みながら自分なりの思考で記述しています。

#### 参考資料

[ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)](https://www.amazon.co.jp/ゼロからわかる-Ruby-超入門-かんたんIT基礎講座-五十嵐/dp/4297101238/ref=sr_1_3?ie=UTF8&qid=1549614126&sr=8-3&keywords=ruby+入門)

## モジュール(module)
- モジュールの定義はクラスと同じです。
- クラスと違ってnewを利用してインスタンスを作成することはできません。
- メソッドやインスタンス変数などは定義する事はできます。

#### include
- includeメソッドをクラスで利用するとモジュールのメソッドをinclude先のクラスでインスタンスメソッドとして利用することができる。

```ruby
module Greeting # Greetingモジュールの定義
    def morning # morningメソッドを定義
        "おはようございます！"
    end
end

class School # Schoolクラスを定義
    include Greeting # Greetingモジュールをincludeで利用
end

hensuu = School.new # オブジェクト作成
puts hensuu.morning # インスタンスメソッドでモジュールメソッドを利用

# 結果: おはようございます！
```

#### extend
- extendメソッドをクラスで利用するとモジュールメソッドをextend先のクラスでクラスメソッドとして利用することができる。

```ruby
module Greeting # Greetingモジュールを定義
    def morning # mornigメソッドを定義
        "おはようございます！"
    end
end

class School # Schoolクラスを定義
    extend Greeting # Greetungモジュールをextendで利用
end

puts School.morning # クラスメソッドでモジュールメソッドを利用

# 結果: おはようございます！
```

### モジュールにクラスメソッドを定義
- モジュール内でクラスメソッドを定義して呼び出すことができます。

```ruby
module Greeting 
    def self.morning # morningクラスメソッドを定義
        "朝はおはようございます。"
    end
end

puts Greeting.morning # Greetingモジュール内のmorningクラスメソッドを呼び出す

# 結果: 朝はおはようございます！
``` 

### モジュールに定数を定義
- モジュールに定数を定義して呼び出すこともできます。
- 定数の呼び出しには::を利用します。

```ruby
module SchoolTime
    Time = "07:00" # Time定数を定義
end

puts SchoolTime::Time # SchoolTimeモジュール内のTime定数を呼び出し

# 結果: 07:00 
```

### Ruby定義済みモジュール
- cosはMathモジュールのクラスメソッドです。
    - cosメソッドは余弦関数の引数をラジアンで返す。
- PI(円周率)はMathモジュールでの定数です。

```ruby
puts Math::PI # Mathモジュールの定義済みの定数
puts Math.cos(Math::PI) # Mathモジュールの定義済みのクラスメソッド

#結果: 3.141592653589793
#結果: -1.0
```

### 名前空間
- モジュールを利用して名前を振り分ける手法のことを名前空間という。
    - 同じクラス名を複数利用する際などに名前空間を利用する。

```ruby
module MorningGreeting # モジュールでGreetingクラスの名前を付ける
    class Greeting 
        def self.word
            "おはようございます！"
        end
    end
end

module NightGreeting # モジュールでGreetingクラスの名前を付ける
    class Greeting 
        def self.word
            "こんばんは！"
        end
    end
end


puts MorningGreeting::Greeting.word # 結果: おはようございます！
puts NightGreeting::Greeting.word # 結果: こんばんは！
```

- 名前空間を利用した場合の呼び出し方
    - モジュール名で::を付けてクラスを呼び出す.を付けてメソッドを呼び出す。
    
```ruby
# モジュール名::クラス名.メソッド
```

### ファイルを別に分ける
- ファイルを分けるメリットはモジュールとクラスを別ファイルで分けることで整理もできて使い勝手もいい。

```ruby:greeting.rb
module Greeting # Greetingモジュール定義
    def morning # morningメソッド定義
        @name += "、おはようございます！"
    end
end
```

- require_relativeメソッドでファイル名を文字列で指定することでファイルの読み込みができます。

```ruby:school.rb
require_relative "greeting" # greeting.rbファイル読み込み

class School # Schoolクラス定義
    include Greeting # クラス内でGreetingモジュールを読み込み
    def initialize(name) # インスタンス作成時に自動で呼び出し
        @name = name
    end
    def name # nameメソッド定義
        @name
    end
end

school = School.new("佐藤くん") # インスタンス定義
school.morning # モジュールのメソッドをインスタンスメソッドで利用
puts school.name # nameメソッドを呼び出し
# 結果: 佐藤くん、おはようございます！
```

###### 補足: require "./greeting"で読み込む事も可能.

### includeとrequire_relativeの違い
- includeはモジュール名を渡して読み込んでモジュールメソッドをクラスから利用できるようにするメソッドです。
- require_relativeはファイル名を渡して読み込んで定義されたクラスやモジュールを利用できるようにするメソッドです。

### ライブラリ
- プログラムで共有して利用できる便利なプログラムをライブラリと呼ぶ。
- ライブラリには大きく分けて3つのライブラリが存在します。
    - 1つ目は組み込みライブラリ
        - Integer、String、Arrayなどのクラスのことです。
    - 2つ目は利用する前にrequireメソッドを実行して準備する標準添付ライブラリ
        - JSONなどのクラスのことです。
    - 3つ目は利用する前にインストールが必要Gemというライブラリです。
        - Gemを利用することで自分のプログラムで利用できるよになる。

### Gemの使い方
- まずGemをインストールする。
- awesome_printというGemを利用してみます。
 
```shell:ターミナル
$ gem install awesome_print(Gem名)
```

- requireでawesome_printを読み込むことでawesome_printのメソッドを利用できるよになります。
- apメソッドは配列の要素を見やすくするメソッドです。

```ruby
require "awesome_print"
ap [1, 2, 3, 4, 5]
```

### Bundler
- BundlerとはGemたくさんインストールしようとするとコマンドを入力するだけで時間がかかりますそのためにGemを簡単に管理するため利用にする。

- まず最初にBundlerをインストールする。

```shell:ターミナル
$ gem install bundler 
```

- 次はGemfileというファイルを作成するためにBundlerをinitすることで作成されます。

```shell:ターミナル
$ bundler init
```

- Gemfileファイル内の1番下にGemのインストールしたいものを記述します。

- 記述した後はターミナルでGemfileのあるディレクトリに移動してBundler Installを行います。

```shell:ターミナル
$ bundler install
```

- Gem Install Gem名をまとめてインストールして管理することができます。

- Gemfileに記述されたバージョンが新しくなった場合はbundlet updateを行うことでまとめて更新することができます。

```shell:ターミナル
$ bundler update
```

- バージョンを更新した後に別のバージョンを利用しなくてはならない状況になった場合はbundler execをrubyを実行する前に入力します。

```shell:ターミナル
$ bundler exec ruby ファイル名
```

### Sinatra 
- SinatraはWebアプリを簡単に作ることができるライブラリです。
- インストールしたらrequireで読み込んで利用します。
- getメソッドはSinatraで用意しているメソッドでブラウザからパス/hiへアクセスされたときの処理を続くブロックで書くことができます。
  
```ruby:sinatra.rb
require "sinatra"  # sinatraを読み込み
    get "/hi" do # getメソッドでパスを指定
        "hi!" # /hiのパスにアクセスした時の処理
end
```

- ターミナルで-p 4567を付けてファイルを実行してブラウザでアクセすると結果が表示されます。

```shell:ターミナル
$ ruby sinatra.rb -p 4567
```

- ターミナルで実行後ブラウザで下記を入力すると結果がhi!と返ってくる。
 
```
[http://localhost:4567/指定したパス]
```

#### 別パターン
- getメソッドでリクエストのパスがgreetingだった場合の処理をブロック上に記述します。
  
```ruby
require "sinatra"
get "/greeting" do # 今回のパスは/greeting
    ["おはよう", "こんにちは", "こんばんは"].sample # sampleメソッドでランダムで値を表示
end
```

- この後はターミナルで-p 4567を付けて実行してブラウザでパスを入力して表示すると結果が配列の文字列がランダムで返ってくる。

### URLを理解
- URLの構成は下記のようになっている。

```
スキーム   ホスト名 ポート番号 パス
http://localhost:4567/greeting
```

#### スキーム
- スキームの部分は一般的にはプロトコル(約束事的な)の意味を持つ、ブラウザからWebアプリにアクセスするときに安全に通信するためにHTTPを利用している、それ以降は://で区切ります。

#### ホスト名
- ://から後の2つ目の:までがホスト名で例えばcookpad.comやamazon.co.jpなどWeb上の住所にあたるものlocalhostは自分自身のマシンを指すものです。

#### ポート番号
- 2つ目の:の後ろ/の前まではポート番号でポートとは同じマシンの中で複数の相手と通信をするための仕組み。
- しかし、普通にブラウザを使用してもポート番号を指定することはほとんどありません、ポート番号が省略される定められているポート番号である443や80が使われそれでアクセスができるように作られている。

#### パス(/greeting)の部分
- パスはホストの中でのページ名で、違う情報を載せたいページを作るときはパスを新たに定めてから新しいページを作ります。

### Webアプリの基本動作
- Webアプリがブラウザからアクセスされて画面を表示するまでには分解すると3つのプロセスがあります。
    - ブラウザからリクエストをサーバ投げる
        - URLを入力してこのページを見たいとサーバへリクエストをしている、主要な情報はURL、HTTP、GETメソッドであること。
    - Webアプリがリクエストに対応したレスポンスを返す
        - Webアプリがブラウザからリクエストを受け取るとレスポンスとしてHTMLを作ってブラウザに返します。
        - リクエストを受けっとたWebアプリは情報であるGETメソッドとパスから対応する処理を実行してHTMLを作りそれを含めたレスポンスを作って返します。
    - ブラウザがレスポンスで返ってきたHTMLを解釈して表示
        - ブラウザはレスポンスを受け取るとそれを解釈してユーザが分かるようにWebページに表示します。