programing

Ruby에서 외부주기를 끊는 방법은 무엇입니까?

nasanasas 2021. 1. 9. 10:10
반응형

Ruby에서 외부주기를 끊는 방법은 무엇입니까?


Perl에는 다음과 같이 외부주기를 중단하는 기능이 있습니다.

AAA: for my $stuff (@otherstuff) {
         for my $foo (@bar) {
             last AAA if (somethingbad());
         }
      }

(구문이 잘못되었을 수 있음), 루프 레이블을 사용하여 내부 루프 내부에서 외부 루프를 끊습니다. Ruby에도 비슷한 것이 있습니까?


원하는 것은 비 로컬 제어 흐름이며 Ruby에는 여러 가지 옵션이 있습니다.

  • 연속,
  • 예외 및
  • throw/catch

연속

장점 :

  • 연속은 로컬이 아닌 제어 흐름을위한 표준 메커니즘입니다. 사실, 당신은 구축 할 수 있는 그 위에 비 로컬 제어 흐름 (서브 루틴, 절차, 기능, 방법, 코 루틴, 상태 머신, 발전기, 조건, 예외) : 그들은 꽤 많이 좋네요 트윈입니다 GOTO.

단점 :

  • 연속은 Ruby 언어 사양의 필수 부분이 아니므로 일부 구현 (XRuby, JRuby, Ruby.NET, IronRuby)이이를 구현하지 않습니다. 따라서 당신은 그들에게 의지 할 수 없습니다.

예외

장점 :

  • 예외가 Continuations보다 더 강력 할 수 있음을 수학적으로 증명하는 논문이 있습니다. IOW : 그들은 연속이 할 수있는 모든 것을 할 수 있고, 그래서 당신은 연속을 대신 할 수 있습니다.
  • 예외는 보편적으로 사용 가능합니다.

단점 :

  • 사람들이 "예외 상황에서만"이라고 생각하게 만드는 "예외"라고합니다. 이것은 세 가지를 의미합니다. 코드를 읽는 사람이 코드를 이해하지 못할 수도 있고 구현이 최적화되지 않았을 수도 있고 (예, 거의 모든 Ruby 구현에서 예외 엄청나게 느립니다) 최악의 경우, 그 모든 사람들에게 질리게 될 것입니다. 코드를 훑어 보자 마자 끊임없이 "예외는 예외적 인 상황에서만 발생한다"는 말을 듣지 않습니다. (물론 그들은 당신이하는 일을 이해하려하지도 않을 것입니다.)

throw/catch

(대략) 다음과 같습니다.

catch :aaa do
  stuff.each do |otherstuff|
    foo.each do |bar|
      throw :aaa if somethingbad
    end
  end
end

장점 :

  • 예외와 동일합니다.
  • Ruby 1.9에서 제어 흐름에 예외를 사용하는 것은 실제로 언어 사양의 일부입니다 ! 루프, 열거 자, 반복기 등은 모두 StopIteration종료에 예외를 사용합니다 .

단점 :

  • Ruby 커뮤니티는 제어 흐름에 예외를 사용하는 것보다 훨씬 더 싫어합니다.

고려 throw/catch . 일반적으로 아래 코드의 외부 루프는 5 번 실행되지만 throw를 사용하면 원하는대로 변경하여 프로세스를 중단 할 수 있습니다. 이 완벽하게 유효한 루비 코드를 고려하십시오.

catch (:done) do
  5.times { |i|
    5.times { |j|
      puts "#{i} #{j}"
      throw :done if i + j > 5
    }
  }
end

아니, 없습니다.

옵션은 다음과 같습니다.

  • 메서드에 루프를 넣고 return을 사용하여 외부 루프에서 끊기
  • 내부 루프에서 플래그를 설정하거나 반환 한 다음 외부 루프에서 해당 플래그를 확인하고 플래그가 설정되면 해당 플래그를 중단합니다 (이는 다소 번거 롭습니다).
  • 던지기 / 잡기를 사용하여 루프에서 벗어나십시오.

while c1
 while c2
    do_break=true
 end
 next if do_break
end

or "break if do_break" depending on what you want


Perhaps this is what you want? (not tested)

stuff.find do |otherstuff|
  foo.find do
    somethingbad() && AAA
  end
end

The find method keeps looping until the block returns a non null value or the end of the list is hit.


I know I will regret this in the morning but simply using a while loop could do the trick.

x=0
until x==10
  x+=1
  y=0
  until y==10
    y+=1
    if y==5 && x==3
      x,y=10,10
    end
  end
  break if x==10
  puts x
end

The if y==5 && x==3 is only an example of an expression turning true.


Wrapping an internal method around the loops could do the trick Example:

test = [1,2,3]
test.each do |num|
  def internalHelper
    for i in 0..3 
      for j in 0..3
        puts "this should happen only 3 times"
        if true
          return
        end
      end
    end
  end
internalHelper
end

Here you can do a check inside any of the for loops and return from the internal method once a condition is met.


You may consider adding a flag, which is set inside the inner loop, for controlling the outer loop.

'next' the outer loop

for i in (1 .. 5)
  next_outer_loop = false
  for j in (1 .. 5)
    if j > i     
      next_outer_loop = true if j % 2 == 0
      break      
    end          
    puts "i: #{i}, j: #{j}"
  end            
  print "i: #{i} "                                                                                                                                                                             
  if next_outer_loop
    puts "with 'next'"
    next         
  end            
  puts "withOUT 'next'"
end

'break' the outer loop

for i in (1 .. 5)
  break_outer_loop = false
  for j in (1 .. 5)
    if j > i
      break_outer_loop = true if i > 3
      break
    end
    puts "i: #{i}, j: #{j}"
  end
  break if break_outer_loop
  puts "i: #{i}"
end

ReferenceURL : https://stackoverflow.com/questions/1352120/how-to-break-outer-cycle-in-ruby

반응형