prosource

"도..."가 있습니까?루비의 루프?

probook 2023. 6. 12. 21:34
반응형

"도..."가 있습니까?루비의 루프?

프로그램이 빈 문자열을 입력할 때까지 사용자가 배열에 저장하는 동안 사용자가 이름을 입력할 수 있도록 이 코드를 사용합니다(각 이름 뒤에 Enter 키를 눌러야 함).

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

이 코드는 도(do)에서 훨씬 더 멋져 보일 것입니다.루프하는 동안:

people = []

do
    info = gets.chomp
    people += [Person.new(info)] if not info.empty?
while not info.empty?

이 코드에서는 임의 문자열에 정보를 할당할 필요가 없습니다.

안타깝게도 루비에는 이런 루프가 존재하지 않는 것 같습니다.누가 이것을 하는 더 나은 방법을 제안할 수 있습니까?

주의:

begin <code> end while <condition>Ruby의 작가 Matz에 의해 거부되었습니다.대신에 그는 사용할 것을 제안합니다.Kernel#loop,예.

loop do 
  # some code here
  break if <condition>
end 

다음은 2005년 11월 23일에 있었던 이메일 교환입니다. Matz는 다음과 같이 말합니다.

|> Don't use it please.  I'm regretting this feature, and I'd like to
|> remove it in the future if it's possible.
|
|I'm surprised.  What do you regret about it?

Because it's hard for users to tell

  begin <code> end while <cond>

works differently from

  <code> while <cond>

로제타코드 위키에도 비슷한 이야기가 있습니다.

2005년 11월 루비를 만든 마츠모토 유키히로는 이 루프 기능을 후회하며 커널#루프를 사용할 것을 제안했습니다.

소스를 읽는 동안 다음 스니펫을 발견했습니다.Tempfile#initializeRuby 코어 라이브러리:

begin
  tmpname = File.join(tmpdir, make_tmpname(basename, n))
  lock = tmpname + '.lock'
  n += 1
end while @@cleanlist.include?(tmpname) or
  File.exist?(lock) or File.exist?(tmpname)

언뜻 보기에 begin...end의 내용 전에 while 수식어가 평가될 것이라고 생각했지만 그렇지 않습니다.관찰:

>> begin
?>   puts "do {} while ()" 
>> end while false
do {} while ()
=> nil

예상대로, 수정자가 참인 동안 루프가 계속 실행됩니다.

>> n = 3
=> 3
>> begin
?>   puts n
>>   n -= 1
>> end while n > 0
3
2
1
=> nil

이 관용구를 다시는 볼 수 없게 되어 기쁘지만, 시작... 끝은 꽤 강력합니다.다음은 매개 변수가 없는 한 줄 방법을 메모하는 일반적인 관용구입니다.

def expensive
  @expensive ||= 2 + 2
end

여기 좀 더 복잡한 것을 기억하는 추악하지만 빠른 방법이 있습니다.

def expensive
  @expensive ||=
    begin
      n = 99
      buf = "" 
      begin
        buf << "#{n} bottles of beer on the wall\n" 
        # ...
        n -= 1
      end while n > 0
      buf << "no more bottles of beer" 
    end
end

원작은 Jeremy Voorhis입니다.원본 사이트에서 내용이 삭제된 것 같아 여기에 복사되었습니다.사본은 웹 아카이브Ruby Buzz Forum에서도 찾을 수 있습니다. - Bill the Lizard

다음과 같이:

people = []

begin
  info = gets.chomp
  people += [Person.new(info)] if not info.empty?
end while not info.empty?

참조:() 루프 동안 루비의 숨겨진 행동 {}

이건 어때?

people = []

until (info = gets.chomp).empty?
  people += [Person.new(info)]
end

여기 허버드가 제 블로그에 연결한 데드 링크의 전문은 다음과 같습니다.

소스를 읽는 동안 다음 스니펫을 발견했습니다.Tempfile#initializeRuby 코어 라이브러리:

begin
  tmpname = File.join(tmpdir, make_tmpname(basename, n))
  lock = tmpname + '.lock'
  n += 1
end while @@cleanlist.include?(tmpname) or
  File.exist?(lock) or File.exist?(tmpname)

언뜻 보기에, 나는 생각했습니다.while수식어는 다음의 내용보다 먼저 평가됩니다.begin...end하지만 사실은 그렇지 않습니다.관찰:

>> begin
?>   puts "do {} while ()" 
>> end while false
do {} while ()
=> nil

예상대로, 수정자가 참인 동안 루프가 계속 실행됩니다.

>> n = 3
=> 3
>> begin
?>   puts n
>>   n -= 1
>> end while n > 0
3
2
1
=> nil

이 관용구를 다시는 볼 수 없게 되어 기쁘지만,begin...end상당히 강력합니다.다음은 매개 변수가 없는 한 줄 방법을 메모하는 일반적인 관용구입니다.

def expensive
  @expensive ||= 2 + 2
end

여기 좀 더 복잡한 것을 기억하는 추악하지만 빠른 방법이 있습니다.

def expensive
  @expensive ||=
    begin
      n = 99
      buf = "" 
      begin
        buf << "#{n} bottles of beer on the wall\n" 
        # ...
        n -= 1
      end while n > 0
      buf << "no more bottles of beer" 
    end
end

이제 올바르게 작동합니다.

begin
    # statment
end until <condition>

하지만, 그것은 미래에 제거될 수도 있습니다,begin문이 반직관적입니다.참조: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/6745

Matz(Ruby's Creator)는 다음과 같이 권장했습니다.

loop do
    # ...
    break if <condition>
end

제가 알기로는, Matz는 그 건축물을 좋아하지 않습니다.

begin
    <multiple_lines_of_code>
end while <cond>

왜냐하면, 의미론은 다른 것이기 때문입니다.

<single_line_of_code> while <cond>

첫 번째 구성이 조건을 확인하기 전에 먼저 코드를 실행하고, 두 번째 구성이 코드를 실행하기 전에 먼저 조건을 테스트한다는 것입니다(있는 경우).Matz는 if 문의 한 줄 구조와 일치하기 때문에 두 번째 구조를 유지하는 것을 선호합니다.

나는 if 진술을 하더라도 두 번째 구성이 마음에 들지 않았습니다.다른 모든 경우 컴퓨터는 코드를 왼쪽에서 오른쪽으로 실행합니다(예:그리고 &&) 위에서 아래로.인간은 코드를 왼쪽에서 오른쪽으로 위에서 아래로 읽습니다.

대신 다음 구성을 제안합니다.

if <cond> then <one_line_code>      # matches case-when-then statement

while <cond> then <one_line_code>

<one_line_code> while <cond>

begin <multiple_line_code> end while <cond> # or something similar but left-to-right

저는 그 제안들이 나머지 언어들과 이해가 될지 모르겠습니다.하지만 어떤 경우에도 저는 언어의 일관성뿐만 아니라 왼쪽에서 오른쪽으로 실행하는 것을 선호합니다.

a = 1
while true
  puts a
  a += 1
  break if a > 10
end

여기 또 다른 것이 있습니다.

people = []
1.times do
  info = gets.chomp
  unless info.empty? 
    people += [Person.new(info)]
    redo
  end
end
ppl = []
while (input=gets.chomp)
 if !input.empty?
  ppl << input
 else
 p ppl; puts "Goodbye"; break
 end
end

언급URL : https://stackoverflow.com/questions/136793/is-there-a-do-while-loop-in-ruby

반응형