Cap. 8 – Declarações Condicionais

Anterior Índice Próximo

Declarações Condicionais…

Programas de computadores, como a vida real, estão cheios de decisões difíceis aguardando para serem tomadas. Coisas como: Se eu ficar na cama eu vou dormir um pouco mais, senão eu devo ir para o trabalho; se eu for para o trabalho e vou ganhar algum dinheiro, senão eu vou perder o meu emprego - e assim por diante… Nós já fizemos alguns testes if nos programas anteriores neste livro. Peguemos um simples exemplo, o calculador de impostos do capítulo 1:

if (subtotal < 0.0 ) then
  subtotal = 0.0
end

Neste programa, o usuário foi solicitado a digitar um valor, subtotal, o qual foi então usado para calcular o imposto devido sobre o valor. O pequeno teste acima assegura que o subtotal nunca será um valor negativo. Se o usuário, num momento de loucura, informar um valor menor que 0, o teste if detecta isso já que a condição ( subtotal < 0.0 ) é avaliada como verdadeira, o que causa a execução do código entre o if e o end colocando o valor 0 na variável subtotal.

Igual uma vez = ou igual duas vezes == ? Em comum com muitas outr as linguagens de pr ogr amação, o Ruby usa um sinal de igual par a atr ibuir um valor ‘=’ e usa dois par a testar um valor ‘==’ .

If.. Then.. Else..

Um teste if simples tem apenas um de dois resultados possíveis. Ou um pedaço de código é executado ou não, dependendo se o teste retorna verdadeiro ou falso. Muitas vezes, você precisará ter mais que duas saídas possíveis. Vamos supor, por exemplo, que seu programa necessita seguir um curso de ação se o dia da semana é uma quarta­feira e um curso de ação diferente se é fim de semana. Você pode testar estas condições adicionando uma seção else após a seção if, como no exemplo a seguir:

if aDay == 'Saturday' or aDay == 'Sunday'
  daytype = 'weekend'
else 
  daytype = 'weekday'
end

A condição if aqui é direta. Ela testa 2 condições possíveis:
  1. Se o valor da variável, aDay, é igual a 'Saturday' (sábado) ou ..
  2. Se o valor de aDay é igual a 'Sunday' (domingo).

Se uma destas condições for verdadeira então o código da linha seguinte será executado:

daytype = 'weekend'

Em todos os demais casos, o código depois do else será executado:

daytype = 'weekday'

Quando um teste if e o código a ser executado são colocados em linhas separ adas, a palavr a­ chave then é opcional. Quando o teste e o código são colocados na mesma linha, a palavr a­ chave then ( ou se você pr efer ir r esumir o código, o símbolo de dois pontos ':' ), é obr igatór ia. if x == 1 then puts( 'ok' ) end # com 'then' if x == 1 : puts( 'ok' ) end # com : if x == 1 puts( 'ok' ) end # com erro de sintaxe!

Um teste if não está restrito a avaliar somente duas condições. Vamos supor, por exemplo, que seu código necessite saber se um determinado dia é um dia útil ou um feriado. Todos os dias da semana são dias úteis (dia de trabalho ); todos os sábados (Saturday) são dias de folga mas os domingos (Sunday) somente são dias de folga se você não estiver fazendo horas extras.

Esta é a minha primeira tentativa de escrever um teste para avaliar todas estas condições:

working_overtime = true
if aDay == 'Saturday' or aDay == 'Sunday' and not working_overtime
  daytype = 'holiday'
  puts( &#8220;Hurrah!&#8221; )
else
  daytype = 'working day'
end

Infelizmente, isto não teve o efeito esperado. Lembre­se que Saturday (sábado) é sempre dia de folga. Mas este código insiste que 'Saturday' é um dia útil. Isto ocorre porque o Ruby entende o teste como: - Se o dia é Sábado e eu não estou fazendo horas extras, ou se o dia é Domingo e eu não estou fazendo horas extras, onde eu realmente queria dizer, Se o dia é Sábado; ou s e o dia é Domingo e eu não estou fazendo horas extras.

A forma mais simples de resolver esta ambigüidade é colocar parênteses em volta de qualquer código que deva ser avaliado como uma única expressão, assim:
if aDay == 'Saturday' or (aDay == 'Sunday' and not working_overtime)

And.. Or.. Not

O Ruby tem duas sintaxes diferentes para testar condições lógicas (verdadeiro/falso – true/false). No exemplo acima, E usei os operadores da língua inglesa: and, or and not. Se você preferir você pode usar operadores alternativos similares aos usados em outras linguagens de programação, a saber: && (and), || (or) and ! (not).

Seja cuidadoso, os dois conjuntos de operadores não são completamente intercambiáveis. Eles tem diferente precedência o que significa que quando múltiplos operadores são usados em um único teste, as partes do teste podem ser avaliadas em ordem diferente dependendo de quais operadores você usa.

If.. Elseif

Não há dúvidas que haverá ocasiões que você precisará tomar múltiplas ações baseadas em múltiplas condições alternativas. Uma forma de fazer isso é avaliar uma condição if seguida de uma série de outros testes colocados após a palavra­chave elseif. O lote todo então é terminado usando a palavra­chave end.

Por exemplo, aqui eu estou repetidamente solicitando informação ao usuário dentro de um laço while; uma condição if testa se o usuário digitou 'q' ( eu usei o método chomp() para remover o 'retorno de carro' do dado digitado); se 'q' não foi informado o primeiro elsif testa se foi digitado um número inteiro ( input.to_i ) maior que 800; se o teste falhar a próxima condição elsif testa se o número é menor ou igual a 800:

while input != 'q' do
  puts( &#8220;Informe um número entre 1 e 1000 ( ou 'q' para sair)&#8221; )
  print( &#8220;?­ &#8220; )
  input = gets().chomp()
  if input == 'q'
    puts( &#8220;Tchau...&#8221; )
  elsif input.to_i > 800
    puts( &#8220;Este é um valor muito alto!&#8221; )
  elsif input.to_i <= 800
    puts( &#8220;Eu não posso gastar isso.&#8221; )
  end
end

Este código tem um bug. Ele pede por um númer o entr e 1 e 1000 mas ele aceita outr os númer os, até mesmo palavr as e car acter es diver sos. Veja se você pode a escr ever os testes par a conser tar o código acima.

O Ruby também tem uma for ma r eduzida de notação par a o if..then..else no qual um ponto de interrogação ? Substitui a par te if..then e o sinal de dois pontos : atua como o else…

? :

Por exemplo:

   x == 10 ? puts( &#8220;Igual a 10&#8221; ) : puts( &#8220;Algum outro valor&#8221; )

Quando a condição de teste é complexa ( se usa ands and ors ) você deve envolvê­-la por parênteses.

Se os testes e os códigos extendem­se por vár ias linhas a ? deve ser colocada na mesma linha da condição pr ecedente e o : deve ser colocado na mesma linha do código seguinte à ?.

Em outras palavras, se você colocar uma nova linha antes da ? Ou do : isto ir á gerar um erro de sintaxe. Veja abaixo um exemplo de um bloco de código multi­linhas válido:

   (aDay == 'Saturday' or aDay == 'Sunday') ? 
     daytype = 'weekend' :
     daytype = 'weekday' 

Unless

Ruby também pode executar testes unless, o qual é o oposto do teste if:

unless aDay == 'Saturday' or aDay == 'Sunday'
  daytype = 'weekday'
else 
  daytype = 'weekend'
end

Pense no unless com sendo uma forma alternativa de expressar 'if not'. O exemplo abaixo é equivalente ao código acima:

if !(aDay == 'Saturday' or aDay == 'Sunday')
  daytype = 'weekday'
else 
  daytype = 'weekend'
end

Modificadores If e Unless

Você pode rever a sintaxe alternativa para os laços while no Capítulo 7. Em vez de escrever isso…

while tired do sleep end 

… você pode escrever assim:

sleep while tired

Esta sintaxe alternativa, na qual a palavra­chave while é colocada entre o código a executar e a condição de teste é chamado de 'modificador while'. Dessa mesma forma, Ruby também possui modificadores if e unless. Aqui estão alguns exemplos:

sleep if tired
begin
  sleep
  snore
end if tired
sleep unless not tired
 
begin
  sleep
  snore
end unless not tired

A forma resumida desta sintaxe é útil quando, por exemplo, você repetidamente precisa tomar alguma ação bem definida se uma certa condição é verdadeira.

Aqui está como você poderia criticar o seu código através de depuração se uma constante DEBUG é verdadeira:

puts(&#8220;somevar = #{somevar}&#8221; ) if DEBUG

Declarações Case

Quando você precisa tomar uma variedade de diferentes ações baseado no valor de uma única variável, usar múltiplos testes if..elsif é verboso e repetitivo demais. Uma alternativa elegante é fornecida pela declaração case. Começa-­se com a palavra case seguido do nome da variável a testar. Então vem uma série de seções when, cada qual especifica um valor 'gatilho' seguido de algum código. Este código executa somente quando o valor da variável for igual ao valor 'gatilho':

case( i )
  when 1 : puts( &#8220;É segunda&#8221; )
  when 2 : puts( &#8220;É terça&#8221; )
  when 3 : puts( &#8220;É quarta&#8221; )
  when 4 : puts( &#8220;É quinta&#8221; )
  when 5 : puts( &#8220;É sexta&#8221; )
  when (6..7) : puts( &#8220;Oba! É fim de semana!&#8221; )
  else puts( &#8220;Não é um dia válido&#8221; )
end

No exemplo acima, E usei : para separar cada teste when do código a executar, alternativamente você poderá usar a palavra­chave then.

When 1 then puts( &#8220;É segunda&#8221; )

O sinal de dois pontos : ou o then pode ser omitido se o teste e o código a executar estão em linhas separadas. Diferentemente das declarações case em linguagens semelhantes ao C, não é necessário usar a palavra chave break numa seção cujo teste deu verdadeiro para evitar a execução das seções restantes.

Em Ruby, uma vez que um teste case deu verdadeiro a seção correspondente é executada e então a declaração case é encerrada.

case( i )
 when 5 : puts(&#8220;É sexta&#8221; )
    puts( &#8220;... o fim de semana está chegando!&#8221; )
  wen 6 : puts( &#8220;É sábado&#8221; )
    # O código seguinte nunca executa
 when 5 : puts(&#8220;É sexta novamente&#8221; )
end 

Você pode incluir muitas linhas de código entre cada condição when e você pode incluir múltiplos valores separados por vírgula para disparar um único bloco when, como este:

  when (6, 7) : puts( &#8220;Oba! É fim de semana!&#8221; )

A condição em uma declaração case não está obrigada a ser uma variável simples; pode ser uma expressão como esta:

case (i + 1)

Você também pode usar tipos não inteiros como uma string.

Se múltiplos valores gatilhos são especificados em uma seção when, eles podem ser de tipos variados – por exemplo, ambos string e inteiros:

when 1, 'Monday', 'Mon' : puts( &#8220;Epa, '#{i}' é segunda­feira&#8221; )

Aqui está um exemplo maior, ilustrando alguns dos elementos sintáticos mencionados recentemente:

case( i )
  when 1 : puts( &#8220;É segunda&#8221; )
  when 2 : puts( &#8220;É terça&#8221; )
  when 3 : puts( &#8220;É quarta&#8221; )
  when 4 : puts( &#8220;É quinta&#8221; )
  when 5 : puts( &#8220;É sexta&#8221; )
    puts( &#8220;... o fim de semana está chegando!&#8221; )
  when 6, 7) 
    puts( &#8220;É sábado&#8221; ) if i == 6
    puts( &#8220;É domingo&#8221; ) if i == 7
     puts( &#8220;Oba! É fim de semana!&#8221; )
   # O código seguinte nunca executa
   when 5 : puts(&#8220;É sexta novamente&#8221; )
 else puts( &#8220;Não é um dia válido&#8221; )
end

Anterior Índice Próximo

-- LeandroNunes - 18 Oct 2006
Topic revision: r1 - 05 Jul 2008, UnknownUser
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Wiki-Colivre? Send feedback