Comment detail

文字列のセンタリング (Nested Flatten)

これまたけれんみのない、#4120と同様の実装。rubyらしくStringを拡張して格調高く。

Dan the Occasional Rubyist

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class String
  def centered(width)
    width ||= 80
    margin = (width - self.length)/2;
    return self if margin == 0
    return " " * margin + self if margin > 0
    self[-margin..margin-1]
  end
end

ARGF.readlines.each{|l| puts l.centered(72) }
__END__
0         1         2         3         4         5         6         7
012345678901234567890123456789012345678901234567890123456789012345678901
This line is intentionally longer than 72 chars to test String#centered works fine.
String#centerを使って少し修正しました.
また,入力行がちょうどwidth文字 + \nのときに,頭の一文字と\nを切り落としてしまっていたので,centeredに渡す前にchompするようにしました.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class String
  def centered(width = 80)
    margin = (width - self.length)/2;
    return center(width) if margin >= 0
    self[-margin..margin-1]
  end
end

ARGF.readlines.each{|l| puts l.chomp.centered(72) }
__END__
0         1         2         3         4         5         6         7
012345678901234567890123456789012345678901234567890123456789012345678901
This line is intentionally longer than 72 chars to test String#centered works fine.

さらに修正しました. #4173 で,ご指摘を受けた不具合も直っています.

p "0123456789".centered(3)  # "345"
p "012".centered(5)  # " 012 "
p "012".centered(4)  # "012 "
p "012".centered(3)  # "012"
p "012".centered(2)  # "01"
p "012".centered(1)  # "1"
p "012".centered(0)  # ""
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class String
  def centered(width = 80)
    return center(width) if width > size
    self[(size - width) / 2, width]
  end
end

ARGF.readlines.each{|l| puts l.chomp.centered(72) }
__END__
0         1         2         3         4         5         6         7
012345678901234567890123456789012345678901234567890123456789012345678901
This line is intentionally longer than 72 chars to test String#centered works fine.

String#centerは右側からパディングを入れるようですので,それにあわせて,widthをはみ出す場合は「左側から削る」ようにしました.

Rubyでは,(CやPerlと異なり)負の整数の除算の場合,剰余の符号が除数(divisor)の符号と一致するような商が得られますが,4行目で文字列を削る際にその性質を利用しています. (4171 を見てぱくりました.勉強になります:-)

p "0123456789".centered(3)  # "456"
p "012".centered(5)   # " 012 "
p "012".centered(4)   # "012 "
p "012".centered(3)   # "012"
p "012".centered(2)   # "12"
p "012".centered(1)   # "1"
p "012".centered(0)   # ""
p "012".centered(-1)  # "012"
p "012".center(4) == " 012 ".centered(4)  # true
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
--- center.rb.orig      2007-11-19 17:17:47.000000000 +0900
+++ center.rb   2007-11-19 17:17:39.000000000 +0900
@@ -1,7 +1,7 @@
 class String
   def centered(width = 80)
-    return center(width) if width > size
-    self[(size - width) / 2, width]
+    return center(width) if width > size or 0 > width
+    self[-((width - size) / 2), width]
   end
 end

(width.odd? xor self.odd?) のときに、余計に1文字削ってしまうと思います。

1
p "0123456789".centered(3)  => "45"

Index

Feed

Other

Link

Pathtraq

loading...