こんにちは、moegi (@moegi_web) です。
フィヨルドブートキャンプではlsコマンドを作ろうという課題があるのですが、今回はオプションなしのlsコマンドを作ったときに学んだメソッドいろいろをまとめました。
ファイル系
ディレクトリ内のファイルを取得
Dir.glob('*')
再帰的にファイルを取得。ワイルドカードの展開を行い、パターンにマッチするファイル名を文字列の配列として返します。パターンにマッチするファイルがない場合は空の配列を返します。* 空文字列を含む任意の文字列と一致します。
配列系
取得した配列を並べる
.map
配列の要素の数だけブロック内で処理を繰り返して、新しい配列を返す。各要素に対してブロックを評価した結果を全て含む配列を返します。ブロックを省略した場合は Enumerator(each 以外のメソッドにも Enumerable の機能を提供するためのラッパークラス)を返します。
find_files.map { |file| file.size } → &:size
シンボルを使用した短縮記法
&:size の &
Proc オブジェクト(Ruby で使用できる関数のようなもの)を生成するためのもの。与えられたブロックを実行することができる。& を使って Proc オブジェクトを生成することを「シンボルを使用した書き方」
.max
最大の要素、もしくは最大の n 要素が降順に入った配列を返す。引数を指定しない形式では要素が存在しなければ nil を返します。引数を指定する形式では、空の配列を返します。
[]
ファイルのグループを格納するために使用されるため、コードの先頭で空の配列として作成。
区切る
each_slice(n)
n 要素ずつ区切ってブロックに渡して繰り返す。要素数が n で割り切れないときは、最後の回だけ要素数が減ります。
do |s|
ブロックを定義。ブロックは、Rubyでは、引数を受け取ることができる無名の関数のようなもの。
|s|
ブロックで使用する変数を定義。
追加する
files << s
配列 files の末尾に変数 s を追加。<< は、Rubyで配列に要素を追加するために使われる演算子。
.compact
自身から nil を取り除いた配列を生成して返す。
.values_at
引数で指定されたキーに対応する値の配列を返す。
.transpose
行列の転置(行と列の入れ換え)を行います。転置した配列を生成して返します。空の配列に対しては空の配列を生成して返します。
.each
Ruby の中で配列やハッシュなどのコレクションを処理するために使われるメソッド
文字列系
操作
.to_s
文字列に変換
.ljust
左寄せにする
.join
つなげる
割り算
割り算の結果を小数で出す
.to_f
端数は切り上げる
.ceil
変数
変数名NG集
file_list = Dir.glob('*')
listには配列の意味がある。特別な理由がない場合はfilesのように複数形にすることが一般的。
find_files = Dir.glob(‘*’)
find_files → files に変更。
動詞はメソッド。複数形で終わる名詞は配列。
数値の場合は「〜の数」とか「〜の件数」となるような名前を考える。
モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう – Qiita
file_list.each_slice(n).to_a
file_list → nested_files に変更。 [[1,2,3], [4,5,6]]のような入れ子(ネスト)した配列ができるため。
files = files.each do |a|
a → file_names に変更。aという変数名は中身が何かわからないので、変に省略しない。
プログラミング初心者は変数名やメソッド名を略さない方がいいよ、という話 – give IT a try
max = files.max_by(&:size).size
max → max_file_size に変更。
4行目にもmax_sizeという変数があって、名前だけ見るとどちらも同じ役割のように見えてしまいます。
違いがわかるような名前を付ける
max_value = file_list.map(&:size).max
max_value → max_file_size に変更。max_file_size、またはmax_file_lengthのような名前にすると、「長さである=つまり数値である」ということが伝わりやすくなる。
nested_row.each do |transposed_element|
nested_row → nested_files transposed_element → file_names に変更。
複数形.each do |単数形|
# …
end
ループ処理の場合は「配列は複数形、その中の各要素は単数形」と書くことがセオリー
変数名はfile_name、column_countのように a_bと書かれることが多い
数値を表すなら、size、length、countみたいな単語を使う
変数の寿命はできるだけ短くする
オブジェクトを作る」というときの「作る」はmakeよりもbuildの方がよく使われる
メソッド定義
メソッド定義の順番は特に決まったルールはないが、メソッドは呼ぶ側を手前に、呼ばれる側を後ろに定義する。
【新人プログラマ応援】メソッドは呼ぶ側を手前に、呼ばれる側を後ろに定義しよう
メソッドの責務(メソッドがやること)は1つに押さえた方がシンプルな実装かつ、再利用しやすいメソッドになる。
リファクタリング
files = []
find_files.each_slice(3) do |s|
files << s
end
↓
files = find_files.each_slice(3).to_a
(0..(transposed_file.size - 1)).each do |i|
hoge = transposed_file[i]
↓
transposed_file.each do |hoge|
その他注意点
*破壊的メソッドは予期せぬ不具合を生み出すので危険。プログラミング初心者の場合は原則として`!`なしの非破壊的バージョンを使う
まとめ
lsコマンド1を作ったときに学んだメソッドをまとめました。
コメント