19日目
今日の学習
Ruby
配列
まず大前提として、Rubyは文字、数値、nilなども含めて全てがオブジェクトである。
そして、複数のデータをまとめて格納できるものが配列というArrayクラスのオブジェクトだ。
ブロック
メソッドの引数として渡すことができる処理の塊をブロックと呼ぶ。
numbers = [1, 2, 3, 4] sum = 0 numbers.each do |number| sum += number end
doからendまでがブロックになる。
この形は下記のように書き換え可能
numbers = [1, 2, 3, 4] sum = 0 numbers.each { |n| sum+= n } # do ... end の代わりに{ }を使用する
この場合は、eachメソッドで取り出された配列の要素をどう扱うかをブロックで決める。
| |
ここに入る引数を(上の例だとn)、ブロック引数と呼び、eachメソッドで引き出された配列の要素が順番に入っていく。
ブロック引数に対してどのような処理をするか?というのを書く。
each文はRailsでも非常によく使うので、こういう形のものだと暗記のような形で覚えていたが、仕組みごと理解することができた。
さらに、
①ブロック引数が一つ
②ブロック内で呼び出すメソッドに引数がない
③ブロック内で、ブロック引数に対してメソッドを一回呼び出す以外の処理がない
この場合に限り、以下のように&:メソッド
を使ってさらに簡潔に書くことが可能。
['ruby', 'java', 'php'].map { language| language.upcase } ↓ ['ruby', 'java', 'php'].map(&:upcase)
二つ目、三つ目の簡潔な書き方は、お手本をなぞって使ったことはあるが自主的に使ったことはないので覚えておきたい。
また、ブロック引数を使わない場合は、ブロック引数自体を省略できる。
mapメソッド
の効果も、なんか課題でよく使ったメソッドという印象を持っていたが、「各要素にブロックを評価した結果を新しく配列に返す」と今説明を見てぴんときた。
そして、mapメソッド
のエイリアスメソッドはcollectメソッド
ですという説明があったが、エイリアスってなんだ?となった。
Ruby のエイリアスメソッドはどれを使っても同じ? - Qiita
Ruby本でも前の方の章で説明してあったのに、単語を覚えず流してしまっていた...反省。
同じ意味を持つ別名のメソッドのことね。
範囲オブジェクト
範囲を表すオブジェクトのことを、範囲オブジェクトと呼ぶ。範囲オブジェクトはRangeクラスになる。
1..5
、a..e
のように、..
を使って作成する。
最後の値を含まない場合は、1...5
のように、...
を使う(知らなかった)。この例でいえば、1~4ということになる(1以上5未満)。
範囲オブジェクトそのものにメソッドを使用する場合は、範囲オブジェクトを()でくくること。
配列や文字列の一部を抜き出す
範囲オブジェクトを添字の代わりに渡すことで、指定した範囲の要素を取得できる。
これは知りたかった!
number = [1, 2, 3, 4, 5] number[0..2] #=>[1,2,3]
範囲オブジェクトから配列を作成
(1..5).to_a #=> [1, 2, 3, 4, 5] #*を使って複数の値を配列に展開するsplat展開というものもある。 [*1..5] #=> [1, 2, 3, 4, 5]
to_a
メソッドを利用して、配列を作成する。
他にも本当に多くの内容を学んだが、そのままここに書き記すのはいかがなものかと感じたため、自分用に簡潔なメモ程度で学習メモの部分に書き記しておく。
Ruby on Rails
昨日、なぜか削除、編集機能が使えなくて詰まっていたが、メンターの方に教えていただいて解決することができた。
class FoodsController < ApplicationController before_action :set_food, only: %i[edit update destroy] (省略) def set_food @food = current_user.foods.find(params[:id]) redirect_to root_path, alert: "権限がありません" end
このように書いていたが、set_foodメソッドの書き方がだめだったようで、
def set_food @food = current_user.foods.find_by(id: params[:id]) redirect_to root_path, alert: "権限がありません" if @food.nil? end
if @food.nil?
をつけるとエラーが起こらず、編集と削除機能が使えるようになった!
何気に@food = current_user.foods.find(params[:id])
の部分も間違っており、投稿した本人以外がアクセスできないように設定していたが、試しに他のuser_idを持つ投稿を編集してみようとしたらエラーメッセージが出ていた。
が、下の書き方にすることで解決。
これはメンターの人に聞いてよかった、聞かないと解決できなかったと思う。
明日以降はどんどん課題に取り組んでいきたい。
学習メモ
- 配列の取り出し方
配列[位置, 取得する長さ
負の値を使うと、最後から何番目か指定できる - 配列の連結は極力
+演算子
を使うこと - 配列の和集合 ...
|
を使い、二つの配列の要素をすべて合わせて、重複しないようにして返す - 配列の差集合 ...
-
を使い、左の配列から右の配列に含まれる要素を取り除く - 配列の積集合 ...
&
を使い、配列同士に共通する要素を返す -%記法 ...%w
を用いて文字列の配列を簡単に作成 式展開や改行文字を含めたい場合は大文字%W
- ミュータブルとイミュータブル ... mutableは「変更可能な」、immutableは「変更できない」
- シャドーイング ... 名前の重複により、ほかの変数やメソッドが参照できなくなること
- テスト駆動開発(TDD) ... テストコードから作成して、実際にプログラミングを行い都度リファクタリングを行うこと