Емилиан обнови решението на 22.11.2014 00:26 (преди около 10 години)
+module UI
+ @components = []
+
+ def self.components
+ @components
+ end
+
+ def self.components=(value)
+ @components = value
+ end
+
+ class TextScreen
+ attr_accessor :layout
+
+ def self.draw(&components)
+ self.instance_eval(&components)
+ text = UI.components.join
+ UI.components = []
+ text
+ end
+
+ def self.label(contents)
+ border = contents[:border]
+ text = contents[:text]
+ text = contents[:text].send(contents[:style]) if contents.has_key? :style
+ UI.components << "#{border}#{text}#{border}"
+ end
+
+ def self.horizontal(settings = {}, &components)
+ comps = UI.components.clone
+ self.instance_eval(&components)
+ block = UI.components - comps
+ text = set_text_horizontal(settings, block)
+ UI.components = comps + [text]
+ end
+
+ def self.vertical(settings = {}, &components)
+ comps = UI.components.clone
+ self.instance_eval(&components)
+ block = UI.components - comps
+ block = modify_vertical(settings, block)
+ UI.components = comps + [block.join]
+ end
+
+ def self.set_text_horizontal(settings, block)
+ border = settings[:border] if settings.has_key? :border
+ text = block.join
+ text = block.join.send(settings[:style]) if settings.has_key? :style
+ text = "#{border}#{text}#{border}" if settings.has_key? :border
+ text
+ end
+
+ def self.modify_vertical(settings, block)
+ settings[:border] = "" unless settings.has_key? :border
+ settings[:style] = :clone unless settings.has_key? :style
+ border = settings[:border] if settings.has_key? :border
+ block.map! { |comp| comp.ljust(UI.longest()).prepend(border) << border }
+ block.map! { |comp| comp.send(settings[:style]) }
+ block.map! { |comp| comp << "\n" }
+ end
+ end
+
+ def self.longest
+ UI.components.sort_by(&:length)[-1].length
+ end
+end
Прегледай примерите, които сме дискутирали в темата във форума.
Странно ми е, че си държиш компонентите в UI
. Това трябва да е само namespace, който да държи други класове и модули.
Можеш да помислиш върху това да разделиш кода си на повече модули/класове с ясно дефинирани задачи.
В момента ми се струва, че set_text_horizontal
, modify_vertical
и longest
са част от DSL-а, който изпълняваме в блока подаден на TextScreen.draw
, а не трябва. Този DSL трябва да е максимално чист и опростен.