문제

이 코드를 사용하여 사용자가 이름을 입력 할 수 있도록 프로그램이 빈 문자열을 입력 할 때까지 배열에 저장할 수 있습니다 (각 이름 뒤에 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에서 훨씬 더 멋지게 보일 것입니다 ... While Loop :

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>

Rosettacode Wiki 비슷한 이야기가 있습니다.

2005 년 11 월 루비의 제작자 인 유키히로 마츠모토 (Yukihiro Matsumoto)는이 루프 기능을 후회하고 커널#루프를 사용하여 제안했습니다.

다른 팁

소스를 읽는 동안 다음 스 니펫을 찾았습니다. Tempfile#initialize 루비 코어 라이브러리에서 :

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
?>   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

나는이 관용구를 다시는 보지 못하게되어 기쁘지만 시작은 ... 끝은 매우 강력합니다. 다음은 매개 변수가없는 1 라이너 메소드를 추억화하는 일반적인 관용구입니다.

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. 콘텐츠는 원래 사이트에서 내려진 것으로 보이므로 여기에서 복사되었습니다. 사본도 찾을 수 있습니다 웹 아카이브 그리고 at 루비 버즈 포럼. -도마뱀을 빌리십시오

이와 같이:

people = []

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

참조: Ruby 's Hidden do {} while () loop

이건 어때?

people = []

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

다음은 Hubbardr의 Dead 링크에 대한 전체 텍스트 기사입니다.

소스를 읽는 동안 다음 스 니펫을 찾았습니다. Tempfile#initialize 루비 코어 라이브러리에서 :

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 매우 강력합니다. 다음은 매개 변수가없는 1 라이너 메소드를 추억화하는 일반적인 관용구입니다.

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는 이런 식으로 그렇게 할 것을 권장했습니다.

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

내가 수집 한 것에서 Matz는 구조물을 좋아하지 않습니다.

begin
    <multiple_lines_of_code>
end while <cond>

의미론은 다르기 때문입니다

<single_line_of_code> while <cond>

첫 번째 구성은 조건을 확인하기 전에 코드를 먼저 실행하고 두 번째 구성은 코드를 실행하기 전에 먼저 조건을 테스트합니다 (지금은). IT 문의 한 줄 구성과 일치하기 때문에 MATZ는 두 번째 구성을 유지하는 것을 선호합니다.

나는 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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top