2016-11-23 6 views
0

Я пытаюсь высушить какой-то код. Как сделать композицию и/или наследование рубином с помощью этого фрагмента кода.рубин: как сделать наследование или компостирование

module Ns4 
    module Maps 
    module StrokeStyle 
     class RedOutline 
     def self.strokeColor 
      "red" 
     end 

     def self.strokeWeight 
      4 
     end 
     end 

     class Random 
     def self.strokeColor 
      [ "#808080", "#909090" ].sample(1)[0] 
     end 

     def self.strokeWeight 
      4 
     end 
     end 

     class Transparent 
     def self.strokeColor 
      "transparent" 
     end 

     def self.strokeWeight 
      0 
     end 
     end 
    end 
    end 
end 

В принципе, я хочу уменьшить дублирование логики, где это возможно.

ответ

1

я могу думать о чем-то вдоль этих линий:

module Ns4 
    module Maps 
    module StrokeStyle 
     module StrokeHelper 
     def self.included(base) 
      base.singleton_class.send(:attr_accessor, *%i(strokeColor strokeWeight)) 
     end 
     end 
     class RedOutline 
     include StrokeHelper 
     end 
     class Random 
     include StrokeHelper 
     end 
     class Transparent 
     include StrokeHelper 
     end 
    end 
    end 
end 

Теперь у вас есть и присваивателя для обоих strokeColor и strokeWeight в каждом классе:

Ns4::Maps::StrokeStyle::RedOutline.strokeColor = 'red' 
Ns4::Maps::StrokeStyle::RedOutline.strokeColor 
#=> "red" 
Ns4::Maps::StrokeStyle::RedOutline.strokeWeight = 4 
Ns4::Maps::StrokeStyle::RedOutline.strokeWeight 
#=> 4 
+0

'base.singleton_class.send (: attr_accessor, *% i | strokeColor strokeWeight |)' :) Кроме того, я сомневаюсь, что он будет работать со случайным элементом массива. – mudasobwa

+0

@mudasobwa согласен. –

1

Если вы хотите действительно просушите :

METHODS = %i|strokeColor strokeWeight| 
DECLARATIONS = { 
    :RedOutline => [-> { 'red' }, 4], 
    :Random => [-> { %w|#808080 #909090|.sample }, 4], 
    :Transparent => ['transparent', 0] 
} 


module Ns4 
    module Maps 
    module StrokeStyle 
     DECLARATIONS.each do |klazz, props| 
     StrokeStyle.const_set(klazz, Module.new do 
      METHODS.zip(props).each do |(m, p)| 
      define_method m do p.is_a?(Proc) ? p.call : p end 
      end 
      module_function *METHODS 
     end) 
     end 
    end 
    end 
end 

puts Ns4::Maps::StrokeStyle::RedOutline.strokeColor 
#⇒ red 
puts Ns4::Maps::StrokeStyle::Random.strokeColor 
#⇒ #808080 
puts Ns4::Maps::StrokeStyle::Transparent.strokeColor 
#⇒ transparent 

Добавление новых методов теперь так же просто, как добавление новых Hash элементов.

+0

это едва соответствует принципу KISS, но очень круто :) –

+0

@ AndreyDeineko это именно то, что я называю KISS :) – mudasobwa

+0

Perfect, perfetto, parfait, perfekt, perfecto, 完 ぺ き, 完美, 완전한! (Upvoted ранее.) –

 Смежные вопросы

  • Нет связанных вопросов^_^