【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]]

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

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

【Rubyでlsコマンド作成!(ロジック編)】

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

lsコマンドとは?

まずlsコマンドとは、簡単に説明するとファイルを一覧表示する他、オプションを使ってファイルの詳細情報を表示できたりするコマンド。

lsコマンドを作成する上でのロジック

自分の場合、ロジックは下記の通り

・まず、if文でオプションaのときに取得するファイルデータとそれ以外のオプションのファイルデータを条件分岐
・その後、オプションrとそれ以外のオプションのファイルデータを条件分岐

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

・ここからlオプションを実装。表示する各項目をメソッドに入れて、最後に項目をまとめてprint
・次にlオプション以外のオプションを実装。lオプション以外は表示条件がほぼ同じ。
・最後にopt.onで各オプションを設定して、lオプションまたはそれ以外のオプションで条件分岐させた。

options = {}
OptionParser.new do |opt|
  opt.on('-r') { |r| options[:r] = r }
  opt.on('-a') { |a| options[:a] = a }
  opt.on('-l') { |l| options[:l] = l }
  opt.parse!(ARGV)
end

options[:l] ? output_with_l_options(options) : output_without_l_options(options)

課題提出後、完成した他の生徒さんのコードを読ませていただいたが、それぞれロジックが違って面白かった😄
同じlsコマンドでも作者が違うと作成する過程が違うなんてRuby面白い!!!

【Blog Start!!!】

悔いのない人生を。

昨日33歳を迎え、気持ちを新たにBlog更新していきます!

2020年も残りわずか・・・。
今年は7月末に娘が産まれ、家族が3人になり環境が大きく変わりました。
仕事は8月から育児休暇中で、現在は育児をしながらフィヨルドブートキャンプでプログラミングを学習しています。

プログラミングを学ぼうと思ったきっかけは、 アナログな現在の職場をもっとITで円滑にしたい!そしてみんなに気持ち良く働いてもらいながら生産性を高めたい!という気持ちからです。「ない」のなら作ってしまえ!!!と思い新たに挑戦しています。

たった一度の人生なので悔いのないよう、また産まれた娘が自分の姿を見て、いくつになっても夢や目標を持ってもらえるよう現在もプログラミング学習継続中です。娘はまだ産まれたばかりですが、、(笑)

プログラミングで学んだ知識や他にも読書、生活のことなどをBlogでアウトプットしていけたらと思います。 よろしくお願いします!