2012-12-19 119 views
0

我正在使用Ruby on Rails 3.2.9和Ruby 1.9.3。我有以下case報表:如何重構嵌套case語句(在這種情況下)?

case 
when private? 
    case 
    when not_active? then [:a, :b, :c, :d] 
    when active?  then raise "private cannot be active" 
    else raise "not recognized" 
    end 
when shared? 
    case 
    when not_active? then [:a, :b, :c] 
    when active?  then raise "shared cannot be active" 
    else raise "not recognized" 
    end 
when public? 
    case 
    when not_active? then [:a, :b] 
    when active?  then [:a] 
    else raise "not recognized" 
    end 
else raise "not recognized" 
end 

如何重構上述代碼?

+0

@Andrew馬歇爾 - 我不明白你爲什麼刪除(至少)'的Ruby-on-rails'標記,因爲它可能是有一些回報率的方法,可以幫助重構張貼在代碼這個問題。 – user12882

+0

你能解釋更多關於'active?'和'not_active?'方法嗎? 它們是互補的,我的意思是這種情況'not_active? ==!活躍?'? – Khaled

+1

你的代碼如何能夠「提升」不被識別的「'? – oldergod

回答

6
raise "not recognized" unless private? or shared? or public? 
raise "not recognized" unless not_active? or active? 
raise "private cannot be active" if private? and active? 
raise "shared cannot be active" if shared? and active? 

[:a, *(:b unless active?), *(:c unless public?), *(:d if private?)] 


通過更改錯誤信息,你可以把它更舒適:

raise "visibility not recognized" unless private? or shared? or public? 
raise "activeness not recognized" unless not_active? or active? 
raise "active must be public" if active? and not public? 

[:a, *(:b unless active?), *(:c unless public?), *(:d if private?)] 

順便說一句,inactive?會比not_active?一個更好的方法名。

0

的組織之一:

CONDITIONS = 
    {"private?" => {"not_active?" => [:a, :b, :c, :d], 
        "active?"  => "private cannot be active"}, 
    {"shared?" => {"not_active?" => [:a, :b, :c], 
        "active?"  => "shared cannot be active"}, 
    {"public?" => {"not_active?" => [:a, :b], 
        "active?"  => [:a]}} 

def foo(it) 
    value = "not recognised" 
    CONDITIONS.each do |k, v| 
    if it.send(k.to_sym) 
     v.each do |inner_k, inner_v| 
     if it.send(inner_k.to_sym) 
      value = inner_v 
     end 
     end 
    end 
    end 

    raise value if (value.class.name == "String") 

    value 
end 

在擴張的情況下,你只需要進行條件散列更大。

+1

你的方法似乎有「複雜」的東西,而不是「促進」他們,主要是當條件(即嵌套'case'語句)將增加數量。 – user12882

+0

您尚未完整指定任務。 :)無論如何,然後使用多層hash作爲值。 – Matzi

+0

你是什麼意思,以及你將如何使用「多層散列值」? – user12882

0

DRY神物:

class Public 
    def not_active; [:a, :b]; end 
    def active; not_active.first; end 
    def missing_method; false; end 
end 

class Shared < Public 
    def not_active; super << :c; end 
    def active; raise "#{self.class.name.underscore} cannot be active"; end 
end 

class Private < Shared 
    def not_active; super << :d; end 
end 

state = active? ? :active : (not_active? ? :not_active : :missing_method) 
(Private.new.send(state) if private?)|| 
(Shared.new.send(state) if shared?)|| 
(Public.new.send(state) if public?)||raise("not recognized") 
0

有關使用數組如何?

actions = [ 
    ['[:a, :b, :c, :d]', 'raise "private cannot be active"'], 
    ['[:a, :b, :c]', 'raise "shared cannot be active"'], 
    ['[:a, :b]', '[:a]'] 
] 

x = [:private?, :shared?, :public?].find_index { |i| send(i) } 
y = [:not_active?, :active?].find_index { |i| send(i) } 

if x and y 
    eval(actions[x][y]) 
else 
    raise "not recognized" 
end