Estou usando esse código para permitir que o usuário digite nomes enquanto o programa os armazena em uma matriz até que eles digitam uma string vazia (eles devem pressionar enter após cada nome):
people = []
info = 'a' # must fill variable with something, otherwise loop won't execute
while not info.empty?
info = gets.chomp
people += [Person.new(info)] if not info.empty?
end
Esse código ficaria muito melhor em um loop do ... while:
people = []
do
info = gets.chomp
people += [Person.new(info)] if not info.empty?
while not info.empty?
Nesse código, não preciso atribuir informações a uma sequência aleatória.
Infelizmente, esse tipo de loop parece não existir no Ruby. Alguém pode sugerir uma maneira melhor de fazer isso?
loop do; ...; break if ...; end
?Respostas:
ATENÇÃO :
O
begin <code> end while <condition>
argumento é rejeitado pelo autor de Ruby, Matz. Em vez disso, ele sugere usarKernel#loop
, por exemplo,Aqui está uma troca de e-mails em 23 de novembro de 2005, onde Matz declara:
O wiki do RosettaCode tem uma história semelhante:
fonte
begin end while
método não parecia certo. Obrigado por me dar a forragem de que precisava para convencer o resto da equipe.Originalmente escrito por Jeremy Voorhis . O conteúdo foi copiado aqui porque parece ter sido retirado do site de origem. Cópias também podem ser encontradas no Web Archive e no Ruby Buzz Forum . -Bill the Lizard
fonte
begin .. end
é um tanto desaprovado. Use emloop do .. break if <condition>
vez disso.Como isso:
Referência: Ruby Hidden do {} while () Loop
fonte
until info.empty?
vez dewhile not info.empty?
.Que tal agora?
fonte
Aqui está o artigo em texto completo do link morto do hubbardr para o meu blog.
Encontrei o seguinte trecho ao ler a fonte
Tempfile#initialize
na biblioteca principal do Ruby:À primeira vista, presumi que o
while
modificador seria avaliado antes do conteúdo debegin...end
, mas esse não é o caso. Observar:Como seria de esperar, o loop continuará sendo executado enquanto o modificador for verdadeiro.
Enquanto eu ficaria feliz em nunca ver esse idioma novamente,
begin...end
é bastante poderoso. A seguir, é apresentado um idioma comum para memorizar um método de uma linha sem parâmetros:Aqui está uma maneira feia, mas rápida, de memorizar algo mais complexo:
fonte
Isso funciona corretamente agora:
Mas, pode ser removido no futuro, porque a
begin
declaração é contra-intuitiva. Veja: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/6745Matz (Ruby's Creator) recomendou fazer o seguinte:
fonte
Pelo que entendi, Matz não gosta da construção
porque, é semântica é diferente de
em que a primeira construção executa o código primeiro antes de verificar a condição e a segunda construção testa a condição primeiro antes de executar o código (se houver). Suponho que Matz prefere manter o segundo construto porque ele corresponde a um construto de linha das instruções if.
Eu nunca gostei da segunda construção, mesmo para declarações if. Em todos os outros casos, o computador executa o código da esquerda para a direita (por exemplo, || e &&) de cima para baixo. Os seres humanos leem o código da esquerda para a direita, de cima para baixo.
Sugiro as seguintes construções:
Não sei se essas sugestões serão analisadas com o restante do idioma. Mas, em qualquer caso, prefiro manter a execução da esquerda para a direita, além da consistência da linguagem.
fonte
fonte
while true
pode ser substituído porloop do
.while true
pode ser substituído porloop do
. Mas testei as duas construções com muitas iterações dentro do loop e descobri quewhile true
é pelo menos duas vezes mais rápido queloop do
. Não posso explicar a diferença, mas está definitivamente lá. (Descoberto ao testar o Advent of Code 2017, dia 15.)Aqui está mais um:
fonte
unless
está logo no início e não leio um monte de código (que pode ser mais do que mostrado aqui) apenas para encontrar um 'pendente'unless
no final. É um princípio geral no código que o modificador e as condições são mais fáceis de usar quando estão "na frente" assim.fonte