ちょっとifネストからのcaseネストの変換を考える

 ちょっと、ifのネストされた条件分岐を食わして、caseのネストされた条件分岐のプログラムを生成することを考える。

require 'pp'

def make_tree keys,tree
  return nil if keys.empty?
  ret = tree.assoc keys.first
  if ret
    make_tree keys[1..-1],ret[1]
    tree
  else
    tree<<[keys.first,make_tree(keys[1..-1],[])]
  end
end
t = []
t = make_tree [:a,:b,:c],t
#if :a
#  if :b
#    if :c
#    end
#  end
#end
t = make_tree [:a,:b,:c],t#重複
t = make_tree [:a,:b,:c],t#重複
t = make_tree [:a,:c,:b],t
t = make_tree [:b,:a,:c],t
t = make_tree [:b,:c,:a],t
t = make_tree [:c,:a,:b],t
t = make_tree [:c,:b,:a],t

pp t #=>
#=>[[:a, [[:b, [[:c, nil]]], [:c, [[:b, nil]]]]],
#=> [:b, [[:a, [[:c, nil]]], [:c, [[:a, nil]]]]],
#=> [:c, [[:a, [[:b, nil]]], [:b, [[:a, nil]]]]]]

def make_case condition,keys,state,offset=-1,todo=[]
  key = keys.first
  offset += 1
  
  middle = []
  condition.each{|m|
    middle << "when #{m.first}"
    unless m[1]
      middle << (todo<<m.first).join
    else
      make_case m[1],keys[1..-1],middle,offset,(todo.clone << m.first)
    end
  }
  state << (["case #{key}"]+ middle+["end"])
end

s = []
make_case t,%w[k1 k2 k3],s
puts s #=>

#=>case k1
#=>when a
#=>case k2
#=>when b
#=>case k3
#=>when c
#=>abc
#=>end
#=>when c
#=>case k3
#=>when b
#=>acb
#=>end
#=>end
#=>when b
#=>case k2
#=>when a
#=>case k3
#=>when c
#=>bac
#=>end
#=>when c
#=>case k3
#=>when a
#=>bca
#=>end
#=>end
#=>when c
#=>case k2
#=>when a
#=>case k3
#=>when b
#=>cab
#=>end
#=>when b
#=>case k3
#=>when a
#=>cba
#=>end
#=>end
#=>end

出力を整形して

case k1
when a
  case k2
  when b
    case k3
    when c
      abc
    end
  when c
    case k3
    when b
      acb
    end
  end
when b
  case k2
  when a
    case k3
    when c
      bac
    end
  when c
    case k3
    when a
      bca
    end
  end
when c
  case k2
  when a
    case k3
    when b
      cab
    end
  when b
    case k3
    when a
      cba
    end
  end
end

 こんな感じ。間違ってないよね?
う〜ん、もっと簡単な方法がないかな?無駄に時間を浪費したようなw;これで、一日潰れたよ...orz