From 348d7129567eebf7c0356329c29e5af64fbff925 Mon Sep 17 00:00:00 2001 From: shoma Date: Wed, 3 Dec 2025 16:51:15 +0900 Subject: [PATCH 01/17] =?UTF-8?q?=E3=82=AA=E3=83=96=E3=82=B8=E3=82=A7?= =?UTF-8?q?=E3=82=AF=E3=83=88=E6=8C=87=E5=90=91=E3=81=A7ls=E3=82=B3?= =?UTF-8?q?=E3=83=9E=E3=83=B3=E3=83=89=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/common_ls_method.rb | 28 +++++++++++++++ 07.ls_object/default_ls.rb | 17 +++++++++ 07.ls_object/file.rb | 61 ++++++++++++++++++++++++++++++++ 07.ls_object/get_files.rb | 10 ++++++ 07.ls_object/list_ls.rb | 56 +++++++++++++++++++++++++++++ 07.ls_object/ls.rb | 18 ++++++++++ 07.ls_object/ls_class.rb | 23 ++++++++++++ 7 files changed, 213 insertions(+) create mode 100644 07.ls_object/common_ls_method.rb create mode 100644 07.ls_object/default_ls.rb create mode 100644 07.ls_object/file.rb create mode 100644 07.ls_object/get_files.rb create mode 100644 07.ls_object/list_ls.rb create mode 100644 07.ls_object/ls.rb create mode 100644 07.ls_object/ls_class.rb diff --git a/07.ls_object/common_ls_method.rb b/07.ls_object/common_ls_method.rb new file mode 100644 index 0000000000..31cc9720fa --- /dev/null +++ b/07.ls_object/common_ls_method.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module CommonLsMethod + private + + def sort_to_matrix(row_count, column_count, files) + (0...row_count).map do |i| + index_to_row_value = i + (0...column_count).map do + index_to_target = index_to_row_value + index_to_row_value += row_count + files[index_to_target] + end.compact + end + end + + def generate_rows(matrixed_files, width) + matrixed_files.map do |files| + generate_row(files, width) + end.join("\n") + end + + def generate_row(files, width) + files.map do |file| + files.last.equal?(file) ? file.name : file.name.ljust(width) + end.join + end +end diff --git a/07.ls_object/default_ls.rb b/07.ls_object/default_ls.rb new file mode 100644 index 0000000000..890918b8fa --- /dev/null +++ b/07.ls_object/default_ls.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative 'ls_class' +require_relative 'common_ls_method' + +class DefaultLs < Ls + include CommonLsMethod + def initialize(files) + super(files) + @matrixed_files = sort_to_matrix(@row_count, column_count, files) + @name_width = files.map { |file| file.name.length }.max + 1 + end + + def generate + generate_rows(@matrixed_files, @name_width) + end +end diff --git a/07.ls_object/file.rb b/07.ls_object/file.rb new file mode 100644 index 0000000000..db32bc464c --- /dev/null +++ b/07.ls_object/file.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module My + class File + FILE_TYPES = { + '04' => 'd', + '10' => '-', + '12' => 'l' + }.freeze + PERMISSIONS = { + '7' => 'rwx', + '6' => 'rw-', + '5' => 'r-x', + '4' => 'r--', + '3' => '-wx', + '2' => '-w-', + '1' => '--x', + '0' => '---' + }.freeze + + attr_reader :name + + private_constant :FILE_TYPES, :PERMISSIONS + + def initialize(name) + @name = name + @state = ::File.stat(name) + end + + def str_mode + int_mode = @state.mode.to_s(8).rjust(6, '0') + FILE_TYPES[int_mode[0..1]] + int_mode[3..5].chars.map { |mode| PERMISSIONS[mode] }.join + end + + def nlink + @state.nlink + end + + def owner + uid = @state.uid + Etc.getpwuid(uid) + end + + def group + gid = @state.gid + Etc.getgrgid(gid) + end + + def size + @state.size.to_s + end + + def blocks + @state.blocks + end + + def mtime + @state.mtime.strftime('%b %d %H:%M').to_s + end + end +end diff --git a/07.ls_object/get_files.rb b/07.ls_object/get_files.rb new file mode 100644 index 0000000000..d66dfc07f5 --- /dev/null +++ b/07.ls_object/get_files.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require_relative 'file' + +def get_files(all, reverse) + flags = all ? File::FNM_DOTMATCH : 0 + files = Dir.glob('*', flags).map { |file_name| My::File.new(file_name) } + asc_order_files = files.sort_by(&:name) + reverse ? asc_order_files.reverse : asc_order_files +end diff --git a/07.ls_object/list_ls.rb b/07.ls_object/list_ls.rb new file mode 100644 index 0000000000..b4ca94629e --- /dev/null +++ b/07.ls_object/list_ls.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require_relative 'ls_class' +require_relative 'common_ls_method' + +class ListLs < Ls + include CommonLsMethod + def initialize(files) + super(files) + @matrixed_files = sort_to_matrix(@row_count, column_count, files) + # rubyは1ブロックを512バイト、Linuxは1ブロックを1024で計算しているため、2で割っている + @total_block_size = files.map { |file| file.blocks.div(2) }.sum + @widths = calc_widths(files) + end + + def generate + [ + "total #{@total_block_size}", + generate_rows(@matrixed_files, @widths) + ].join("\n") + end + + private + + def generate_row(files, widths) + # -lオプションが有効な時は必ず一列になるため、このように取得する + file = files[0] + [ + file.str_mode, + file.nlink.to_s.rjust(widths[:nlink]), + file.owner.name.rjust(widths[:owner]), + file.group.name.rjust(widths[:group]), + file.size.rjust(widths[:size]), + file.mtime.rjust(widths[:mtime]), + ' ', + file.name + ].join + end + + def column_count + 1 + end + + def calc_widths(files) + widths = Hash.new { |hash, key| hash[key] = [] } + files.each do |f| + widths[:owner].push(f.owner.name.length) + widths[:group].push(f.group.name.length) + widths[:nlink].push(f.nlink.to_s.length) + widths[:size].push(f.size.length) + widths[:mtime].push(f.mtime.length) + widths[:name].push(f.name.length) + end + widths.transform_values { |widths| widths.max + 1 } + end +end diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb new file mode 100644 index 0000000000..e461586232 --- /dev/null +++ b/07.ls_object/ls.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'optparse' +require_relative 'get_files' +require_relative 'default_ls' +require_relative 'list_ls' + +opt = OptionParser.new +all = false +reverse = false +list = false +opt.on('-a') { |v| all = v } +opt.on('-r') { |v| reverse = v } +opt.on('-l') { |v| list = v } +opt.parse(ARGV) + +files = get_files(all, reverse) +puts list ? ListLs.generate(files) : DefaultLs.generate(files) diff --git a/07.ls_object/ls_class.rb b/07.ls_object/ls_class.rb new file mode 100644 index 0000000000..bbef16440a --- /dev/null +++ b/07.ls_object/ls_class.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'debug' + +class Ls + def initialize(files) + @row_count = files.count.ceildiv(column_count) + end + + def self.generate(files) + new(files).generate + end + + private + + def column_count + 3 + end + + def generate + raise NotImplementedError + end +end From af023c0135caa37238714ed06a55a45985359bdf Mon Sep 17 00:00:00 2001 From: shoma Date: Wed, 3 Dec 2025 16:51:36 +0900 Subject: [PATCH 02/17] =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/test/abc.txt | 1 + 07.ls_object/test/file_a.txt | 1 + 07.ls_object/test/file_b.txt | 2 + 07.ls_object/test/file_c.txt | 0 07.ls_object/test/file_d.txt | 0 07.ls_object/test/file_e.txt | 0 07.ls_object/test/file_f.txt | 0 07.ls_object/test/test_ls.rb | 145 +++++++++++++++++++++++++++++++++++ 8 files changed, 149 insertions(+) create mode 100644 07.ls_object/test/abc.txt create mode 100644 07.ls_object/test/file_a.txt create mode 100644 07.ls_object/test/file_b.txt create mode 100644 07.ls_object/test/file_c.txt create mode 100644 07.ls_object/test/file_d.txt create mode 100644 07.ls_object/test/file_e.txt create mode 100644 07.ls_object/test/file_f.txt create mode 100644 07.ls_object/test/test_ls.rb diff --git a/07.ls_object/test/abc.txt b/07.ls_object/test/abc.txt new file mode 100644 index 0000000000..44d5a7b33b --- /dev/null +++ b/07.ls_object/test/abc.txt @@ -0,0 +1 @@ +この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大き diff --git a/07.ls_object/test/file_a.txt b/07.ls_object/test/file_a.txt new file mode 100644 index 0000000000..038abb698b --- /dev/null +++ b/07.ls_object/test/file_a.txt @@ -0,0 +1 @@ +ダミーです diff --git a/07.ls_object/test/file_b.txt b/07.ls_object/test/file_b.txt new file mode 100644 index 0000000000..e861f0d264 --- /dev/null +++ b/07.ls_object/test/file_b.txt @@ -0,0 +1,2 @@ +あなたの名前は何ですか +私の名前は diff --git a/07.ls_object/test/file_c.txt b/07.ls_object/test/file_c.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/file_d.txt b/07.ls_object/test/file_d.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/file_e.txt b/07.ls_object/test/file_e.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/file_f.txt b/07.ls_object/test/file_f.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb new file mode 100644 index 0000000000..05c13d3510 --- /dev/null +++ b/07.ls_object/test/test_ls.rb @@ -0,0 +1,145 @@ +# frozen_string_literal: true + +require 'minitest/autorun' +require_relative '../ls_class' +require_relative '../get_files' +require_relative '../default_ls' +require_relative '../list_ls' + +class LsTest < Minitest::Test + def test_default + expected = <<~LIST.chomp + abc.txt file_c.txt file_f.txt + file_a.txt file_d.txt test_ls.rb + file_b.txt file_e.txt + LIST + all = false + reverse = false + files = get_files(all, reverse) + ls_content = DefaultLs.generate(files) + assert_equal expected, ls_content + end + + def test_all + expected = <<~LIST.chomp + . file_b.txt file_e.txt + abc.txt file_c.txt file_f.txt + file_a.txt file_d.txt test_ls.rb + LIST + all = true + reverse = false + files = get_files(all, reverse) + ls_content = DefaultLs.generate(files) + assert_equal expected, ls_content + end + + def test_reverse + expected = <<~LIST.chomp + test_ls.rb file_d.txt file_a.txt + file_f.txt file_c.txt abc.txt + file_e.txt file_b.txt + LIST + all = false + reverse = true + files = get_files(all, reverse) + ls_content = DefaultLs.generate(files) + assert_equal expected, ls_content + end + + def test_list + file = My::File.new('test_ls.rb') + expected = <<~LIST.chomp + total 20 + -rw-r--r-- 1 s-tone s-tone 3001 Dec 03 14:54 abc.txt + -rw-r--r-- 1 s-tone s-tone 16 Dec 03 14:57 file_a.txt + -rw-r--r-- 1 s-tone s-tone 50 Dec 03 14:57 file_b.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_c.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_d.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_e.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_f.txt + -rw-r--r-- 1 s-tone s-tone #{file.size} #{file.mtime} test_ls.rb + LIST + all = false + reverse = false + files = get_files(all, reverse) + ls_content = ListLs.generate(files) + assert_equal expected, ls_content + end + + def test_all_reverse + expected = <<~LIST.chomp + test_ls.rb file_d.txt file_a.txt + file_f.txt file_c.txt abc.txt + file_e.txt file_b.txt . + LIST + all = true + reverse = true + files = get_files(all, reverse) + ls_content = DefaultLs.generate(files) + assert_equal expected, ls_content + end + + def test_all_list + file = My::File.new('test_ls.rb') + current_directory = My::File.new('.') + expected = <<~LIST.chomp + total 24 + drwxr-xr-x 2 s-tone s-tone #{current_directory.size} #{current_directory.mtime} . + -rw-r--r-- 1 s-tone s-tone 3001 Dec 03 14:54 abc.txt + -rw-r--r-- 1 s-tone s-tone 16 Dec 03 14:57 file_a.txt + -rw-r--r-- 1 s-tone s-tone 50 Dec 03 14:57 file_b.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_c.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_d.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_e.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_f.txt + -rw-r--r-- 1 s-tone s-tone #{file.size} #{file.mtime} test_ls.rb + LIST + all = true + reverse = false + files = get_files(all, reverse) + ls_content = ListLs.generate(files) + assert_equal expected, ls_content + end + + def test_reverse_list + file = My::File.new('test_ls.rb') + expected = <<~LIST.chomp + total 20 + -rw-r--r-- 1 s-tone s-tone #{file.size} #{file.mtime} test_ls.rb + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_f.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_e.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_d.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_c.txt + -rw-r--r-- 1 s-tone s-tone 50 Dec 03 14:57 file_b.txt + -rw-r--r-- 1 s-tone s-tone 16 Dec 03 14:57 file_a.txt + -rw-r--r-- 1 s-tone s-tone 3001 Dec 03 14:54 abc.txt + LIST + all = false + reverse = true + files = get_files(all, reverse) + ls_content = ListLs.generate(files) + assert_equal expected, ls_content + end + + def test_reverse_list_all + file = My::File.new('test_ls.rb') + current_directory = My::File.new('.') + expected = <<~LIST.chomp + total 24 + -rw-r--r-- 1 s-tone s-tone #{file.size} #{file.mtime} test_ls.rb + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_f.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_e.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_d.txt + -rw-r--r-- 1 s-tone s-tone 0 Dec 03 14:56 file_c.txt + -rw-r--r-- 1 s-tone s-tone 50 Dec 03 14:57 file_b.txt + -rw-r--r-- 1 s-tone s-tone 16 Dec 03 14:57 file_a.txt + -rw-r--r-- 1 s-tone s-tone 3001 Dec 03 14:54 abc.txt + drwxr-xr-x 2 s-tone s-tone #{current_directory.size} #{current_directory.mtime} . + LIST + all = true + reverse = true + files = get_files(all, reverse) + ls_content = ListLs.generate(files) + assert_equal expected, ls_content + end +end From b5ae272948a8f34b3b14d43b46e18249bb24a7c5 Mon Sep 17 00:00:00 2001 From: shoma Date: Wed, 3 Dec 2025 18:04:44 +0900 Subject: [PATCH 03/17] =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?=E3=81=AE=E6=8C=99=E5=8B=95=E3=81=A8=E5=91=BD=E5=90=8D=E3=81=8C?= =?UTF-8?q?=E3=81=82=E3=81=A3=E3=81=A6=E3=81=84=E3=81=AA=E3=81=8B=E3=81=A3?= =?UTF-8?q?=E3=81=9F=E3=81=9F=E3=82=81=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/common_ls_method.rb | 2 +- 07.ls_object/default_ls.rb | 2 +- 07.ls_object/list_ls.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/07.ls_object/common_ls_method.rb b/07.ls_object/common_ls_method.rb index 31cc9720fa..898e7cbe2d 100644 --- a/07.ls_object/common_ls_method.rb +++ b/07.ls_object/common_ls_method.rb @@ -3,7 +3,7 @@ module CommonLsMethod private - def sort_to_matrix(row_count, column_count, files) + def build_matrix(row_count, column_count, files) (0...row_count).map do |i| index_to_row_value = i (0...column_count).map do diff --git a/07.ls_object/default_ls.rb b/07.ls_object/default_ls.rb index 890918b8fa..0b328d13ac 100644 --- a/07.ls_object/default_ls.rb +++ b/07.ls_object/default_ls.rb @@ -7,7 +7,7 @@ class DefaultLs < Ls include CommonLsMethod def initialize(files) super(files) - @matrixed_files = sort_to_matrix(@row_count, column_count, files) + @matrixed_files = build_matrix(@row_count, column_count, files) @name_width = files.map { |file| file.name.length }.max + 1 end diff --git a/07.ls_object/list_ls.rb b/07.ls_object/list_ls.rb index b4ca94629e..08474e87b7 100644 --- a/07.ls_object/list_ls.rb +++ b/07.ls_object/list_ls.rb @@ -7,7 +7,7 @@ class ListLs < Ls include CommonLsMethod def initialize(files) super(files) - @matrixed_files = sort_to_matrix(@row_count, column_count, files) + @matrixed_files = build_matrix(@row_count, column_count, files) # rubyは1ブロックを512バイト、Linuxは1ブロックを1024で計算しているため、2で割っている @total_block_size = files.map { |file| file.blocks.div(2) }.sum @widths = calc_widths(files) From c78d1df03b0d131194c14ce636619d8c183db88c Mon Sep 17 00:00:00 2001 From: shoma Date: Sat, 6 Dec 2025 17:01:38 +0900 Subject: [PATCH 04/17] =?UTF-8?q?=E8=A6=81=E7=B4=A0=E3=81=AE=E5=B9=85?= =?UTF-8?q?=E3=81=A8=E3=81=97=E8=A6=81=E7=B4=A0=E9=96=93=E3=81=AE=E7=A9=BA?= =?UTF-8?q?=E7=99=BD=E3=81=AE=E5=B9=85=E3=82=82=E5=90=AB=E3=81=BE=E3=82=8C?= =?UTF-8?q?=E3=81=A6=E3=81=84=E3=81=9F=E3=81=AE=E3=81=A7=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/common_ls_method.rb | 2 +- 07.ls_object/default_ls.rb | 2 +- 07.ls_object/list_ls.rb | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/07.ls_object/common_ls_method.rb b/07.ls_object/common_ls_method.rb index 898e7cbe2d..97c4bc73c8 100644 --- a/07.ls_object/common_ls_method.rb +++ b/07.ls_object/common_ls_method.rb @@ -23,6 +23,6 @@ def generate_rows(matrixed_files, width) def generate_row(files, width) files.map do |file| files.last.equal?(file) ? file.name : file.name.ljust(width) - end.join + end.join(' ') end end diff --git a/07.ls_object/default_ls.rb b/07.ls_object/default_ls.rb index 0b328d13ac..f4b09a84fe 100644 --- a/07.ls_object/default_ls.rb +++ b/07.ls_object/default_ls.rb @@ -8,7 +8,7 @@ class DefaultLs < Ls def initialize(files) super(files) @matrixed_files = build_matrix(@row_count, column_count, files) - @name_width = files.map { |file| file.name.length }.max + 1 + @name_width = files.map { |file| file.name.length }.max end def generate diff --git a/07.ls_object/list_ls.rb b/07.ls_object/list_ls.rb index 08474e87b7..5572b9374c 100644 --- a/07.ls_object/list_ls.rb +++ b/07.ls_object/list_ls.rb @@ -32,9 +32,8 @@ def generate_row(files, widths) file.group.name.rjust(widths[:group]), file.size.rjust(widths[:size]), file.mtime.rjust(widths[:mtime]), - ' ', file.name - ].join + ].join(' ') end def column_count @@ -51,6 +50,6 @@ def calc_widths(files) widths[:mtime].push(f.mtime.length) widths[:name].push(f.name.length) end - widths.transform_values { |widths| widths.max + 1 } + widths.transform_values { |widths| widths.max } end end From 7add53d0ec85f1f84ae731409f349a2573aaa614 Mon Sep 17 00:00:00 2001 From: shoma Date: Sat, 6 Dec 2025 17:09:28 +0900 Subject: [PATCH 05/17] =?UTF-8?q?l=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E3=81=AE=E5=BD=B9=E5=89=B2=E3=81=A8=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E3=81=AB=E3=81=9A=E3=82=8C=E3=81=8C=E3=81=82=E3=81=A3=E3=81=9F?= =?UTF-8?q?=E3=81=9F=E3=82=81=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/{list_ls.rb => long_format_ls.rb} | 2 +- 07.ls_object/ls.rb | 8 ++++---- 07.ls_object/test/test_ls.rb | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) rename 07.ls_object/{list_ls.rb => long_format_ls.rb} (98%) diff --git a/07.ls_object/list_ls.rb b/07.ls_object/long_format_ls.rb similarity index 98% rename from 07.ls_object/list_ls.rb rename to 07.ls_object/long_format_ls.rb index 5572b9374c..8f03ad06a1 100644 --- a/07.ls_object/list_ls.rb +++ b/07.ls_object/long_format_ls.rb @@ -3,7 +3,7 @@ require_relative 'ls_class' require_relative 'common_ls_method' -class ListLs < Ls +class LongFormatLs < Ls include CommonLsMethod def initialize(files) super(files) diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index e461586232..c9d21f23d9 100644 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -3,16 +3,16 @@ require 'optparse' require_relative 'get_files' require_relative 'default_ls' -require_relative 'list_ls' +require_relative 'long_format_ls' opt = OptionParser.new all = false reverse = false -list = false +long_format = false opt.on('-a') { |v| all = v } opt.on('-r') { |v| reverse = v } -opt.on('-l') { |v| list = v } +opt.on('-l') { |v| long_format = v } opt.parse(ARGV) files = get_files(all, reverse) -puts list ? ListLs.generate(files) : DefaultLs.generate(files) +puts long_format ? LongFormatLs.generate(files) : DefaultLs.generate(files) diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb index 05c13d3510..62d8fc9225 100644 --- a/07.ls_object/test/test_ls.rb +++ b/07.ls_object/test/test_ls.rb @@ -4,7 +4,7 @@ require_relative '../ls_class' require_relative '../get_files' require_relative '../default_ls' -require_relative '../list_ls' +require_relative '../long_format_ls' class LsTest < Minitest::Test def test_default @@ -62,7 +62,7 @@ def test_list all = false reverse = false files = get_files(all, reverse) - ls_content = ListLs.generate(files) + ls_content = LongFormatLs.generate(files) assert_equal expected, ls_content end @@ -97,7 +97,7 @@ def test_all_list all = true reverse = false files = get_files(all, reverse) - ls_content = ListLs.generate(files) + ls_content = LongFormatLs.generate(files) assert_equal expected, ls_content end @@ -117,7 +117,7 @@ def test_reverse_list all = false reverse = true files = get_files(all, reverse) - ls_content = ListLs.generate(files) + ls_content = LongFormatLs.generate(files) assert_equal expected, ls_content end @@ -139,7 +139,7 @@ def test_reverse_list_all all = true reverse = true files = get_files(all, reverse) - ls_content = ListLs.generate(files) + ls_content = LongFormatLs.generate(files) assert_equal expected, ls_content end end From b28b6d4a4c5ac135bf0592aa348d869f3c845ea1 Mon Sep 17 00:00:00 2001 From: shoma Date: Sat, 6 Dec 2025 17:20:30 +0900 Subject: [PATCH 06/17] =?UTF-8?q?=E8=A6=AA=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AEls=E3=81=8C=E5=85=B7=E4=BD=93=E7=9A=84=E3=81=AA?= =?UTF-8?q?=E5=80=A4=E3=82=92=E6=8C=81=E3=81=A4=E3=81=AE=E3=81=8C=E4=B8=8D?= =?UTF-8?q?=E8=87=AA=E7=84=B6=E3=81=A7=E3=81=82=E3=81=A3=E3=81=9F=E3=81=9F?= =?UTF-8?q?=E3=82=81=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/default_ls.rb | 4 ++++ 07.ls_object/ls_class.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/07.ls_object/default_ls.rb b/07.ls_object/default_ls.rb index f4b09a84fe..b821578a34 100644 --- a/07.ls_object/default_ls.rb +++ b/07.ls_object/default_ls.rb @@ -11,6 +11,10 @@ def initialize(files) @name_width = files.map { |file| file.name.length }.max end + def column_count + 3 + end + def generate generate_rows(@matrixed_files, @name_width) end diff --git a/07.ls_object/ls_class.rb b/07.ls_object/ls_class.rb index bbef16440a..3b90dd9396 100644 --- a/07.ls_object/ls_class.rb +++ b/07.ls_object/ls_class.rb @@ -14,7 +14,7 @@ def self.generate(files) private def column_count - 3 + raise NotImplementedError end def generate From 81cc5bf406a7cf92a684b5d16c8148ad6fdabd79 Mon Sep 17 00:00:00 2001 From: shoma Date: Sat, 6 Dec 2025 19:30:43 +0900 Subject: [PATCH 07/17] =?UTF-8?q?=E3=83=A2=E3=82=B8=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E3=83=AB=E3=81=A7=E5=88=87=E3=82=8A=E5=87=BA=E3=81=97=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=9F=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=8C?= =?UTF-8?q?ls=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AB=E5=8C=85=E6=8B=AC?= =?UTF-8?q?=E3=81=95=E3=82=8C=E3=82=8B=E3=81=A8=E5=88=A4=E6=96=AD=E3=81=97?= =?UTF-8?q?=E3=81=A6=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF=E3=83=AA?= =?UTF-8?q?=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/common_ls_method.rb | 28 ----------------------- 07.ls_object/default_ls.rb | 17 +++++--------- 07.ls_object/long_format_ls.rb | 28 ++++++++--------------- 07.ls_object/ls_class.rb | 39 ++++++++++++++++++++++++++++---- 07.ls_object/test/test_ls.rb | 6 ++--- 5 files changed, 53 insertions(+), 65 deletions(-) delete mode 100644 07.ls_object/common_ls_method.rb diff --git a/07.ls_object/common_ls_method.rb b/07.ls_object/common_ls_method.rb deleted file mode 100644 index 97c4bc73c8..0000000000 --- a/07.ls_object/common_ls_method.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module CommonLsMethod - private - - def build_matrix(row_count, column_count, files) - (0...row_count).map do |i| - index_to_row_value = i - (0...column_count).map do - index_to_target = index_to_row_value - index_to_row_value += row_count - files[index_to_target] - end.compact - end - end - - def generate_rows(matrixed_files, width) - matrixed_files.map do |files| - generate_row(files, width) - end.join("\n") - end - - def generate_row(files, width) - files.map do |file| - files.last.equal?(file) ? file.name : file.name.ljust(width) - end.join(' ') - end -end diff --git a/07.ls_object/default_ls.rb b/07.ls_object/default_ls.rb index b821578a34..43479e561b 100644 --- a/07.ls_object/default_ls.rb +++ b/07.ls_object/default_ls.rb @@ -1,21 +1,16 @@ # frozen_string_literal: true require_relative 'ls_class' -require_relative 'common_ls_method' class DefaultLs < Ls - include CommonLsMethod + COLUMN_COUNT = 3 def initialize(files) - super(files) - @matrixed_files = build_matrix(@row_count, column_count, files) - @name_width = files.map { |file| file.name.length }.max + name_width = files.map { |file| file.name.length }.max + content_widths = { name: name_width } + super(files, COLUMN_COUNT, content_widths) end - def column_count - 3 - end - - def generate - generate_rows(@matrixed_files, @name_width) + def generate_content(file) + file.name.ljust(@content_widths[:name]) end end diff --git a/07.ls_object/long_format_ls.rb b/07.ls_object/long_format_ls.rb index 8f03ad06a1..699de6976a 100644 --- a/07.ls_object/long_format_ls.rb +++ b/07.ls_object/long_format_ls.rb @@ -1,45 +1,37 @@ # frozen_string_literal: true require_relative 'ls_class' -require_relative 'common_ls_method' class LongFormatLs < Ls - include CommonLsMethod + COLUMN_COUNT = 1 def initialize(files) - super(files) - @matrixed_files = build_matrix(@row_count, column_count, files) + content_widths = calc_widths(files) + super(files, COLUMN_COUNT, content_widths) # rubyは1ブロックを512バイト、Linuxは1ブロックを1024で計算しているため、2で割っている @total_block_size = files.map { |file| file.blocks.div(2) }.sum - @widths = calc_widths(files) end def generate [ "total #{@total_block_size}", - generate_rows(@matrixed_files, @widths) + generate_rows(@matrixed_files) ].join("\n") end private - def generate_row(files, widths) - # -lオプションが有効な時は必ず一列になるため、このように取得する - file = files[0] + def generate_content(file) [ file.str_mode, - file.nlink.to_s.rjust(widths[:nlink]), - file.owner.name.rjust(widths[:owner]), - file.group.name.rjust(widths[:group]), - file.size.rjust(widths[:size]), - file.mtime.rjust(widths[:mtime]), + file.nlink.to_s.rjust(@content_widths[:nlink]), + file.owner.name.rjust(@content_widths[:owner]), + file.group.name.rjust(@content_widths[:group]), + file.size.rjust(@content_widths[:size]), + file.mtime.rjust(@content_widths[:mtime]), file.name ].join(' ') end - def column_count - 1 - end - def calc_widths(files) widths = Hash.new { |hash, key| hash[key] = [] } files.each do |f| diff --git a/07.ls_object/ls_class.rb b/07.ls_object/ls_class.rb index 3b90dd9396..0551d2b379 100644 --- a/07.ls_object/ls_class.rb +++ b/07.ls_object/ls_class.rb @@ -3,21 +3,50 @@ require 'debug' class Ls - def initialize(files) - @row_count = files.count.ceildiv(column_count) + def initialize(files, column_count, content_widths) + row_count = files.count.ceildiv(column_count) + @matrixed_files = build_matrix(row_count, column_count, files) + @content_widths = content_widths end + # このメソッドが利用者との接点となる。 + # 子クラスはgenerateを適宜オーバーライドしてこのメソッドの結果を操作する。子クラスの実装で荒らされることが無いようにしたかったためそのようにした。 def self.generate(files) new(files).generate end + def generate + generate_rows(@matrixed_files) + end + + private_class_method :new + private - def column_count - raise NotImplementedError + def build_matrix(row_count, column_count, files) + (0...row_count).map do |i| + index_to_row_value = i + (0...column_count).map do + index_to_target = index_to_row_value + index_to_row_value += row_count + files[index_to_target] + end.compact + end end - def generate + def generate_rows(matrixed_files) + matrixed_files.map do |files| + generate_row(files) + end.join("\n") + end + + def generate_row(files) + files.map do |file| + generate_content(file) + end.join(' ') + end + + def generate_content(file) raise NotImplementedError end end diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb index 62d8fc9225..4261a25698 100644 --- a/07.ls_object/test/test_ls.rb +++ b/07.ls_object/test/test_ls.rb @@ -36,7 +36,7 @@ def test_all def test_reverse expected = <<~LIST.chomp test_ls.rb file_d.txt file_a.txt - file_f.txt file_c.txt abc.txt + file_f.txt file_c.txt abc.txt#{' '} file_e.txt file_b.txt LIST all = false @@ -69,8 +69,8 @@ def test_list def test_all_reverse expected = <<~LIST.chomp test_ls.rb file_d.txt file_a.txt - file_f.txt file_c.txt abc.txt - file_e.txt file_b.txt . + file_f.txt file_c.txt abc.txt#{' '} + file_e.txt file_b.txt .#{' '} LIST all = true reverse = true From 50704a04f2803aa3015ac7b8f897882af9a92d8b Mon Sep 17 00:00:00 2001 From: shoma Date: Sat, 6 Dec 2025 19:49:24 +0900 Subject: [PATCH 08/17] =?UTF-8?q?=E5=91=BD=E5=90=8D=E3=81=AE=E5=85=B7?= =?UTF-8?q?=E4=BD=93=E5=BA=A6=E3=82=92=E4=B8=8A=E3=81=92=E3=81=A6=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/ls.rb | 4 ++-- 07.ls_object/{default_ls.rb => multi_column_ls.rb} | 2 +- 07.ls_object/test/test_ls.rb | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) rename 07.ls_object/{default_ls.rb => multi_column_ls.rb} (93%) diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index c9d21f23d9..3684e61db1 100644 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -2,7 +2,7 @@ require 'optparse' require_relative 'get_files' -require_relative 'default_ls' +require_relative 'multi_column_ls' require_relative 'long_format_ls' opt = OptionParser.new @@ -15,4 +15,4 @@ opt.parse(ARGV) files = get_files(all, reverse) -puts long_format ? LongFormatLs.generate(files) : DefaultLs.generate(files) +puts long_format ? LongFormatLs.generate(files) : MultiColumnLs.generate(files) diff --git a/07.ls_object/default_ls.rb b/07.ls_object/multi_column_ls.rb similarity index 93% rename from 07.ls_object/default_ls.rb rename to 07.ls_object/multi_column_ls.rb index 43479e561b..07a545403f 100644 --- a/07.ls_object/default_ls.rb +++ b/07.ls_object/multi_column_ls.rb @@ -2,7 +2,7 @@ require_relative 'ls_class' -class DefaultLs < Ls +class MultiColumnLs < Ls COLUMN_COUNT = 3 def initialize(files) name_width = files.map { |file| file.name.length }.max diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb index 4261a25698..436f4ce749 100644 --- a/07.ls_object/test/test_ls.rb +++ b/07.ls_object/test/test_ls.rb @@ -3,7 +3,7 @@ require 'minitest/autorun' require_relative '../ls_class' require_relative '../get_files' -require_relative '../default_ls' +require_relative '../multi_column_ls' require_relative '../long_format_ls' class LsTest < Minitest::Test @@ -16,7 +16,7 @@ def test_default all = false reverse = false files = get_files(all, reverse) - ls_content = DefaultLs.generate(files) + ls_content = MultiColumnLs.generate(files) assert_equal expected, ls_content end @@ -29,7 +29,7 @@ def test_all all = true reverse = false files = get_files(all, reverse) - ls_content = DefaultLs.generate(files) + ls_content = MultiColumnLs.generate(files) assert_equal expected, ls_content end @@ -42,7 +42,7 @@ def test_reverse all = false reverse = true files = get_files(all, reverse) - ls_content = DefaultLs.generate(files) + ls_content = MultiColumnLs.generate(files) assert_equal expected, ls_content end @@ -75,7 +75,7 @@ def test_all_reverse all = true reverse = true files = get_files(all, reverse) - ls_content = DefaultLs.generate(files) + ls_content = MultiColumnLs.generate(files) assert_equal expected, ls_content end From 5ccd7e78d9e3799ccfc5d74f0ec823a672ed59f1 Mon Sep 17 00:00:00 2001 From: shoma Date: Wed, 17 Dec 2025 10:31:24 +0900 Subject: [PATCH 09/17] =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E6=A7=8B?= =?UTF-8?q?=E6=88=90=E3=82=92=E5=86=8D=E8=80=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/directory_content_output.rb | 117 ++++++++++++++++++++++ 07.ls_object/file.rb | 120 ++++++++++++----------- 07.ls_object/get_files.rb | 10 -- 07.ls_object/input_builder.rb | 25 +++++ 07.ls_object/long_format_ls.rb | 47 --------- 07.ls_object/ls.rb | 24 ++--- 07.ls_object/ls_class.rb | 52 ---------- 07.ls_object/multi_column_ls.rb | 16 --- 07.ls_object/test/test_ls.rb | 74 ++++++++------ 9 files changed, 259 insertions(+), 226 deletions(-) create mode 100644 07.ls_object/directory_content_output.rb delete mode 100644 07.ls_object/get_files.rb create mode 100644 07.ls_object/input_builder.rb delete mode 100644 07.ls_object/long_format_ls.rb delete mode 100644 07.ls_object/ls_class.rb delete mode 100644 07.ls_object/multi_column_ls.rb diff --git a/07.ls_object/directory_content_output.rb b/07.ls_object/directory_content_output.rb new file mode 100644 index 0000000000..8510c88f5a --- /dev/null +++ b/07.ls_object/directory_content_output.rb @@ -0,0 +1,117 @@ +# frozen_string_literal: true + +class DirectoryContentOutput + def self.run(files, long_format) + directory_content_output = new(files, long_format) + puts directory_content_output.generate + end + + def initialize(files, long_format) + @files = files + @long_format = long_format + end + + def generate + @long_format ? LongFormat.generate(@files) : MultiColumnFormat.generate(@files) + end + + class MultiColumnFormat + COLUMN_COUNT = 3 + + def self.generate(files) + multi_column_format = new(files) + matrixed_files = multi_column_format.build_matrix + multi_column_format.generate_rows(matrixed_files) + end + + def initialize(files) + @files = files + end + + def name_width + @files.map { |file| file.name.length }.max + end + + def row_count + @files.count.ceildiv(COLUMN_COUNT) + end + + def build_matrix + (0...row_count).map do |i| + index_to_row_value = i + (0...COLUMN_COUNT).map do + index_to_target = index_to_row_value + index_to_row_value += row_count + @files[index_to_target] + end.compact + end + end + + def generate_rows(matrixed_files) + matrixed_files.map do |files| + generate_row(files) + end.join("\n") + end + + def generate_row(files) + files.map do |file| + generate_content(file) + end.join(' ') + end + + def generate_content(file) + file.name.ljust(name_width) + end + end + + class LongFormat + def self.generate(files) + long_format = new(files) + column = files.map do |file| + long_format.generate_content(file) + end.join("\n") + + [ + "total #{long_format.total_block_size}", + column + ].join("\n") + end + + def initialize(files) + @files = files + end + + def total_block_size + # rubyは1ブロックを512バイト、Linuxは1ブロックを1024で計算しているため、2で割っている + @files.map { |file| file.blocks.div(2) }.sum + end + + def generate_content(file) + content_widths = calc_widths + [ + file.str_mode, + file.nlink.to_s.rjust(content_widths[:nlink]), + file.owner.name.rjust(content_widths[:owner]), + file.group.name.rjust(content_widths[:group]), + file.size.rjust(content_widths[:size]), + file.mtime.rjust(content_widths[:mtime]), + file.name + ].join(' ') + end + + def calc_widths + widths = Hash.new { |hash, key| hash[key] = [] } + @files.each do |f| + widths[:owner].push(f.owner.name.length) + widths[:group].push(f.group.name.length) + widths[:nlink].push(f.nlink.to_s.length) + widths[:size].push(f.size.length) + widths[:mtime].push(f.mtime.length) + widths[:name].push(f.name.length) + end + widths.transform_values(&:max) + end + end + + private_constant :MultiColumnFormat, :LongFormat +end diff --git a/07.ls_object/file.rb b/07.ls_object/file.rb index db32bc464c..31345075ae 100644 --- a/07.ls_object/file.rb +++ b/07.ls_object/file.rb @@ -1,61 +1,67 @@ # frozen_string_literal: true -module My - class File - FILE_TYPES = { - '04' => 'd', - '10' => '-', - '12' => 'l' - }.freeze - PERMISSIONS = { - '7' => 'rwx', - '6' => 'rw-', - '5' => 'r-x', - '4' => 'r--', - '3' => '-wx', - '2' => '-w-', - '1' => '--x', - '0' => '---' - }.freeze - - attr_reader :name - - private_constant :FILE_TYPES, :PERMISSIONS - - def initialize(name) - @name = name - @state = ::File.stat(name) - end - - def str_mode - int_mode = @state.mode.to_s(8).rjust(6, '0') - FILE_TYPES[int_mode[0..1]] + int_mode[3..5].chars.map { |mode| PERMISSIONS[mode] }.join - end - - def nlink - @state.nlink - end - - def owner - uid = @state.uid - Etc.getpwuid(uid) - end - - def group - gid = @state.gid - Etc.getgrgid(gid) - end - - def size - @state.size.to_s - end - - def blocks - @state.blocks - end - - def mtime - @state.mtime.strftime('%b %d %H:%M').to_s - end +require 'etc' + +class FileMetadata + FILE_TYPES = { + '04' => 'd', + '10' => '-', + '12' => 'l' + }.freeze + PERMISSIONS = { + '7' => 'rwx', + '6' => 'rw-', + '5' => 'r-x', + '4' => 'r--', + '3' => '-wx', + '2' => '-w-', + '1' => '--x', + '0' => '---' + }.freeze + + private_constant :FILE_TYPES, :PERMISSIONS + attr_reader :name + + def self.get_files(all, reverse) + flags = all ? File::FNM_DOTMATCH : 0 + files = Dir.glob('*', flags).map { |file_name| new(file_name) } + asc_order_files = files.sort_by(&:name) + reverse ? asc_order_files.reverse : asc_order_files + end + + def initialize(name) + @name = name + @state = ::File.stat(name) + end + + def str_mode + int_mode = @state.mode.to_s(8).rjust(6, '0') + FILE_TYPES[int_mode[0..1]] + int_mode[3..5].chars.map { |mode| PERMISSIONS[mode] }.join + end + + def nlink + @state.nlink + end + + def owner + uid = @state.uid + Etc.getpwuid(uid) + end + + def group + gid = @state.gid + Etc.getgrgid(gid) + end + + def size + @state.size.to_s + end + + def blocks + @state.blocks + end + + def mtime + @state.mtime.strftime('%b %d %H:%M').to_s end end diff --git a/07.ls_object/get_files.rb b/07.ls_object/get_files.rb deleted file mode 100644 index d66dfc07f5..0000000000 --- a/07.ls_object/get_files.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -require_relative 'file' - -def get_files(all, reverse) - flags = all ? File::FNM_DOTMATCH : 0 - files = Dir.glob('*', flags).map { |file_name| My::File.new(file_name) } - asc_order_files = files.sort_by(&:name) - reverse ? asc_order_files.reverse : asc_order_files -end diff --git a/07.ls_object/input_builder.rb b/07.ls_object/input_builder.rb new file mode 100644 index 0000000000..56c895e77f --- /dev/null +++ b/07.ls_object/input_builder.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'optparse' +require_relative 'file' + +class InputBuilder + def self.build + input_builder = new + all, reverse, long_format = input_builder.parse_options + files = FileMetadata.get_files(all, reverse) + [files, long_format] + end + + def parse_options + opt = OptionParser.new + all = false + reverse = false + long_format = false + opt.on('-a') { |v| all = v } + opt.on('-r') { |v| reverse = v } + opt.on('-l') { |v| long_format = v } + opt.parse(ARGV) + [all, reverse, long_format] + end +end diff --git a/07.ls_object/long_format_ls.rb b/07.ls_object/long_format_ls.rb deleted file mode 100644 index 699de6976a..0000000000 --- a/07.ls_object/long_format_ls.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require_relative 'ls_class' - -class LongFormatLs < Ls - COLUMN_COUNT = 1 - def initialize(files) - content_widths = calc_widths(files) - super(files, COLUMN_COUNT, content_widths) - # rubyは1ブロックを512バイト、Linuxは1ブロックを1024で計算しているため、2で割っている - @total_block_size = files.map { |file| file.blocks.div(2) }.sum - end - - def generate - [ - "total #{@total_block_size}", - generate_rows(@matrixed_files) - ].join("\n") - end - - private - - def generate_content(file) - [ - file.str_mode, - file.nlink.to_s.rjust(@content_widths[:nlink]), - file.owner.name.rjust(@content_widths[:owner]), - file.group.name.rjust(@content_widths[:group]), - file.size.rjust(@content_widths[:size]), - file.mtime.rjust(@content_widths[:mtime]), - file.name - ].join(' ') - end - - def calc_widths(files) - widths = Hash.new { |hash, key| hash[key] = [] } - files.each do |f| - widths[:owner].push(f.owner.name.length) - widths[:group].push(f.group.name.length) - widths[:nlink].push(f.nlink.to_s.length) - widths[:size].push(f.size.length) - widths[:mtime].push(f.mtime.length) - widths[:name].push(f.name.length) - end - widths.transform_values { |widths| widths.max } - end -end diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index 3684e61db1..93ad412920 100644 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -1,18 +1,14 @@ # frozen_string_literal: true -require 'optparse' -require_relative 'get_files' -require_relative 'multi_column_ls' -require_relative 'long_format_ls' +require_relative 'input_builder' +require_relative 'file' +require_relative 'directory_content_output' -opt = OptionParser.new -all = false -reverse = false -long_format = false -opt.on('-a') { |v| all = v } -opt.on('-r') { |v| reverse = v } -opt.on('-l') { |v| long_format = v } -opt.parse(ARGV) +class Ls + def self.run + files_and_option = InputBuilder.build + DirectoryContentOutput.run(*files_and_option) + end +end -files = get_files(all, reverse) -puts long_format ? LongFormatLs.generate(files) : MultiColumnLs.generate(files) +Ls.run diff --git a/07.ls_object/ls_class.rb b/07.ls_object/ls_class.rb deleted file mode 100644 index 0551d2b379..0000000000 --- a/07.ls_object/ls_class.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require 'debug' - -class Ls - def initialize(files, column_count, content_widths) - row_count = files.count.ceildiv(column_count) - @matrixed_files = build_matrix(row_count, column_count, files) - @content_widths = content_widths - end - - # このメソッドが利用者との接点となる。 - # 子クラスはgenerateを適宜オーバーライドしてこのメソッドの結果を操作する。子クラスの実装で荒らされることが無いようにしたかったためそのようにした。 - def self.generate(files) - new(files).generate - end - - def generate - generate_rows(@matrixed_files) - end - - private_class_method :new - - private - - def build_matrix(row_count, column_count, files) - (0...row_count).map do |i| - index_to_row_value = i - (0...column_count).map do - index_to_target = index_to_row_value - index_to_row_value += row_count - files[index_to_target] - end.compact - end - end - - def generate_rows(matrixed_files) - matrixed_files.map do |files| - generate_row(files) - end.join("\n") - end - - def generate_row(files) - files.map do |file| - generate_content(file) - end.join(' ') - end - - def generate_content(file) - raise NotImplementedError - end -end diff --git a/07.ls_object/multi_column_ls.rb b/07.ls_object/multi_column_ls.rb deleted file mode 100644 index 07a545403f..0000000000 --- a/07.ls_object/multi_column_ls.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -require_relative 'ls_class' - -class MultiColumnLs < Ls - COLUMN_COUNT = 3 - def initialize(files) - name_width = files.map { |file| file.name.length }.max - content_widths = { name: name_width } - super(files, COLUMN_COUNT, content_widths) - end - - def generate_content(file) - file.name.ljust(@content_widths[:name]) - end -end diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb index 436f4ce749..61a81adb18 100644 --- a/07.ls_object/test/test_ls.rb +++ b/07.ls_object/test/test_ls.rb @@ -1,10 +1,8 @@ # frozen_string_literal: true require 'minitest/autorun' -require_relative '../ls_class' -require_relative '../get_files' -require_relative '../multi_column_ls' -require_relative '../long_format_ls' +require_relative '../file' +require_relative '../directory_content_output' class LsTest < Minitest::Test def test_default @@ -15,8 +13,10 @@ def test_default LIST all = false reverse = false - files = get_files(all, reverse) - ls_content = MultiColumnLs.generate(files) + long_format = false + files = FileMetadata.get_files(all, reverse) + output = DirectoryContentOutput.new(files, long_format) + ls_content = output.generate assert_equal expected, ls_content end @@ -28,8 +28,10 @@ def test_all LIST all = true reverse = false - files = get_files(all, reverse) - ls_content = MultiColumnLs.generate(files) + long_format = false + files = FileMetadata.get_files(all, reverse) + output = DirectoryContentOutput.new(files, long_format) + ls_content = output.generate assert_equal expected, ls_content end @@ -41,13 +43,15 @@ def test_reverse LIST all = false reverse = true - files = get_files(all, reverse) - ls_content = MultiColumnLs.generate(files) + long_format = false + files = FileMetadata.get_files(all, reverse) + output = DirectoryContentOutput.new(files, long_format) + ls_content = output.generate assert_equal expected, ls_content end - def test_list - file = My::File.new('test_ls.rb') + def test_long_format + file = FileMetadata.new('test_ls.rb') expected = <<~LIST.chomp total 20 -rw-r--r-- 1 s-tone s-tone 3001 Dec 03 14:54 abc.txt @@ -61,8 +65,10 @@ def test_list LIST all = false reverse = false - files = get_files(all, reverse) - ls_content = LongFormatLs.generate(files) + long_format = true + files = FileMetadata.get_files(all, reverse) + output = DirectoryContentOutput.new(files, long_format) + ls_content = output.generate assert_equal expected, ls_content end @@ -74,14 +80,16 @@ def test_all_reverse LIST all = true reverse = true - files = get_files(all, reverse) - ls_content = MultiColumnLs.generate(files) + long_format = false + files = FileMetadata.get_files(all, reverse) + output = DirectoryContentOutput.new(files, long_format) + ls_content = output.generate assert_equal expected, ls_content end - def test_all_list - file = My::File.new('test_ls.rb') - current_directory = My::File.new('.') + def test_all_long_format + file = FileMetadata.new('test_ls.rb') + current_directory = FileMetadata.new('.') expected = <<~LIST.chomp total 24 drwxr-xr-x 2 s-tone s-tone #{current_directory.size} #{current_directory.mtime} . @@ -96,13 +104,15 @@ def test_all_list LIST all = true reverse = false - files = get_files(all, reverse) - ls_content = LongFormatLs.generate(files) + long_format = true + files = FileMetadata.get_files(all, reverse) + output = DirectoryContentOutput.new(files, long_format) + ls_content = output.generate assert_equal expected, ls_content end - def test_reverse_list - file = My::File.new('test_ls.rb') + def test_reverse_long_format + file = FileMetadata.new('test_ls.rb') expected = <<~LIST.chomp total 20 -rw-r--r-- 1 s-tone s-tone #{file.size} #{file.mtime} test_ls.rb @@ -116,14 +126,16 @@ def test_reverse_list LIST all = false reverse = true - files = get_files(all, reverse) - ls_content = LongFormatLs.generate(files) + long_format = true + files = FileMetadata.get_files(all, reverse) + output = DirectoryContentOutput.new(files, long_format) + ls_content = output.generate assert_equal expected, ls_content end - def test_reverse_list_all - file = My::File.new('test_ls.rb') - current_directory = My::File.new('.') + def test_reverse_liong_format_all + file = FileMetadata.new('test_ls.rb') + current_directory = FileMetadata.new('.') expected = <<~LIST.chomp total 24 -rw-r--r-- 1 s-tone s-tone #{file.size} #{file.mtime} test_ls.rb @@ -138,8 +150,10 @@ def test_reverse_list_all LIST all = true reverse = true - files = get_files(all, reverse) - ls_content = LongFormatLs.generate(files) + long_format = true + files = FileMetadata.get_files(all, reverse) + output = DirectoryContentOutput.new(files, long_format) + ls_content = output.generate assert_equal expected, ls_content end end From b71f8f5abd39bec8178989f9b16a3858a3987f57 Mon Sep 17 00:00:00 2001 From: shoma Date: Fri, 19 Dec 2025 10:22:10 +0900 Subject: [PATCH 10/17] =?UTF-8?q?typo=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/file.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/07.ls_object/file.rb b/07.ls_object/file.rb index 31345075ae..57830be588 100644 --- a/07.ls_object/file.rb +++ b/07.ls_object/file.rb @@ -31,37 +31,37 @@ def self.get_files(all, reverse) def initialize(name) @name = name - @state = ::File.stat(name) + @stat = ::File.stat(name) end def str_mode - int_mode = @state.mode.to_s(8).rjust(6, '0') + int_mode = @stat.mode.to_s(8).rjust(6, '0') FILE_TYPES[int_mode[0..1]] + int_mode[3..5].chars.map { |mode| PERMISSIONS[mode] }.join end def nlink - @state.nlink + @stat.nlink end def owner - uid = @state.uid + uid = @stat.uid Etc.getpwuid(uid) end def group - gid = @state.gid + gid = @stat.gid Etc.getgrgid(gid) end def size - @state.size.to_s + @stat.size.to_s end def blocks - @state.blocks + @stat.blocks end def mtime - @state.mtime.strftime('%b %d %H:%M').to_s + @stat.mtime.strftime('%b %d %H:%M').to_s end end From 97ebac84c4ffc38cdf3e450b108e192d952416ce Mon Sep 17 00:00:00 2001 From: shoma Date: Fri, 19 Dec 2025 10:24:34 +0900 Subject: [PATCH 11/17] =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=94?= =?UTF-8?q?=E3=81=A8=E3=81=AB=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92?= =?UTF-8?q?=E5=88=86=E5=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/directory_content_output.rb | 103 +---------------------- 07.ls_object/long_format.rb | 52 ++++++++++++ 07.ls_object/multi_column_format.rb | 53 ++++++++++++ 3 files changed, 108 insertions(+), 100 deletions(-) create mode 100644 07.ls_object/long_format.rb create mode 100644 07.ls_object/multi_column_format.rb diff --git a/07.ls_object/directory_content_output.rb b/07.ls_object/directory_content_output.rb index 8510c88f5a..e18c608c2a 100644 --- a/07.ls_object/directory_content_output.rb +++ b/07.ls_object/directory_content_output.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +require_relative 'multi_column_format' +require_relative 'long_format' + class DirectoryContentOutput def self.run(files, long_format) directory_content_output = new(files, long_format) @@ -14,104 +17,4 @@ def initialize(files, long_format) def generate @long_format ? LongFormat.generate(@files) : MultiColumnFormat.generate(@files) end - - class MultiColumnFormat - COLUMN_COUNT = 3 - - def self.generate(files) - multi_column_format = new(files) - matrixed_files = multi_column_format.build_matrix - multi_column_format.generate_rows(matrixed_files) - end - - def initialize(files) - @files = files - end - - def name_width - @files.map { |file| file.name.length }.max - end - - def row_count - @files.count.ceildiv(COLUMN_COUNT) - end - - def build_matrix - (0...row_count).map do |i| - index_to_row_value = i - (0...COLUMN_COUNT).map do - index_to_target = index_to_row_value - index_to_row_value += row_count - @files[index_to_target] - end.compact - end - end - - def generate_rows(matrixed_files) - matrixed_files.map do |files| - generate_row(files) - end.join("\n") - end - - def generate_row(files) - files.map do |file| - generate_content(file) - end.join(' ') - end - - def generate_content(file) - file.name.ljust(name_width) - end - end - - class LongFormat - def self.generate(files) - long_format = new(files) - column = files.map do |file| - long_format.generate_content(file) - end.join("\n") - - [ - "total #{long_format.total_block_size}", - column - ].join("\n") - end - - def initialize(files) - @files = files - end - - def total_block_size - # rubyは1ブロックを512バイト、Linuxは1ブロックを1024で計算しているため、2で割っている - @files.map { |file| file.blocks.div(2) }.sum - end - - def generate_content(file) - content_widths = calc_widths - [ - file.str_mode, - file.nlink.to_s.rjust(content_widths[:nlink]), - file.owner.name.rjust(content_widths[:owner]), - file.group.name.rjust(content_widths[:group]), - file.size.rjust(content_widths[:size]), - file.mtime.rjust(content_widths[:mtime]), - file.name - ].join(' ') - end - - def calc_widths - widths = Hash.new { |hash, key| hash[key] = [] } - @files.each do |f| - widths[:owner].push(f.owner.name.length) - widths[:group].push(f.group.name.length) - widths[:nlink].push(f.nlink.to_s.length) - widths[:size].push(f.size.length) - widths[:mtime].push(f.mtime.length) - widths[:name].push(f.name.length) - end - widths.transform_values(&:max) - end - end - - private_constant :MultiColumnFormat, :LongFormat end diff --git a/07.ls_object/long_format.rb b/07.ls_object/long_format.rb new file mode 100644 index 0000000000..8087f4a764 --- /dev/null +++ b/07.ls_object/long_format.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +class LongFormat + def self.generate(files) + long_format = new(files) + column = files.map do |file| + long_format.generate_content(file) + end.join("\n") + + [ + "total #{long_format.total_block_size}", + column + ].join("\n") + end + + def initialize(files) + @files = files + end + + def total_block_size + # rubyは1ブロックを512バイト、Linuxは1ブロックを1024で計算しているため、2で割っている + @files.map { |file| file.blocks.div(2) }.sum + end + + def generate_content(file) + content_widths = calc_widths + [ + file.str_mode, + file.nlink.to_s.rjust(content_widths[:nlink]), + file.owner.name.rjust(content_widths[:owner]), + file.group.name.rjust(content_widths[:group]), + file.size.rjust(content_widths[:size]), + file.mtime.rjust(content_widths[:mtime]), + file.name + ].join(' ') + end + + private + + def calc_widths + widths = Hash.new { |hash, key| hash[key] = [] } + @files.each do |f| + widths[:owner].push(f.owner.name.length) + widths[:group].push(f.group.name.length) + widths[:nlink].push(f.nlink.to_s.length) + widths[:size].push(f.size.length) + widths[:mtime].push(f.mtime.length) + widths[:name].push(f.name.length) + end + widths.transform_values(&:max) + end +end diff --git a/07.ls_object/multi_column_format.rb b/07.ls_object/multi_column_format.rb new file mode 100644 index 0000000000..cc2e1cf0e4 --- /dev/null +++ b/07.ls_object/multi_column_format.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +class MultiColumnFormat + COLUMN_COUNT = 3 + + def self.generate(files) + multi_column_format = new(files) + matrixed_files = multi_column_format.build_matrix + multi_column_format.generate_rows(matrixed_files) + end + + def initialize(files) + @files = files + end + + def build_matrix + (0...row_count).map do |i| + index_to_row_value = i + (0...COLUMN_COUNT).map do + index_to_target = index_to_row_value + index_to_row_value += row_count + @files[index_to_target] + end.compact + end + end + + def generate_rows(matrixed_files) + matrixed_files.map do |files| + generate_row(files) + end.join("\n") + end + + private + + def name_width + @files.map { |file| file.name.length }.max + end + + def row_count + @files.count.ceildiv(COLUMN_COUNT) + end + + + def generate_row(files) + files.map do |file| + generate_content(file) + end.join(' ') + end + + def generate_content(file) + file.name.ljust(name_width) + end +end From 30c62c45c1bf1876ec7ad958cf8c12a02f40232d Mon Sep 17 00:00:00 2001 From: shoma Date: Fri, 19 Dec 2025 10:47:20 +0900 Subject: [PATCH 12/17] =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AE?= =?UTF-8?q?=E5=BD=B9=E5=89=B2=E3=82=92=E8=A6=8B=E7=9B=B4=E3=81=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/input_builder.rb | 11 ++--------- 07.ls_object/ls.rb | 5 +++-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/07.ls_object/input_builder.rb b/07.ls_object/input_builder.rb index 56c895e77f..52a4b48172 100644 --- a/07.ls_object/input_builder.rb +++ b/07.ls_object/input_builder.rb @@ -3,15 +3,8 @@ require 'optparse' require_relative 'file' -class InputBuilder - def self.build - input_builder = new - all, reverse, long_format = input_builder.parse_options - files = FileMetadata.get_files(all, reverse) - [files, long_format] - end - - def parse_options +class CommandLineArgumentsParser + def self.parse opt = OptionParser.new all = false reverse = false diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index 93ad412920..8634aa0098 100644 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -6,8 +6,9 @@ class Ls def self.run - files_and_option = InputBuilder.build - DirectoryContentOutput.run(*files_and_option) + getting_all, getting_reverse_order, show_in_long_format = CommandLineArgumentsParser.parse + files = FileMetadata.get_files(getting_all, getting_reverse_order) + DirectoryContentOutput.run(files, show_in_long_format) end end From cf1429cfcaa6292b19307c0295b17330fd59c9cd Mon Sep 17 00:00:00 2001 From: shoma Date: Fri, 19 Dec 2025 10:50:34 +0900 Subject: [PATCH 13/17] =?UTF-8?q?=E4=BD=99=E8=A8=88=E3=81=AA=E7=A9=BA?= =?UTF-8?q?=E7=99=BD=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/ls.rb | 2 +- 07.ls_object/multi_column_format.rb | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index 8634aa0098..ecf46335bb 100644 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -7,7 +7,7 @@ class Ls def self.run getting_all, getting_reverse_order, show_in_long_format = CommandLineArgumentsParser.parse - files = FileMetadata.get_files(getting_all, getting_reverse_order) + files = FileMetadata.get_files(getting_all, getting_reverse_order) DirectoryContentOutput.run(files, show_in_long_format) end end diff --git a/07.ls_object/multi_column_format.rb b/07.ls_object/multi_column_format.rb index cc2e1cf0e4..a9c5044dea 100644 --- a/07.ls_object/multi_column_format.rb +++ b/07.ls_object/multi_column_format.rb @@ -12,7 +12,7 @@ def self.generate(files) def initialize(files) @files = files end - + def build_matrix (0...row_count).map do |i| index_to_row_value = i @@ -40,7 +40,6 @@ def row_count @files.count.ceildiv(COLUMN_COUNT) end - def generate_row(files) files.map do |file| generate_content(file) From 1a45ee7e1e936dfa56fb208673eaa7e6856b0e15 Mon Sep 17 00:00:00 2001 From: shoma Date: Mon, 22 Dec 2025 08:21:56 +0900 Subject: [PATCH 14/17] =?UTF-8?q?=E5=87=BA=E5=8A=9B=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=81=AE=E5=91=BD=E5=90=8D=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ..._content_output.rb => file_list_printer.rb} | 2 +- 07.ls_object/ls.rb | 4 ++-- 07.ls_object/test/test_ls.rb | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) rename 07.ls_object/{directory_content_output.rb => file_list_printer.rb} (93%) diff --git a/07.ls_object/directory_content_output.rb b/07.ls_object/file_list_printer.rb similarity index 93% rename from 07.ls_object/directory_content_output.rb rename to 07.ls_object/file_list_printer.rb index e18c608c2a..8aad25d4fb 100644 --- a/07.ls_object/directory_content_output.rb +++ b/07.ls_object/file_list_printer.rb @@ -3,7 +3,7 @@ require_relative 'multi_column_format' require_relative 'long_format' -class DirectoryContentOutput +class FileListPrinter def self.run(files, long_format) directory_content_output = new(files, long_format) puts directory_content_output.generate diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index ecf46335bb..c63b8d6a6e 100644 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -2,13 +2,13 @@ require_relative 'input_builder' require_relative 'file' -require_relative 'directory_content_output' +require_relative 'file_list_printer' class Ls def self.run getting_all, getting_reverse_order, show_in_long_format = CommandLineArgumentsParser.parse files = FileMetadata.get_files(getting_all, getting_reverse_order) - DirectoryContentOutput.run(files, show_in_long_format) + FileListPrinter.run(files, show_in_long_format) end end diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb index 61a81adb18..7389627592 100644 --- a/07.ls_object/test/test_ls.rb +++ b/07.ls_object/test/test_ls.rb @@ -2,7 +2,7 @@ require 'minitest/autorun' require_relative '../file' -require_relative '../directory_content_output' +require_relative '../file_list_printer' class LsTest < Minitest::Test def test_default @@ -15,7 +15,7 @@ def test_default reverse = false long_format = false files = FileMetadata.get_files(all, reverse) - output = DirectoryContentOutput.new(files, long_format) + output = FileListPrinter.new(files, long_format) ls_content = output.generate assert_equal expected, ls_content end @@ -30,7 +30,7 @@ def test_all reverse = false long_format = false files = FileMetadata.get_files(all, reverse) - output = DirectoryContentOutput.new(files, long_format) + output = FileListPrinter.new(files, long_format) ls_content = output.generate assert_equal expected, ls_content end @@ -45,7 +45,7 @@ def test_reverse reverse = true long_format = false files = FileMetadata.get_files(all, reverse) - output = DirectoryContentOutput.new(files, long_format) + output = FileListPrinter.new(files, long_format) ls_content = output.generate assert_equal expected, ls_content end @@ -67,7 +67,7 @@ def test_long_format reverse = false long_format = true files = FileMetadata.get_files(all, reverse) - output = DirectoryContentOutput.new(files, long_format) + output = FileListPrinter.new(files, long_format) ls_content = output.generate assert_equal expected, ls_content end @@ -82,7 +82,7 @@ def test_all_reverse reverse = true long_format = false files = FileMetadata.get_files(all, reverse) - output = DirectoryContentOutput.new(files, long_format) + output = FileListPrinter.new(files, long_format) ls_content = output.generate assert_equal expected, ls_content end @@ -106,7 +106,7 @@ def test_all_long_format reverse = false long_format = true files = FileMetadata.get_files(all, reverse) - output = DirectoryContentOutput.new(files, long_format) + output = FileListPrinter.new(files, long_format) ls_content = output.generate assert_equal expected, ls_content end @@ -128,7 +128,7 @@ def test_reverse_long_format reverse = true long_format = true files = FileMetadata.get_files(all, reverse) - output = DirectoryContentOutput.new(files, long_format) + output = FileListPrinter.new(files, long_format) ls_content = output.generate assert_equal expected, ls_content end @@ -152,7 +152,7 @@ def test_reverse_liong_format_all reverse = true long_format = true files = FileMetadata.get_files(all, reverse) - output = DirectoryContentOutput.new(files, long_format) + output = FileListPrinter.new(files, long_format) ls_content = output.generate assert_equal expected, ls_content end From e054253255a653bcbf08ab7b6ee6027d10d163e7 Mon Sep 17 00:00:00 2001 From: shoma Date: Mon, 22 Dec 2025 09:18:00 +0900 Subject: [PATCH 15/17] =?UTF-8?q?=E9=85=8D=E5=88=97=E3=81=AE=E9=A0=86?= =?UTF-8?q?=E7=95=AA=E3=81=AB=E4=BE=9D=E5=AD=98=E3=81=97=E3=81=AA=E3=81=84?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/command_line_options.rb | 25 +++++++++++++++++++++++++ 07.ls_object/input_builder.rb | 18 ------------------ 07.ls_object/ls.rb | 8 ++++---- 3 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 07.ls_object/command_line_options.rb delete mode 100644 07.ls_object/input_builder.rb diff --git a/07.ls_object/command_line_options.rb b/07.ls_object/command_line_options.rb new file mode 100644 index 0000000000..c58b88d535 --- /dev/null +++ b/07.ls_object/command_line_options.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'optparse' + +class CommandLineOptions + def initialize + opt = OptionParser.new + opt.on('-a') { |v| @all = v } + opt.on('-r') { |v| @reverse = v } + opt.on('-l') { |v| @long_format = v } + opt.parse(ARGV) + end + + def show_all? + @all.nil? ? false : @all + end + + def show_long_format? + @long_format.nil? ? false : @long_format + end + + def show_reverse? + @reverse.nil? ? false : @reverse + end +end diff --git a/07.ls_object/input_builder.rb b/07.ls_object/input_builder.rb deleted file mode 100644 index 52a4b48172..0000000000 --- a/07.ls_object/input_builder.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require 'optparse' -require_relative 'file' - -class CommandLineArgumentsParser - def self.parse - opt = OptionParser.new - all = false - reverse = false - long_format = false - opt.on('-a') { |v| all = v } - opt.on('-r') { |v| reverse = v } - opt.on('-l') { |v| long_format = v } - opt.parse(ARGV) - [all, reverse, long_format] - end -end diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index c63b8d6a6e..c6445f5582 100644 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -1,14 +1,14 @@ # frozen_string_literal: true -require_relative 'input_builder' +require_relative 'command_line_options' require_relative 'file' require_relative 'file_list_printer' class Ls def self.run - getting_all, getting_reverse_order, show_in_long_format = CommandLineArgumentsParser.parse - files = FileMetadata.get_files(getting_all, getting_reverse_order) - FileListPrinter.run(files, show_in_long_format) + options = CommandLineOptions.new + files = FileMetadata.get_files(options.show_all?, options.show_reverse?) + FileListPrinter.run(files, options.show_long_format?) end end From f2bb7faab6a9fd144f2463fe77d3269529c78d26 Mon Sep 17 00:00:00 2001 From: shoma Date: Mon, 22 Dec 2025 09:21:04 +0900 Subject: [PATCH 16/17] =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E5=90=8D=E3=81=A8=E3=82=AF=E3=83=A9=E3=82=B9=E5=90=8D=E3=82=92?= =?UTF-8?q?=E4=B8=80=E8=87=B4=E3=81=95=E3=81=9B=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/{file.rb => file_metadata.rb} | 0 07.ls_object/ls.rb | 2 +- 07.ls_object/test/test_ls.rb | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename 07.ls_object/{file.rb => file_metadata.rb} (100%) diff --git a/07.ls_object/file.rb b/07.ls_object/file_metadata.rb similarity index 100% rename from 07.ls_object/file.rb rename to 07.ls_object/file_metadata.rb diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index c6445f5582..618a8724cf 100644 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require_relative 'command_line_options' -require_relative 'file' +require_relative 'file_metadata' require_relative 'file_list_printer' class Ls diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb index 7389627592..11ed71fb07 100644 --- a/07.ls_object/test/test_ls.rb +++ b/07.ls_object/test/test_ls.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'minitest/autorun' -require_relative '../file' +require_relative '../file_metadata' require_relative '../file_list_printer' class LsTest < Minitest::Test From 1967c3d45982e06a753902725930c15c10eba0c7 Mon Sep 17 00:00:00 2001 From: shoma Date: Mon, 22 Dec 2025 15:05:50 +0900 Subject: [PATCH 17/17] =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=82=B9=E3=82=BF?= =?UTF-8?q?=E3=83=B3=E3=82=B9=E3=81=AE=E5=91=BD=E5=90=8D=E3=82=92=E3=82=AF?= =?UTF-8?q?=E3=83=A9=E3=82=B9=E3=81=A8=E4=B8=80=E8=87=B4=E3=81=95=E3=81=9B?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/file_list_printer.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/07.ls_object/file_list_printer.rb b/07.ls_object/file_list_printer.rb index 8aad25d4fb..aa27e58465 100644 --- a/07.ls_object/file_list_printer.rb +++ b/07.ls_object/file_list_printer.rb @@ -5,8 +5,8 @@ class FileListPrinter def self.run(files, long_format) - directory_content_output = new(files, long_format) - puts directory_content_output.generate + file_list_printer = new(files, long_format) + puts file_list_printer.generate end def initialize(files, long_format)