1.4.1.6. fejezet, Elágazások

if...then...else

Ez a kétirányú elágazás szinte minden programnyelvben szerepel. Itt viszont a then kulcsszó nem szerepel. Mint eddig megszokhattuk már, a Ruby-ban több formában jelenik meg.

if aDay == 'Saturday' or aDay == 'Sunday'
  daytype = 'weekend'
else 
  daytype = 'weekday'
end
 
working_overtime = true
if aDay == 'Saturday' or aDay == 'Sunday' and not working_overtime
  daytype = 'holiday'
  puts( "Hurrah!" ) 
else 
  daytype = 'working day' 
end

Logikai operátorok precedencia szerint:

  • ! (not)
  • && (and)
  • || (or)
  • Mindkét forma használható, nincs megkötés. Csak legyünk következetesek, és ügyeljünk a precedencia különbségekre.

    Precedencia szöveges változatnál:

  • not
  • or
  • and
  • Booleand kifejezések

    Az and kisebb precedenciával rendelkezik mint az &&.Az or kisebb precedenciával rendelkezi mint az ||. Használjuk következetesen ezeket, és ne keverjük a programban. Természetesen zárójelezni itt is lehet. Az egyenlőség vizsgálatára használjuk a == vagy a === jelöléseket. A kisebb egyenlő <= és nagyobb egyenlő >= mellett a nem egyenlő != jelölést is használhatjuk not(1==1).

    puts( (not( 1==1 )) ) # This is ok
    puts( not( 1==1 ) ) # This is a syntax error
    puts( true && true && !(true) ) # This is ok
    puts( true && true and !(true) ) # This is a syntax error
    puts( ((true) and (true)) ) # This is ok 
    puts( true && true ) # This is ok 
    puts( true and true ) # This is a syntax error

    A fenti példa mutatja, hogy melyik szintakszis használható, és melyik hibás.

    A kérdőjel operátor

    Itt van még a feltételes kifejezéseknél a kérdőjel operátor.

    x == 10 ? puts("it's 10") : puts( "it's some other number" )

    elsif

    A elsif kulcsszó, a máskülönben feltételág többször is szerepelhet a feltételben.

    if input == 'q'
      puts( "Bye" )
    elsif input.to_i > 800 && input.to_i <= 1000
      puts( "That's a high rate of pay!" )
    elsif input.to_i <= 800 && input.to_i > 0
      puts( "We can afford that" )
    else
      puts( "I said: Enter a number between 1 and 1000!" )
    end

    Ezen kívül a then kucsszót alkalmaznunk kell, ha egy sorba írjuk a feltétel és következmény részeket.

    def showDay( i )
      if i == 1 then puts("It's Monday" ) 
        elsif i == 2 then puts("It's Tuesday" )
        elsif i == 3 then puts("It's Wednesday" )
        elsif i == 4 then puts("It's Thursday" )
        elsif i == 5 then puts("It's Friday" )
        elsif (6..7) === i then puts( "Yippee! It's the weekend! " )
        else puts( "That's not a real day!" ) 
      end
    end

    A végén látható tartomány ellenőrzést megírható a már korábban említett include metódussal.

    (6..7)===i
     
    (6..7).include?(i)

    Fordítva is felírható a feltétel

    puts "egy" if i==1

    Vagy kettősponttal is elválaszthatjuk a következmény részt:

    if x == 1 : puts( 'ok' ) end

    Unless

    Az unless az if kiértékelésével ellentétes. Ha hamis értéket ad vissza a feltétel részben összeállított kifejezés, akkor végrehajtódik a következmény rész.

    sleep unless not tired

    Case...when elágazások

    Több if, elsif felírása helyett alkalmazható ez a forma:

    case( i )
      when 1 : puts("It's Monday" )
      when 2 : puts("It's Tuesday" )
      when 3 : puts("It's Wednesday" )
      when 4 : puts("It's Thursday" )
      when 5 : puts("It's Friday" )
      when (6..7) : puts( "Yippee! It's the weekend! " )
      else puts( "That's not a real day!" )
    end

    A kettőspont helyett alkalmazható a then kulcsszó:

    when 1 then puts("It's Monday" )

    A case-ben alkalmazott vizsgálandó érték nemcsak egy változó, hanem egy kifejezés is lehet:

    case( i + 1 )

    A feltétel többféle lehet. Szám, string, tartomány, és mindez kombinálható egy feltételben.

    when 1, 'Monday', 'Mon' : puts( "Yup, '#{i}' is Monday" )

    Itt egy összetett példa:

    case( i )
      when 1 : puts("It's Monday" )
      when 2 : puts("It's Tuesday" )
      when 3 : puts("It's Wednesday" )
      when 4 : puts("It's Thursday" )
      when 5 then puts("It's Friday" )
                  puts("...nearly the weekend!")
      when 6, 7 puts("It's Saturday!" )
        if i == 6 puts("It's Sunday!" ) 
        if i == 7 puts( "Yippee! It's the weekend! " ) 
      when 5 : puts( "It's Friday all over again!" )# Ez a kódrész nem fut le
      else puts( "That's not a real day!" )
    end

    Egy alternatív módja a case elágazásoknak:

    salary = 2000000
    season = 'summer'
     happy = case 
       when salary > 10000 && season == 'summer': puts( "Yes, I really am happy!" )
         'Very happy' #=> This value is "returned"
       when salary > 500000 && season == 'spring' : 'Pretty happy'
       else puts( 'miserable' )
    end
    puts( happy ) #=> "Very happy"

    cath ... throw

    Most egy olyan kódot nézzünk meg, ami szokatlan azoknak, akik a blokkok címkézését és azokra hivatkozást nagyon kerülték, mert azt tanulták, hogy ez már a múlté (pl.: goto). A blokkból való kiugrásra használható módszert láthatunk.

    # think of this as a block called :done
    catch( :done )
    {
     # some code here
    }
    # and this is a block called :finished
    catch( :finished ) do
      # some code here
    end

    Paraméterként egy szimbólumot kap a throw, és abból a blokkból ugrik ki, amit kapott paraméterül, és amiben jelenleg futna tovább.

    catch( :finished) do
      print( 'Enter a number: ' )
      num = gets().chomp.to_i
      if num == 0 then throw :finished 
        # if num is 0, jump out of the block 
      end
        # Here there may be hundreds of lines of
        # calculations based on the value of num
        # if num is 0 this code will be skipped
    end
        # the throw method causes execution to 
        # jump to here – outside of the block 
    puts( "Finished" )

    Címkézett catch blokkok egymásba is ágyazhatók. Könnyen segíthet a nehezen megtalálható hibák észrevételében.

    Egy külső blokk végére is léptethetjük a futó programot. Olyan blokkból léphetünk ki, amibe egy metódushívással léptünk bele:

    def dothings( aNum )
      i = 0
      while true
        puts( "I'm doing things..." )
        i += 1
        throw( :go_to_tea ) if (i == aNum ) # throws to end of go_to_tea block
      end
    end
     
    catch( :go_to_tea ){ # this is the :go_to_tea block
     dothings(5)
    }