Skip to content

wcコマンドを作成#10

Open
s-tone-gs wants to merge 25 commits intomainfrom
wc
Open

wcコマンドを作成#10
s-tone-gs wants to merge 25 commits intomainfrom
wc

Conversation

@s-tone-gs
Copy link
Copy Markdown
Owner

レビューお願いいたします

Copy link
Copy Markdown

@JunichiIto JunichiIto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コメントしました!

あと、実行結果のスクショを見ましたが、オリジナルのwcコマンドは数値が右寄せになっているので、ここもできたら見た目を合わせてほしいです〜。

y5i23hhoh6uy9c435cbolc2bd9kb

05.wc/wc.rb Outdated
display(totals, flags)
end

get_option_and_paths(ARGV) => { line:, word:, byte:, paths: }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

82-100行目はmainメソッドに入れてみてください〜。
https://qiita.com/jnchito/items/4b4cae54170cc2f4377e

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

05.wc/wc.rb Outdated
else
paths.each do |path|
outputs = {}
if File.directory?(path)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ディレクトリのケースって、スクショ載せてます?
https://bootcamp.fjord.jp/pages/write-code-write-test

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

載せていなかったので新しく追加しました

05.wc/wc.rb Outdated
{
line: File.read(path).lines.count,
word: File.read(path).split.count,
byte: File.size(path),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

byte: input.sizeの結果と数値が変わりそうですね。
同じ入力値に対しては同じ出力値が出るようにしてほしいです。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

05.wc/wc.rb Outdated
def build_file_output(path)
{
line: File.read(path).lines.count,
word: File.read(path).split.count,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

読み取り対象のファイルが巨大な場合、readを繰り返すとメモリの消費や実行時間が増えてしまいそうです。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

実行効率を上げるために修正にて修正しました!

05.wc/wc.rb Outdated
byte: File.size(path),
name: path
}
rescue Errno::ENOTDIR
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このあたりのエラー処理も実装したらエビデンスを残しておきたいですね。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

提出物の中にスクショを新しく追加しました!

05.wc/wc.rb Outdated

def display(outputs, flags)
# ループ処理にするとflagsとoutputsの要素の順番が同期する必要があるため、今後予期せぬバグに繋がると判断しこのように記述している。
outputs.delete(:line) unless flags[:line]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

引数を破壊的に変更するのは避けたいですね。
https://bootcamp.fjord.jp/pages/do-not-use-destructive-method

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

05.wc/wc.rb Outdated
def calculate_total(totals, outputs)
return totals if outputs.key?(:error)

totals[:line] += outputs[:line]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここも引数の内容を破壊的に変更しています

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown

@JunichiIto JunichiIto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

動画でレビューしたので別途リンクを送ります〜。

05.wc/wc.rb Outdated
return str_output.rjust(width) if key == :line || :word || :byte

str_output.ljust(width)
def calculate_output_width(text_metadata_collection)
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

入力に応じて動的に幅を計算するメソッドを追加し、後ほどのadjust_styleと組み合わせて右揃えのレイアウトを実現しました

05.wc/wc.rb Outdated
end
display_totals(totals, output_flags) if paths.length > 1
end
option_and_paths => { paths:, **option_flags }
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

パターンマッチの結果を分割代入し、output_flags = { line:, word:, byte: }で行われていた無駄な再定義を無くしました

05.wc/wc.rb Outdated
byte: input.size
}
def display(paths, option_flags)
text_metadata_collection =
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

元のstdinsoutputsにあたるもの命名をtext_metadata_collectionとしました


def build_directory_output(path)
def set_text_metadata(option_flags, message: nil, input: '', name: nil)
{
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build_stdin_outputbuild_file_outputの処理をset_text_metadataにて共通化しました

05.wc/wc.rb Outdated
}
def build_text_metadata(paths, option_flags)
text_metadata_collection = paths.map do |path|
if File.directory?(path)
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

例外処理で行っていたエラー処理をif文での実行に変えました

opt.on('-w') { |v| word = v }
opt.on('-c') { |v| byte = v }
paths = opt.parse(arguments)
paths = opt.parse(ARGV)
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ARGVを直接記述しました

05.wc/wc.rb Outdated
temporary[key] = (temporary[key] || 0) + data if %i[line_count word_count size].include?(key)
end
end
totals.merge(name: 'total')
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

破壊的変更が起こらないように修正しました

05.wc/wc.rb Outdated
end
end
if text_metadata_collection.length > 1
text_metadata_collection + [calculate_total(text_metadata_collection)]
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

破壊的変更を起こさないためにこのような記述になっています。

Copy link
Copy Markdown

@JunichiIto JunichiIto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今回も動画でレビューしたので別途リンクを送ります〜。

Copy link
Copy Markdown

@JunichiIto JunichiIto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コメントしました!

05.wc/wc.rb Outdated
if paths.empty?
[create_text_metadata(input: $stdin.read)]
else
build_text_metadata(paths)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create_text_metadataとbuild_text_metadata、名前だけ見ると、どちらも同じ機能を持つメソッドに見えますね。(createとbuildという動詞に大きな違いがない&目的語もtext_metadataで同じ)

実際は提供する機能(取得されるデータ)は異なるはずなので、もっと違いがわかる名前を付けたいなと思いました。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

命名を修正にて修正しました!

wcのWikipediaを参考にしました
https://en.wikipedia.org/wiki/Wc_(Unix)

05.wc/wc.rb Outdated
def main
option_and_paths => { paths:, **option_flags }
display(paths, option_flags)
paths, target_options = options_and_paths
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

options_and_pathsなら、その順番に合わせて

Suggested change
paths, target_options = options_and_paths
target_options, paths = options_and_paths

にする方がいいかも。

あと、target_は省略してもいいんじゃないでしょうか。

https://bootcamp.fjord.jp/pages/avoid-too-specific-var-name

Copy link
Copy Markdown
Owner Author

@s-tone-gs s-tone-gs Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

記事ありがとうございます!
返り値や引数の順番を修正にて修正しました!

05.wc/wc.rb Outdated
end
width = calculate_output_width(text_metadata_collection, target_options)
text_metadata_collection.each do |text_metadata|
render(target_options, text_metadata, width)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
render(target_options, text_metadata, width)
render(text_metadata, target_options, width)

text_metadataをrenderするのが主目的なので、text_metadataが最初の引数にある方がいいですね。
オプションの類いは引数の順番としては後ろの方に来ることが多いです。

Copy link
Copy Markdown
Owner Author

@s-tone-gs s-tone-gs Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

引数の順番にも意味があるのですね!ありがとうございます!
返り値や引数の順番を修正にて修正しました!

05.wc/wc.rb Outdated
Comment on lines +32 to +34
{ line_count: line, word_count: word, size: size }.map do |option, flag|
option if flag
end.compact
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{ line_count: line, word_count: word, size: size }.map do |option, flag|
option if flag
end.compact
{ line_count: line, word_count: word, size: size }.select { |_, v| v }.keys

こんな書き方もできます

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

select、keysのメソッドは初めて使いました!短く記述できて好みでした( ´∀` )
冗長であったため修正にて反映しました!

05.wc/wc.rb Outdated
opt.on('-w') { |v| word = v }
opt.on('-c') { |v| size = v }
paths = opt.parse(ARGV)
target_options =
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

データの中身を考えるとオプションというより、出力対象の項目名、っていう感じがしますね 🤔

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

命名を修正にて修正しました!

wcのWikipediaを参考にしました
https://en.wikipedia.org/wiki/Wc_(Unix)

05.wc/wc.rb Outdated
[paths, target_options]
end

def create_text_metadata(input:, name: nil)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def create_text_metadata(input:, name: nil)
def create_text_metadata(input, name = nil)

キーワード引数じゃなくてもいいんじゃないかなー、と思います
https://bootcamp.fjord.jp/pages/dont-abuse-keyword-args

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

05.wc/wc.rb Outdated
Comment on lines +52 to +56
if text_metadata_collection.length > 1
text_metadata_collection + [calculate_total(text_metadata_collection)]
else
text_metadata_collection
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if text_metadata_collection.length > 1
text_metadata_collection + [calculate_total(text_metadata_collection)]
else
text_metadata_collection
end
text_metadata_collection << calculate_total(text_metadata_collection) if paths.size > 1
text_metadata_collection

好みの問題ですが、こんなふうに書くのもありです

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

提示いただいた方が簡潔で好みでした!冗長であったため修正にて反映しました!

05.wc/wc.rb Outdated
Comment on lines +81 to +85
target_options.each do |option|
print "#{text_metadata[option].to_s.rjust(width)} "
end
print text_metadata[:name]
puts ''
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
target_options.each do |option|
print "#{text_metadata[option].to_s.rjust(width)} "
end
print text_metadata[:name]
puts ''
values = target_options.map do |option|
text_metadata[option].to_s.rjust(width)
end
puts [*values, text_metadata[:name]].join(' ')

みたいにするとちょっとスッキリするかも

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

冗長であったため修正にて反映しました!

Copy link
Copy Markdown

@JunichiIto JunichiIto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

いくつかコメントしましたが大きな問題ではないのでこれでOKです!🙆‍♂️

opt.on('-w') { |v| word = v }
opt.on('-c') { |v| size = v }
paths = opt.parse(ARGV)
column_names = [line, word, size].none? ? %i[line_count word_count size] : { line_count: line, word_count: word, size: size }.select { |_, v| v }.keys
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ちょっと横に長すぎる気がしますね。改行した方が読みやすいかも。

Suggested change
column_names = [line, word, size].none? ? %i[line_count word_count size] : { line_count: line, word_count: word, size: size }.select { |_, v| v }.keys
column_names = [line, word, size].none? ?
%i[line_count word_count size] :
{ line_count: line, word_count: word, size: size }.select { |_, v| v }.keys

end

def render(statistics, column_names, width)
filterd_statistics = column_names.map do |column_name|
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filterd -> filtered ですね。
ただ、filteredだと不要なデータを取り除くイメージです。
https://docs.ruby-lang.org/ja/latest/method/Array/i/filter.html

ここでやってるのは見た目の調整だと思うので、formatted とかの方が良さそうです

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants