From: Robert Klemme Date: 2008-02-01T00:06:23+09:00 Subject: Re: can ik make this more beautifull? 2008/1/31, Jari Williamsson : > Peter Hickman wrote: > > Jari Williamsson wrote: > >> Remco Hh wrote: > >>> nowadays i try to improve my coding style to produce nicer and beter > >>> readable code. I try to improve the following code but i dont know how. > >>> > >>> if condtion1 > >>> x=1 > >>> else > >>> if condition2 > >>> x=2 > >>> else > >>> if condition3 > >>> x=3 > >>> end > >>> end > >>> x=nill > >>> end > >>> > >>> there are three different conditions which can not occur at the same > >>> time > >>> can i make this nicer? > >> > >> A case expression is probably the most clear alternative. The shortest > >> is perhaps something like: > >> > >> x = condition1 ? 1 : condition2 ? 2 : 3 > >> > >> > >> Best regards, > >> > >> Jari Williamsson > >> > >> > > Short it may be but this sort of code can hardly be called beautiful, I > > have had to maintain crap like this before and the few keystrokes the > > author saved was made up for 1000 times when someone updated it and > > things didn't 'quite' work how they thought. Ruby allows simplicity and > > clarity, this however is heading into obfuscation. > > > > The better solution is to use the elsif keyword to flatten the indentation: > > > > if (temp == 'cat') > > x = 1 > > elsif(temp == 'dog') > > x = 2 > > elsif(temp == 'banana') > > x = 3 > > else > > x = nil > > end > > But this elsif solution isn't heading for clarity either, compared to > using a case expression: > x = case temp > when 1 then 'cat' > when 2 then 'dog' > when 3 then 'banana' > else nil > end > > In the elsif example, x appears 4 times instead of 1, temp appears 3 > times instead of 1. Apart from require an editor that support > refactoring and the risk of typos, there will also be a performance hit > when temp isn't matched. If you are using "case" then there is yet another solution: x = case when condition1 then 1 when condition2 then 2 when condition3 then 3 else nil end Another approach would be to stuff conditions in an array: CONDITIONS = [ lambda {|x| condition1 }, lambda {|x| condition2 }, lambda {|x| condition3 }, ] def test(*values) CONDITIONS.each_with_index do |c,i| return i+1 if c[*values] end nil end x = test "whatever" Kind regards robert -- use.inject do |as, often| as.you_can - without end