Progate　Ruby　備忘録


Progateの「Ruby」で学習した内容をまとめてみました。

## コンソールへの出力
`puts`の後に出力したい文字列や変数などを指定する。
文字列を含む内容を出力する場合は以下のように、ダブルクォーテーション（`"`）で囲む必要がある。
```ruby
# 変数宣言
name = "huga"

puts "hoge"
puts 1 + 2
puts "1 + 2"
puts name
```
一応、シングルクォーテーション（`'`）で囲むやり方でも文字列の出力は可能だが、
ほとんど使い道はなさそうなので覚えなくても大丈夫だと思われる。
（Javaでもシングルクォーテーションはほとんど使わない気がする）‘

また、`#{変数名}`の構文を使用することで、変数の中身を文字列に含めることができる。
```ruby
name = "hoge"
puts "初めまして、#{name}さん"
```

## コメントについて
行の先頭に`#`を入れた行はコメントとして扱われる。
複数行をコメントアウトしたい場合は、`=begin`と`=end`の構文を利用すればよい。
```ruby
# puts "非表示"
puts "表示"

puts 1
=begin
puts 2
puts 3
=end
puts 4
```

## ifによる条件分岐
`if`や`elsif`、`else`を組み合わせることで条件分岐を行うことができる。
条件分岐の最後には必ず`end`を入れること。
1行で記述する場合は`if`や`elsif`の後に`then`を入れる必要がある。
（`elsif`は`else if`等と間違えやすいため注意）
```ruby
# 複数行に分けて記述した場合
score = 80
if score >= 80
  puts "A評価"
elsif score >= 60
  puts "B評価"
else
  puts "C評価"
end

 # 1行で記述した場合
point = 90
if point >= 100 then puts "100以上"
elsif point >= 80 then puts "80以上"
else puts "80未満"
```

### if文に複数の条件を記述したい場合
AND演算子（`&&`）、OR演算子（`||`）を入れることでif文の中に複数の条件を記述することができる。
条件が多くて複数行になってしまう場合、改行前にAND演算子やOR演算子、バックスラッシュ（`\`）のいずれかをを入れる必要がある。
```ruby
subject = "math"
score = 80
if subject == "math" && score >= 80
  puts "A評価"
end

# バックスラッシュを用いた例
year = 2022
month = 6
day = 1
if year == 2022 \
   && month == 6 \
   && day == 1
  puts "2022年6月1日です"
end
```

## 繰り返し処理について
繰り返し処理は`each`を使うことで実現できる。
仕組みとしてはJavaでいうところの拡張for文、JavaScriptでいうところの`for...of`文に近い。
```ruby
subjects = ["Japanese", "Math", "English"]
subjects.each do |subject|
  puts subject
end
```

## ハッシュについて
いわゆる連想配列やオブジェクトのこと。
波かっこ（`{}`）の中に`key => value`の形式で記述する。
複数作成したい場合はコンマ（`,`）で区切ること。
```ruby
exam_result = {"Japanese" => 80, "Math" => 90, "English" => 75}
```

### ハッシュの参照や追加、更新を行う場合
`ハッシュを格納した変数[キー]`で特定の要素にアクセスできる。
（この部分はほかの言語と変わらないので、覚えやすい）
```ruby
exam_result = {"Japanese" => 80, "Math" => 90, "English" => 75}
# 国語の点数を参照
puts exam_result["Japanese"]
# 理科の点数を追加
exam_result["Science"] = 60
# 数学の点数を変更
exam_result["Math"] = 100
```

### シンボルを使った効率的な書き方について
ハッシュのキーとして、文字列のほかにシンボルを利用することができる。
文字列の先頭、または最後にコロン（`:`）をつけると、シンボルとして扱われる。
公式リファレンスには、メリットとして次のような内容が記載されている。
> ・新しく文字列を生成しない分やや効率がよく、比較も高速。
> ・文字の意味がはっきりするのでコードが読みやすくなる。
> ・immutable なので内容を書き換えられる心配がない。

```ruby
# 定義
exam_result = {Japanese: 80, Math: 90, English: 75}

# 参照
puts exam_result[:Japanese]
```

## nilについて
他言語でいうところの`null`がこれに該当する。
nilはfalsyな値として扱われる。
（if文などの条件で指定されたときに、falseとして扱われる）

## 複数のハッシュを配列で扱う場合
配列の定義方法、ハッシュの定義方法を組み合わせて使用することで複数のハッシュを配列で扱える。
```ruby
# 定義
foods = [
  {name: "apple", price: 100},
  {name: "banana", price: 120}
]
# 2つ目の要素を参照
puts foods[1][:name]
# 繰り返し処理で扱う場合
foods.each do |food|
  puts food[:name]
end
```

## メソッドの定義や利用方法について
`def メソッド名`でメソッドを定義することができる。
引数を受け取りたい場合の記述方法はJavaやJavaScriptなどと似ている。
戻り値がある場合、メソッド定義時に戻り値の型は記述する必要がないが、
boolean型の戻り値の場合はメソッド名の後ろに`?`を入れる風習があるようだ。
（?が入っているおかげで、戻り値がbooleanだということが一目でわかっていいかも。）
```ruby
# 引数なし、戻り値なし
def hoge
  puts "hoge"
end
# 引数あり、戻り値なし
def huga(hugahuga)
  puts hugahuga
end
# 引数あり、戻り値あり
def plus(num1, num2)
  return num1 + num2
end
# 引数あり、戻り値がboolean
def isOddNumber?(num)
  return num % 2 == 1
end

# メソッドの呼び出し
hoge
huga
plus(1, 2)
isOddNumber?(3)
```

### メソッドで利用できるキーワード引数について
引数名の最後にコロン（`:`）を入れるとキーワード引数として扱われる。
メソッドで定義した引数名を呼び出し時に記述できるようになり、可読性が高くなる。
```ruby
def print_fruit_info(name:, price:)
  puts "#{name}の値段は#{price}円です。"
end
print_fruit_info(name:"apple", price:100)
```

## クラスについて
`class クラス名`でクラスを定義することができる。
クラスのフィールドは、`attr_accessor :フィールド名`で定義できる。
（`attr_accessor`はgetterとsetterの両方の役割を持たせることができる？）
attr_accessorについては以下の説明がわかりやすい。

https://qiita.com/Hassan/items/0e034a1d42b2335936e6

```ruby
# 定義
class hoge
  attr_accessor :hogehoge
  attr_accessor :hugahuga
end
# インスタンスの生成
hoge1 = hoge.new
# フィールドの参照
hoge1.hogehoge
hoge1.hugahuga
```
### クラスのコンストラクタについて
インスタンス生成直後に呼び出される`initialize`メソッドがコンストラクタの役割を果たす。
コンストラクタの引数はインスタンス生成時に渡せばよい。
コンストラクタでフィールドの初期値設定などを行う場合は`self.フィールド名`と記述すればよい。
(Javaの`this.フィールド名`と意味は似ている？)
```ruby
def Fruit
  attr_accessor :name
  attr_accessor :price

  # コンストラクタ
  def initialize(name:, price:)
    self.name = name
    self.price = price
  end

  def print_info
    puts "#{self.name}は#{self.price}円です"
  end
end

# インスタンス生成＆コンストラクタの呼び出し
fruit1 = Fruit.new(name: "apple", price: 100)

fruit1.print_info
```

### クラスの継承
`子クラス < 親クラス`でクラスの継承を行うことができる。
（シンプルすぎて、最初は比較しているのか？と勘違いしてしまいそう。）
```ruby
# Parentクラスの内容をChildクラスへ継承する
Child < Parent
```

### `super`について
継承元クラスの同名メソッドを呼び出すときに使用する。
よく使用するケースとしては、親クラスのコンストラクタを呼び出したいときだろうか。

### クラスメソッドについて
クラス全体で扱いたい情報がある場合はクラスメソッドに記述する。
`def クラス名.メソッド名`や`def self.メソッド名`で定義できる。
（Javaでいうところのstaticメソッドとクラスメソッドは似ているかも。）

## ファイルのインポート
`require インポートしたいファイルのパス`を記述することで、インポートを行える。
パスの箇所には絶対パスか、相対パスを記述できる。
Dateなどの、既に定義されているクラスはクラス名のみ直接記述すればよい。
```ruby
# ファイル名：fileA
require "./fileB"
b = B.new

# ファイル名：fileB
def fileB
  def initialize
    puts "クラスBのコンストラクタが呼び出されました"
  end
end

# 別ファイル
# dateクラスの呼び出し
require "date"
```





# 参考
- https://prog-8.com/courses/ruby
- https://simanman.hatenablog.com/entry/2013/08/28/104603
- https://qiita.com/ryosuketter/items/ddad508cb0124e4fe378
- https://www.task-notes.com/entry/20141116/1416106800
- https://zenn.dev/fjsh/articles/ac17ccae67ef1a
- https://docs.ruby-lang.org/ja/latest/class/Symbol.html