루비 블록에서 탈출하는 방법은?
여기 있습니다Bar#do_things
:
class Bar
def do_things
Foo.some_method(x) do |x|
y = x.do_something
return y_is_bad if y.bad? # how do i tell it to stop and return do_things?
y.do_something_else
end
keep_doing_more_things
end
end
그리고 여기 있습니다.Foo#some_method
:
class Foo
def self.some_method(targets, &block)
targets.each do |target|
begin
r = yield(target)
rescue
failed << target
end
end
end
end
인상을 사용하려고 생각했지만, 일반적으로 만들려고 노력하고 있기 때문에 특정한 것을 넣고 싶지 않습니다.Foo
.
키워드 사용next
다음 항목으로 계속 진행하지 않으려면 다음을 사용합니다.break
.
언제next
를 사용하면 블록이 즉시 종료되고 제어가 반복기 메서드로 되돌아갑니다. 그러면 다시 블록을 호출하여 새 반복을 시작할 수 있습니다.
f.each do |line| # Iterate over the lines in file f
next if line[0,1] == "#" # If this line is a comment, go to the next
puts eval(line)
end
블록에서 사용할 경우,break
는 컨트롤을 블록 밖으로, 블록을 호출한 반복기 밖으로, 반복기 호출 후 첫 번째 식으로 전송합니다.
f.each do |line| # Iterate over the lines in file f
break if line == "quit\n" # If this break statement is executed...
puts eval(line)
end
puts "Good bye" # ...then control is transferred here
그리고 마지막으로, 의 사용법은return
블록 내:
return
블록 내에 얼마나 깊이 내포되어 있는지에 관계없이 항상 둘러싸는 방법을 반환합니다(람다의 경우 제외).
def find(array, target)
array.each_with_index do |element,index|
return index if (element == target) # return from find
end
nil # If we didn't find the element, return nil
end
저는 단지 블록을 뚫고 나갈 수 있기를 원했습니다. 일종의 전진처럼 말이죠. 루프와 관련이 없습니다.사실, 저는 루프를 종료하지 않고 루프에 있는 블록을 절단하고 싶습니다.이를 위해 블록을 1회 반복 루프로 만들었습니다.
for b in 1..2 do
puts b
begin
puts 'want this to run'
break
puts 'but not this'
end while false
puts 'also want this to run'
end
이것이 주제 라인을 기반으로 여기에 도착하는 다음 구글러에게 도움이 되기를 바랍니다.
블록이 유용한 값을 반환하도록 하려면(예: 사용 시)#map
,#inject
등),next
그리고.break
인수도 수락합니다.
다음 사항을 고려합니다.
def contrived_example(numbers)
numbers.inject(0) do |count, x|
if x % 3 == 0
count + 2
elsif x.odd?
count + 1
else
count
end
end
end
동등한 용도next
:
def contrived_example(numbers)
numbers.inject(0) do |count, x|
next count if x.even?
next (count + 2) if x % 3 == 0
count + 1
end
end
물론 필요한 논리를 항상 메서드에 추출하여 블록 내부에서 호출할 수 있습니다.
def contrived_example(numbers)
numbers.inject(0) { |count, x| count + extracted_logic(x) }
end
def extracted_logic(x)
return 0 if x.even?
return 2 if x % 3 == 0
1
end
키워드를 사용합니다.break
대신에return
아마도 당신은 배열에서 특정한 항목을 찾기 위해 내장된 메소드를 사용할 수 있을 것입니다.each
-잉targets
손으로 모든 것을 하는 것.몇 가지 예:
class Array
def first_frog
detect {|i| i =~ /frog/ }
end
def last_frog
select {|i| i =~ /frog/ }.last
end
end
p ["dog", "cat", "godzilla", "dogfrog", "woot", "catfrog"].first_frog
# => "dogfrog"
p ["hats", "coats"].first_frog
# => nil
p ["houses", "frogcars", "bottles", "superfrogs"].last_frog
# => "superfrogs"
한 가지 예로 다음과 같은 작업을 수행할 수 있습니다.
class Bar
def do_things
Foo.some_method(x) do |i|
# only valid `targets` here, yay.
end
end
end
class Foo
def self.failed
@failed ||= []
end
def self.some_method(targets, &block)
targets.reject {|t| t.do_something.bad? }.each(&block)
end
end
next
그리고.break
이 단순화된 예에서 옳은 일을 하는 것처럼 보입니다!
class Bar
def self.do_things
Foo.some_method(1..10) do |x|
next if x == 2
break if x == 9
print "#{x} "
end
end
end
class Foo
def self.some_method(targets, &block)
targets.each do |target|
begin
r = yield(target)
rescue => x
puts "rescue #{x}"
end
end
end
end
Bar.do_things
출력: 1 3 4 5 6 7 8
스택을 '비 예외적'인 방법으로 풀 수 있는 네 가지 방법이 있습니다.next
,break
,return
,그리고.throw
.
next
블록이 반환됩니다.
break
블록에 양보한 메서드가 반환됩니다.
return
블록이 정의된 메서드를 반환합니다.
throw
다음을 찾을 때까지 스택을 가로질러 이동합니다.catch
일치하는 기호와 함께, 그리고 그것을 되돌립니다.이는 예외적이지 않은 상황에 대한 '경량' 예외와 매우 유사합니다.
이들은 모두 정상적으로 반환되는 마지막 식 값 대신 반환되는 반환 값을 취할 수 있습니다.
다음은 몇 가지 예입니다.
def doSomething
puts "> doSomething"
yield
puts "< doSomething"
end
def withNext
puts "> withNext"
doSomething do
puts "> block"
puts "* NEXT! causes the block to return to doSomething"
next
puts "< block"
end
puts "< withNext"
end
def withBreak
puts "> withBreak"
doSomething do
puts "> block"
puts "* BREAK! causes doSomething to return to withBreak"
break
puts "< block"
end
puts "< withBreak"
end
def withReturn
puts "> withReturn"
doSomething do
puts "> block"
puts "* RETURN! causes withReturn to return"
return
puts "< block"
end
puts "< withReturn"
end
def withThrow
puts "> withThrow"
catch :label do
puts "> catch :label"
doSomething do
puts "> block 1"
doSomething do
puts "> block 2"
puts "* THROW! causes catch :label to return to withThrow"
throw :label
puts "< block 2"
end
puts "< block 1"
end
puts "< catch :label"
end
puts "< withThrow"
end
withNext
puts "* Done"
puts
withBreak
puts "* Done"
puts
withReturn
puts "* Done"
puts
withThrow
puts "* Done"
출력:
> withNext
> doSomething
> block
* NEXT! causes the block to return to doSomething
< doSomething
< withNext
* Done
> withBreak
> doSomething
> block
* BREAK! causes doSomething to return to withBreak
< withBreak
* Done
> withReturn
> doSomething
> block
* RETURN! causes withReturn to return
* Done
> withThrow
> catch :label
> doSomething
> block 1
> doSomething
> block 2
* THROW! causes catch :label to return to withThrow
< withThrow
* Done
루비 블록에서 벗어나려면 키워드를 사용하면 됩니다. next
.
next
람다, 블럭 또는 procit가 들어 있는 것을 종료합니다.break
블록에 양보하거나 블록이 있는 프로세서 람다를 호출한 메서드를 종료합니다.
언급URL : https://stackoverflow.com/questions/1402757/how-to-break-out-from-a-ruby-block
'programing' 카테고리의 다른 글
루비 - 아직 배열이 아닌 경우 변수를 배열로 우아하게 변환합니다). (0) | 2023.06.01 |
---|---|
아이폰처럼 HTML 텍스트 입력 상자에 클리어 버튼을 넣으려면 어떻게 해야 합니까? (0) | 2023.06.01 |
JVM 대상 1.8로 빌드된 바이트 코드를 JVM 대상 1.6으로 빌드되는 바이트 코드로 인라인할 수 없습니다. (0) | 2023.06.01 |
실제 사용된 범위 가져오기 (0) | 2023.06.01 |
Gem 중에 확인되지 않은 사양:Specification.reset: (0) | 2023.06.01 |