2012-12-19 72 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