【Rubyでlsコマンド作成!(リファクタリング編)】

現在、プログラミングを学んでいるフィヨルドブートキャンプでlsコマンドを作成するという課題が出たので学んだ内容をアウトプットしていきます。※lsコマンドをどこまで再現するかの条件あり(a,r,lのオプションは実装)

今回、メンターのかたにリファクタリングしていただきコードを修正いただいたので、アウトプットしていきます。

1. オプションごとにif文で条件分岐をしていると組み合わせ爆発が起きてしまう。

→パターンを見つけて、必要な箇所だけ条件分岐する。

リファクタリング

それぞれのオプションで条件を分岐して分けている。今後オプションが増えると大変なことに…

def file_list(options)
LIST1 = Dir.glob('*').sort
LIST2 = Dir.glob('*', File::FNM_DOTMATCH).sort
  if options[:a] && options[:r]
    Dir.glob('*', File::FNM_DOTMATCH).sort.reverse
    LIST2.reverse
  elsif options[:a]
    Dir.glob('*', File::FNM_DOTMATCH).sort
    LIST2
  elsif options[:r]
    Dir.glob('*').sort.reverse
  elsif options[:l] || options.empty?
    Dir.glob('*').sort
    LIST1.reverse
  else
    LIST1
  end
end

リファクタリング

最初に隠しファイルを取ってくるオプションaとそれ以外で条件分岐。 その後、取得したファイルをreverseするかで条件分岐。

def list_file_paths(options)
  file_names =
    if options[:a]
      Dir.glob('*', File::FNM_DOTMATCH)
    else
      Dir.glob('*')
    end
  if options[:r]
    file_names.sort.reverse
  else
    file_names.sort
  end
end

2. マジックナンバーは定数に入れる。

→誰が見ても何の数字かわかるようにする。

3. 空の配列を用意して、他のループ処理した結果を空の配列に詰め込んでいく場合、mapメソッドに置き換えられる。

空の配列を作成するVer.

(例)
numbers = [1, 2, 3, 4, 5]
new_numbers  = []
numbers.each { |n| new_numbers << n * 10 }
new_numbers #=> [10, 20, 30, 40, 50]

mapメソッドVer.

(例)
numbers = [1, 2, 3, 4, 5]
new_numbers = numbers.map { |n| n * 10 } 
new_numbers #=> [10, 20, 30, 40, 50]
4. 同じメソッドを何度も呼び出さない。

→処理に時間がかかってしまうため

5. 要素が合わない[[1, 2, 3], [4, 5, 6], [7, 8]]の配列を [[1, 4, 7], [2, 5, 8], [3, 6, nil]]という配列にしたいときは、zipメソッドに複数の引数を入れて作成できる。
(例)
a, b, c = [[1, 2, 3], [4, 5, 6], [7, 8]]
a.zip(b, c)
#=> [[1, 4, 7], [2, 5, 8], [3, 6, nil]]

lsコマンドだと配列(ファイル)の個数はいくつやってくるかわからない。。。

(例)
# lsコマンドの配列はこの状態に近い
file_array = [[1, 2, 3], [4, 5, 6], [7, 8]]

この場合は最初の要素と残りの要素で分ける。

(例)
first, *rest = file_array
first
#=> [1, 2, 3]
rest
#=> [[4, 5, 6], [7, 8]]

restsuplat展開させて引数に入れると、

(例)
first.zip(*rest)
#=> [[1, 4, 7], [2, 5, 8], [3, 6, nil]]

のように書くことができる。

修正、反省点が多々あってこれまでの課題で一番勉強になった課題でした😄
日々パワーアップしたい💪