Евгений обнови решението на 25.11.2014 08:22 (преди почти 10 години)
+module UI
+ class TextScreen
+
+ class << self
+ :text
+
+ def draw &block
+ @text = ''
+ class_eval &block
+ @text
+ end
+
+ def label (text:, border: nil, style: nil)
+ label = Label.new text
+ label.style style
+ label.border border
+ @text += label.text
+ end
+
+ def vertical (border: nil, style: nil, &block)
+ group = VerticalGroup.new(border: border, style: style, &block)
+ @text += group.text
+ end
+
+ def horizontal (border: nil, style: nil, &block)
+ group = HorizontalGroup.new(border: border, style: style, &block)
+ @text += group.text
+ end
+ end
+ end
+
+ class Label
+ attr_reader :text
+
+ def initialize text
+ @text = text
+ end
+
+ def add text
+ @text += text
+ end
+
+ def border border
+ return if border == nil
+ @text = border + @text + border
+ end
+
+ def style style
+ return if style == nil
+
+ case style
+ when :upcase then @text = @text.upcase
+ when :downcase then @text = @text.downcase
+ end
+ end
+ end
+
+ class VerticalGroup
+ :block
+ :border
+ :style
+
+ :lines
+
+ def initialize (border: nil, style: nil, &block)
+ @block = block
+ @border = border
+ @style = style
+
+ @lines = []
+ instance_eval &block
+ end
+
+ def label (text:, border: nil, style: nil)
+ label = Label.new text
+ label.style (style != nil ? style : @style)
+ label.border border
+ @lines << label
+ end
+
+ def vertical (border: nil, style: nil, &block)
+ border = (border != nil ? border : @border)
+ style = (style != nil ? style : @style)
+ group = VerticalGroup.new(border: border, style: style, &block)
+ label = Label.new group.text
+ @lines << label
+ end
+
+ def horizontal (border: nil, style: nil, &block)
+ border = (border != nil ? border : @border)
+ style = (style != nil ? style : @style)
+ group = HorizontalGroup.new(border: border, style: style, &block)
+ label = Label.new group.text
+ @lines << label
+ end
+
+ def text
+ TextUtilities::add_border(@lines, @border)
+
+ result = ''
+ @lines.each {|label| result += label.text + "\n"}
+ result
+ end
+ end
+
+ class HorizontalGroup
+ :block
+ :border
+ :style
+
+ :text_container
+
+ def initialize (border: nil, style: nil, &block)
+ @block = block
+ @border = border
+ @style = style
+
+ @text_container = Label.new ""
+ instance_eval &block
+ end
+
+ def label (text:, border: nil, style: nil)
+ label = Label.new text
+ label.style (style != nil ? style : @style)
+ label.border border
+ @text_container.add (label.text)
+ end
+
+ def vertical (border: nil, style: nil, &block)
+ border = (border != nil ? border : @border)
+ style = (style != nil ? style : @style)
+ group = VerticalGroup.new(border: border, style: style, &block)
+ @text_container.add (group.text)
+ end
+
+ def horizontal (border: nil, style: nil, &block)
+ border = (border != nil ? border : @border)
+ style = (style != nil ? style : @style)
+ group = HorizontalGroup.new(border: border, style: style, &block)
+ @text_container.add (group.text)
+ end
+
+ def text
+ if @border != nil
+ @border + @text_container.text + @border
+ else
+ @text_container.text
+ end
+ end
+ end
+
+ class TextUtilities
+ class << self
+ def add_border (labels, border)
+ return if border == nil
+
+ longest_line_size = biggest_line_size labels
+ labels.each do |label|
+ add_spaces label, (longest_line_size - label.text.size)
+ label.border border
+ end
+ end
+
+ def biggest_line_size labels
+ labels.max_by{|label| label.text.size}.text.size
+ end
+
+ def add_spaces (label, spaces_count)
+ label.add (" " * spaces_count)
+ end
+ end
+ end
+end
Прегледай примерите, които дискутираме тук.
Защо имаш символи в класовете? Какво постигаш с
class VerticalGroup
:block
...
Не ми харесва това, че имаш код за horizontal
, vertical
и label
на три места. Помисли как можеш да го рефакторираш, така че тези неща да са обособени на едно място.
Кодът ти не е форматиран правилно. Погледни style guide-а за това как се дефинира метод с аргументи. Също така на места ползваш 4 интервала, а не 2.