여기 있습니다 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
나는 raise 사용에 대해 생각했지만 그것을 일반으로 만들려고 노력하고 있으므로에 특정 항목을 넣고 싶지 않습니다 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
이것이 제목 줄을 기준으로 여기에 오는 다음 Google 직원에게 도움이되기를 바랍니다.
답변
당신은 당신의 블록이 유용한 값 (예를 들어, 사용하는 경우 반환 할 경우 #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
-ing 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
답변
루비 블록에서 벗어나려면 단순히 return
키워드
를 사용하십시오return if value.nil?