Używam tego kodu, aby pozwolić użytkownikowi na wprowadzanie nazw, podczas gdy program przechowuje je w tablicy, dopóki nie wprowadzi pustego ciągu (muszą nacisnąć Enter po każdej nazwie):
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
Ten kod wyglądałby znacznie ładniej w pętli do ... while:
people = []
do
info = gets.chomp
people += [Person.new(info)] if not info.empty?
while not info.empty?
W tym kodzie nie muszę przypisywać informacji do jakiegoś losowego ciągu.
Niestety ten typ pętli nie istnieje w Ruby. Czy ktoś może zaproponować lepszy sposób na zrobienie tego?
loop do; ...; break if ...; end
?Odpowiedzi:
UWAGA :
Został
begin <code> end while <condition>
odrzucony przez autora Ruby, Matza. Zamiast tego sugeruje użycieKernel#loop
npOto wymiana wiadomości e-mail z 23 listopada 2005 r., W której Matz stwierdza:
Wiki RosettaCode ma podobną historię:
źródło
begin end while
metoda wydawała się niewłaściwa. Dzięki za dostarczenie mi paszy, której potrzebowałem, aby przekonać resztę zespołu.Pierwotnie napisany przez Jeremy Voorhis . Treść została tutaj skopiowana, ponieważ wygląda na to, że została usunięta z witryny źródłowej. Kopie można również znaleźć w Archiwum internetowym i na forum Ruby Buzz . -Bill Jaszczurka
źródło
begin .. end
jest to trochę rozczarowane. Użyjloop do .. break if <condition>
zamiast tego.Lubię to:
Odniesienie: Ruby's Hidden do {} while () Loop
źródło
until info.empty?
zamiastwhile not info.empty?
.Co powiesz na to?
źródło
Oto pełny artykuł z martwego linku Hubbardra do mojego bloga.
Podczas czytania źródła
Tempfile#initialize
w bibliotece Ruby core znalazłem następujący fragment kodu :Na pierwszy rzut oka założyłem, że
while
modyfikator będzie oceniany przed zawartościąbegin...end
, ale tak nie jest. Przestrzegać:Jak można się spodziewać, pętla będzie nadal działać, dopóki modyfikator będzie prawdziwy.
Chociaż byłbym szczęśliwy, że nigdy więcej nie zobaczę tego idiomu,
begin...end
jest dość potężny. Poniższy typowy idiom zapamiętuje metodę jednowierszową bez parametrów:Oto brzydki, ale szybki sposób na zapamiętanie czegoś bardziej złożonego:
źródło
Działa to teraz poprawnie:
Ale może zostać usunięty w przyszłości, ponieważ
begin
oświadczenie jest sprzeczne z intuicją. Widzieć: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/6745Matz (Ruby's Creator) zalecił zrobienie tego w ten sposób:
źródło
Z tego, co zbieram, Matz nie lubi konstrukcji
ponieważ jego semantyka jest inna niż
w tym, że pierwsza konstrukcja najpierw wykonuje kod przed sprawdzeniem warunku, a druga konstrukcja najpierw sprawdza warunek, zanim wykona kod (jeśli w ogóle). Rozumiem, że Matz woli zachować drugą konstrukcję, ponieważ pasuje ona do konstrukcji liniowej instrukcji if.
Nigdy nie podobał mi się drugi konstrukt, nawet jeśli instrukcje. We wszystkich innych przypadkach komputer wykonuje kod od lewej do prawej (np. || i &&) od góry do dołu. Ludzie czytają kod od lewej do prawej od góry do dołu.
Zamiast tego sugeruję następujące konstrukcje:
Nie wiem, czy te sugestie zostaną przeanalizowane z resztą języka. Ale w każdym razie wolę zachować wykonanie od lewej do prawej, a także spójność językową.
źródło
źródło
while true
można go zastąpićloop do
.while true
można zastąpićloop do
. Ale przetestowałem obie konstrukcje z dużą ilością iteracji w pętli i odkryłem, żewhile true
jest to co najmniej 2x szybsza niżloop do
. Nie potrafię wyjaśnić różnicy, ale na pewno jest. (Odkryte podczas testowania Advent of Code 2017, dzień 15)Oto kolejny:
źródło
unless
jest na samym początku i nie czytam kawałków kodu (które mogą być więcej niż pokazane tutaj) tylko po to, aby znaleźć „wiszące”unless
na końcu. Jest ogólną zasadą w kodzie, że modyfikator i warunki są łatwiejsze w użyciu, gdy są „z góry” w ten sposób.źródło