Ruby usa a case
expressão .
case x
when 1..5
"It's between 1 and 5"
when 6
"It's 6"
when "foo", "bar"
"It's either foo or bar"
when String
"You passed a string"
else
"You gave me #{x} -- I have no idea what to do with that."
end
Ruby compara o objeto na when
cláusula com o objeto na case
cláusula usando o ===
operador. Por exemplo,, 1..5 === x
e não x === 1..5
.
Isso permite when
cláusulas sofisticadas, como visto acima. Intervalos, classes e todo tipo de coisa podem ser testados em vez de apenas igualdade.
Diferentemente das switch
declarações em muitos outros idiomas, o Ruby case
não tem falhas , portanto, não há necessidade de terminar cada when
um com a break
. Você também pode especificar várias correspondências em uma única when
cláusula, como when "foo", "bar"
.
when
ereturn
na mesma linha:when "foo" then "bar"
switch
declarações em muitos outros idiomas, o Ruby'scase
NÃO possui falhas , portanto, não há necessidade de terminar cadawhen
um com abreak
.then
. Por favor, veja também as outras respostas.case...when
se comporta um pouco inesperadamente ao lidar com classes. Isso se deve ao fato de ele usar o===
operador.Esse operador trabalha como esperado com literais, mas não com classes:
Isso significa que se você quiser fazer uma
case ... when
classe sobre um objeto, isso não funcionará:Irá imprimir "Não é uma string ou número".
Felizmente, isso é facilmente resolvido. O
===
operador foi definido para que retornetrue
se você o usar com uma classe e fornecer uma instância dessa classe como o segundo operando:Em resumo, o código acima pode ser corrigido removendo o
.class
:Encontrei esse problema hoje ao procurar uma resposta, e essa foi a primeira página que apareceu, então achei que seria útil para outras pessoas na mesma situação.
fonte
.class
parte É interessante notar, obrigado. Claro, esse é um comportamento inteiramente apropriado (embora eu pudesse ver como seria um erro comum pensar que isso seria impressoIt is a string
) ... você está testando a classe de algum objeto arbitrário, não o próprio objeto. Assim, por exemplo:case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" end
resulta em:"Class!"
Isso funciona da mesma para1.class
,{}.class
, etc. deixando cair.class
, temos"String!"
ou"Something else"
para estes vários valores.Isso é feito usando
case
Ruby. Veja também " Alternar declaração " na Wikipedia.Citado:
Outro exemplo:
Na página 123 da Linguagem de programação Ruby (1ª edição, O'Reilly) no meu Kindle, ele diz que a
then
palavra - chave após aswhen
cláusulas pode ser substituída por uma nova linha ou ponto e vírgula (como naif then else
sintaxe). (O Ruby 1.8 também permite dois pontos no lugar dethen
, mas essa sintaxe não é mais permitida no Ruby 1.9.)fonte
when (-1.0/0.0)..-1 then "Epic fail"
type = #{score}
cada linha, posso simplesmente copiar o que você fez. Muito mais elegante que eu também gosto do one-liners muito melhor (se possível)caso ... quando
Para adicionar mais exemplos à resposta de Chuck :
Com parâmetro:
Sem parâmetro:
Por favor, esteja ciente de " Como escrever uma instrução switch em Ruby " sobre a qual o kikito alerta.
fonte
or
Muitas linguagens de programação, especialmente as derivadas de C, têm suporte para o chamado Switch Fallthrough . Eu estava procurando a melhor maneira de fazer o mesmo no Ruby e achei que poderia ser útil para outras pessoas:
Em idiomas do tipo C, o avanço geralmente se parece com isso:
No Ruby, o mesmo pode ser alcançado da seguinte maneira:
Isso não é estritamente equivalente, porque não é possível
'a'
executar um bloco de código antes de passar para'b'
ou'c'
, mas, na maioria das vezes, acho semelhante o suficiente para ser útil da mesma maneira.fonte
No Ruby 2.0, você também pode usar lambdas em
case
instruções, da seguinte maneira:Você também pode criar seus próprios comparadores facilmente usando um Struct com um personalizado
===
(Exemplo extraído de "Os procs podem ser usados com instruções de caso no Ruby 2.0? ".)
Ou, com uma aula completa:
(Exemplo retirado de " Como uma declaração de caso Ruby funciona e o que você pode fazer com ela ".)
fonte
Você pode usar expressões regulares, como encontrar um tipo de sequência:
Ruby
case
usará o operando de igualdade===
para isso (obrigado @ JimDeville). Informações adicionais estão disponíveis em " Ruby Operators ". Isso também pode ser feito usando o exemplo @mmdemirbas (sem parâmetro), apenas essa abordagem é mais limpa para esses tipos de casos.fonte
Se você está ansioso para saber como usar uma condição OR em um caso de switch Ruby:
Portanto, em uma
case
declaração, a,
é equivalente a||
em umaif
declaração.Consulte " Como uma declaração de caso Ruby funciona e o que você pode fazer com ela ".
fonte
É chamado
case
e funciona como você esperaria, além de muito mais coisas divertidas, cortesia da===
qual implementa os testes.Agora, para se divertir:
E acontece que você também pode substituir uma cadeia if / else arbitrária (ou seja, mesmo que os testes não envolvam uma variável comum)
case
deixando de fora ocase
parâmetro inicial e escrevendo expressões onde a primeira correspondência é o que você deseja.fonte
Ruby usa o
case
para escrever instruções de opção.Conforme a
case
documentação:Exemplo:
Versão mais curta:
E como " declaração de caso de Ruby - técnicas avançadas " descreve Ruby
case
;Pode ser usado com intervalos :
Pode ser usado com o Regex :
Pode ser usado com Procs e Lambdas :
Além disso, pode ser usado com suas próprias classes de correspondência:
fonte
Dependendo do seu caso, você pode preferir usar um hash de métodos.
Se houver uma longa lista de se
when
cada um deles tiver um valor concreto para comparar (não um intervalo), será mais eficaz declarar um hash de métodos e depois chamar o método relevante a partir desse hash.fonte
Como
switch case
sempre retorna um único objeto, podemos imprimir diretamente seu resultado:fonte
Caso com vários valores quando e sem valor:
E uma solução de expressão regular aqui:
fonte
case some_string, when /\d/, (stuff), when /[a-zA-Z]/, (stuff), end
(onde,
os meios de nova linha)Você pode escrever
case
expressões de duas maneiras diferentes no Ruby:if
declaraçõescase
cadawhen
cláusula é comparada ao destino.ou:
fonte
Você pode fazer isso de maneira mais natural,
fonte
Muitas ótimas respostas, mas pensei em adicionar um factóide. Se você estiver tentando comparar objetos (Classes), verifique se você tem um método de nave espacial (não uma piada) ou entenda como eles estão sendo comparados.
" Igualdade de Ruby e comparação de objetos " é uma boa discussão sobre o assunto.
fonte
<=>
é usado para retornar -1, 0, 1 ou zero, dependendo se a comparação retorna menos que, igual, maior que ou não comparável, respectivamente. A documentação do módulo Comparable do Ruby explica isso.Conforme declarado em muitas das respostas acima, o
===
operador é usado sob o capôcase
/when
declarações.Aqui estão informações adicionais sobre esse operador:
Operador de igualdade de caso:
===
Muitas das classes internas do Ruby, como String, Range e Regexp, fornecem suas próprias implementações do
===
operador, também conhecidas como "igualdade de caso", "igual a triplo" ou "três a igual". Como é implementado de maneira diferente em cada classe, ele se comportará de maneira diferente, dependendo do tipo de objeto em que foi chamado. Geralmente, ele retornará true se o objeto à direita "pertencer a" ou "for um membro" do objeto à esquerda. Por exemplo, ele pode ser usado para testar se um objeto é uma instância de uma classe (ou uma de suas subclasses).O mesmo resultado pode ser alcançado com outros métodos que provavelmente são mais adequados para o trabalho, como
is_a?
einstance_of?
.Implementação de Gama de
===
Quando o
===
operador é chamado em um objeto de intervalo, ele retorna true se o valor à direita estiver dentro do intervalo à esquerda.Lembre-se de que o
===
operador chama o===
método do objeto esquerdo. Então(1..4) === 3
é equivalente a(1..4).=== 3
. Em outras palavras, a classe do operando esquerdo definirá qual implementação do===
método será chamada, de modo que as posições do operando não serão intercambiáveis.Implementação Regexp de
===
Retorna true se a sequência à direita corresponder à expressão regular à esquerda.
A única diferença relevante entre os dois exemplos acima é que, quando há uma correspondência,
===
retorna true e=~
retorna um número inteiro, que é um valor verdadeiro em Ruby. Voltaremos a isso em breve.fonte
fonte
Consulte " Ruby - se ... mais, caso, a menos " para obter mais informações.
fonte
Comecei a usar:
Ajuda o código compacto em alguns casos.
fonte
Hash
umacase
instrução , e não uma instrução.Não há suporte para expressões regulares em seu ambiente? Por exemplo, Editor de scripts do Shopify (abril de 2018):
Uma solução alternativa após uma combinação de métodos já abordados anteriormente aqui e aqui :
Eu usei
or
s na instrução de método de classe, pois||
tem maior precedência que.include?
. Se você é um rubi-nazista , imagine que eu usei isso(item.include? 'A') || ...
. teste repl.it.fonte
É essencial enfatizar a vírgula (
,
) em umawhen
cláusula. Ele atua como um||
de umaif
declaração, ou seja, ele faz um OR comparação e não um E comparação entre as expressões delimitados dawhen
cláusula. Veja a seguinte declaração de caso:x
não é menor que 2, mas o valor de retorno é"apple"
. Por quê? Porquex
tinha 3 anos e desde',`` acts as an
||, it did not bother to evaluate the expression
x <2 '.Você pode pensar que, para executar um AND , pode fazer algo como isto abaixo, mas não funciona:
Não funciona porque é
(3 && x > 2)
avaliado como verdadeiro, e Ruby pega o valor True e o comparax
com o===
que não é verdadeiro, poisx
é 3.Para fazer uma
&&
comparação, você terá que tratarcase
como um blocoif
/else
:No livro Ruby Programming Language, Matz diz que esse último formulário é simples (e raramente usado), que nada mais é do que uma sintaxe alternativa para
if
/elsif
/else
. No entanto, se é pouco usado ou não, não vejo outra maneira de anexar várias&&
expressões para uma determinadawhen
cláusula.fonte
if...elsif
? Parece que você está tentando misturar uma declaração de caso e uma condição. Por quê? Basta colocar a condicional dentro do bloco when, por exemplo.when 3; ( x < 2 ) ? 'apple' : 'orange'
Podemos escrever a instrução switch para várias condições.
Por exemplo,
fonte
case
,when
,end
) São maiúsculas de minúsculas e não pode ser maiúscula como esta.NoMethodError (undefined method
CASE 'para main: Object) `. Como @ sondra.kinsey disse, você não pode usar maiúsculas. Ruby achará que é um CONSTANTE.O
case
operador de instrução é comoswitch
nos outros idiomas.Esta é a sintaxe de
switch...case
em C:Esta é a sintaxe do
case...when
Ruby:Por exemplo:
Para mais informações, consulte a
case
documentação.fonte