0

Ruby on Rails 3.2.9 と Ruby 1.9.3 を使用しています。私は次の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

上記のコードをリファクタリングするにはどうすればよいですか?

4

4 に答える 4

7
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?

于 2012-12-20T00:18:02.930 に答える
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
于 2012-12-20T01:49:55.163 に答える
0

ドライフェチ:

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")
于 2012-12-20T00:19:48.893 に答える
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

拡張の場合、CONDITIONS ハッシュを大きくするだけで済みます。

于 2012-12-19T22:21:11.593 に答える