Skip to content

lsコマンドオブジェクト指向版の提出#10

Open
thmz337 wants to merge 10 commits intomainfrom
my-ls_object
Open

lsコマンドオブジェクト指向版の提出#10
thmz337 wants to merge 10 commits intomainfrom
my-ls_object

Conversation

@thmz337
Copy link
Copy Markdown
Owner

@thmz337 thmz337 commented Jul 6, 2024

No description provided.

Copy link
Copy Markdown

@kaito0046 kaito0046 left a comment

Choose a reason for hiding this comment

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

クラス設計がそもそもうまくいっていない感じがあるので、もう一度オブジェクト指向について復習したうえで、クラス設計だけをまずはやり直していただくのがよさそうです。

Comment on lines +29 to +38
@stat = [
file_mode_text(raw_stat),
raw_stat.nlink.to_s,
Etc.getpwuid(raw_stat.uid).name,
Etc.getgrgid(raw_stat.gid).name,
raw_stat.size.to_s,
raw_stat.mtime.month.to_s,
raw_stat.mtime.day.to_s,
raw_stat.mtime.strftime('%H:%M')
]
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/class-like-class-and-non-class-like-class#%E3%82%AF%E3%83%A9%E3%82%B9%E5%90%8D%E3%81%A8%E5%90%8C%E5%90%8D%E3%81%AE%E5%A4%89%E6%95%B0%E3%82%92%E7%99%BB%E5%A0%B4%E3%81%95%E3%81%9B%E3%81%AA%E3%81%84 より:

クラス名と同名の変数がクラス内に登場する場合はたいてい設計や考え方をミスっている証拠なので、もう一度設計を考え直してみてください。

FileStat クラスは上記に該当すると思います(FileStat と @stat で厳密には同名ではありませんが、同じとみなせるかと)。


require_relative 'file_stat'

class LS
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LS という概念は、オブジェクト指向版に変更する前にあったもともとの処理を押し込めるために独自に導き出されたものに見えます。
ボウリングのスコア計算プログラムをオブジェクト指向にアレンジしたときのことを思い出していただきたいです。あのプラクティスではプログラム中に登場する概念(登場人物)をうまく見出して、インスタンス同士のやり取りに上手に落とし込めていたと思います。現状、このプラクティスでは、そういった概念設定(モデリングといいます)にそもそも失敗してる感じがあるんですよね。
登場人物には(プログラム中にしか出てこない創作の概念ではなく)一般的に世に知られる具体的なモノのみを用いる、という制限を設けてみるとよいかもしれません。lsコマンドの処理には、どのような登場人物が出てくるでしょうか?

※モデリングに失敗した状態でプログラムを書いてもうまくいきませんし、具体的なプログラムを書いてからモデリングをやり直すのは修正コストが高いので、まずはクラス図か箇条書きリストの作成だけしてから再レビュー依頼をしていただくのがよいかもしれません

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

  • このファイルが持っている処理がまだ多すぎるように見えます 👀 基本的にはすべての処理は何らかのクラスに持たせることができるはずだからです。このファイルは「何らかのクラスに対して処理を一度呼び、表示すべき文字列(lsコマンドの結果として表示すべき形式になったファイル一覧)を取得する」「その文字列を puts する」というくらいが妥当です。

Comment on lines +30 to +39
@stat = [
file_mode_text(raw_stat),
raw_stat.nlink.to_s,
Etc.getpwuid(raw_stat.uid).name,
Etc.getgrgid(raw_stat.gid).name,
raw_stat.size.to_s,
raw_stat.mtime.month.to_s,
raw_stat.mtime.day.to_s,
raw_stat.mtime.strftime('%H:%M')
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LsFile という「ファイル」を模したオブジェクトなので、理想としては @stats で配列でまとめて情報が返ってくるよりも、file_mode nilnk など個別の情報をそれぞれオブジェクトのフィールドとして持っている方が、実際の「ファイル」に近いので読み手が理解しやすくなると思います。
今回の要件では結局のところ配列に展開して文字列にするだけなのでこの書き方でも十分と言えば十分なのですが、プログラム上でオブジェクトを作ってそいつに処理を持たせて扱うという趣旨から考えると、実際に存在する概念になぞらえて作ったオブジェクトならば、(やりすぎない、無理のない範囲で)実態に沿って属性を定義したほうが理解しやすいコードになります。

lsのメインの処理を、file_listに移動。
Copy link
Copy Markdown

@kaito0046 kaito0046 left a comment

Choose a reason for hiding this comment

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

実行してみたら file_list.rb:33: syntax error, unexpected ')' (SyntaxError) ...atrix(max_column, long_format:).map { |m| m.join.rstrip!.con... になりました。
お手元でも同様でしょうか?

Comment on lines +10 to +25
options = OptionParser.new do |opts|
opts.banner = 'Usage: ./ls.rb [options]'

opts.on('-a', 'Include directory entries whose names begin with a dot (‘.’).')
opts.on('-r', 'Display files in reverse order.')
opts.on('-l', 'List files in the long format.')
end

begin
params = {}
options.parse!(ARGV, into: params)
rescue OptionParser::ParseError => e
puts e.message
puts options.help
exit
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.

オプションもクラスに切り出してみるとよいかもしれません。

Comment on lines +27 to +30
max_column = params.include?(:l) ? 1 : 3

file_names = params.include?(:a) ? Dir.glob('*', File::FNM_DOTMATCH) : Dir.glob('*')
file_names.reverse! if params.include?(:r)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

file_names の取得も LS::FileList に任せましょう。

@thmz337
Copy link
Copy Markdown
Owner Author

thmz337 commented Nov 23, 2024

@kaito0046

実行してみたら file_list.rb:33: syntax error, unexpected ')' (SyntaxError) ...atrix(max_column, long_format:).map { |m| m.join.rstrip!.con... になりました。 お手元でも同様でしょうか?

私の方ではエラーが出ないようです。rubyのバージョンは以下の通りです。
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin23]

@kaito0046
Copy link
Copy Markdown

@thmz337
失礼しました、SyntaxError は私の手元がおかしかったようです 🙇
しかし、 l オプションつきではやはりエラーが出てしまいます。何度もすみませんが、お手元でも同様かお教えください。

file_list.rb:30:in `block (2 levels) in current_directory_stats': undefined local variable or method `_1' for #<LS::FileList:0x000000014c868bf0> (NameError)
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:29:in `map'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:29:in `with_index'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:29:in `block in current_directory_stats'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:28:in `map'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:28:in `with_index'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:28:in `current_directory_stats'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:47:in `matrix'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:39:in `show'
        from ../scripts/ls.rb:14:in `<main>'

@kaito0046
Copy link
Copy Markdown

上記の点以外はよさそうに思いました。

@thmz337
Copy link
Copy Markdown
Owner Author

thmz337 commented Nov 28, 2024

@thmz337 失礼しました、SyntaxError は私の手元がおかしかったようです 🙇 しかし、 l オプションつきではやはりエラーが出てしまいます。何度もすみませんが、お手元でも同様かお教えください。

file_list.rb:30:in `block (2 levels) in current_directory_stats': undefined local variable or method `_1' for #<LS::FileList:0x000000014c868bf0> (NameError)
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:29:in `map'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:29:in `with_index'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:29:in `block in current_directory_stats'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:28:in `map'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:28:in `with_index'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:28:in `current_directory_stats'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:47:in `matrix'
        from /Users/kaitofukai/Workspace/ls_normal/scripts/file_list.rb:39:in `show'
        from ../scripts/ls.rb:14:in `<main>'

こちら確認しましたが、私の方で-l オプションをつけて実行してもエラーは出ない状況です。

Copy link
Copy Markdown

@kaito0046 kaito0046 left a comment

Choose a reason for hiding this comment

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

本当にすみません、改めて rbenv install しなおしてバージョンを揃えたら要件通りに動作しました!何度もやりとりさせてしまい申し訳ありませんでした 🙇

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