Как мне сделать ранний возврат в ruby, чтобы уменьшить вложенность if? - PullRequest
0 голосов
/ 21 декабря 2018

Я всегда использую ранний возврат, чтобы уменьшить вложенность if (программирование на других языках), например:

//instead of nested if like this 
if (condition1) {
   if (condition2) {
     if (condition3) {
       //... finally meet all conditions 
       //do the job 
     }
   }
}
//return early 
if (!condition1) {
   //clean up resource in step #1
   return
}
if (!condition2) {
   //clean up resource in step #2
   return
}
if (!condition3) {
   //clean up resource in step #2
   return
}
...
//finally meet all conditions 

Но как мне сделать ранний возврат в ruby?Я не могу вернуться в блок if в Ruby.Я получил сообщение об ошибке

«Необработанное исключение: неожиданное возвращение ...` блок (2 уровня) в ': неожиданное возвращение (LocalJumpError) "

----обновление -----

Извините, я забыл упомянуть, что в такой простой ситуации это работает

def early(input)
  if (input <0)
    puts 'should >0'
    return
  end
  puts 'good'
end

Я изучаю Fiber и использую пример из https://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/

def http_get(url)
  f = Fiber.current
  http = EventMachine::HttpRequest.new(url).get

  # resume fiber once http call is done
  http.callback { f.resume(1,http) }
  http.errback  { f.resume(2,http) }

  return Fiber.yield
end

EventMachine.run do
  Fiber.new{
    result = http_get('https://www.google.com/')
    if (result[0] ==2) 
      puts "error"
      return # using break has the error 'break from proc-closure (LocalJumpError)' too 
    end
    result = http_get('https://www.google.com/search?q=eventmachine')
    page = result[1]
    puts "Fetched page 2: #{page.response}"
  }.resume
end

Я получил ошибку.

---- обновление 2 ----

Получив ответ и комментарии, я нашел это Как я могувернуть что-то рано из блока?

И это Почему оператор break в ruby ​​ведет себя по-разному при использовании Proc.new v. знак амперсанда? объясняет, почему break не будетработать тоже.Цитировать «break должен заставить вызывающего возвращать блок, но Proc.new уже вернулся».

return против break против next, безусловно, является препятствием для рубинового новичка

1 Ответ

0 голосов
/ 21 декабря 2018

Используйте next вместо return для раннего выхода из внутреннего блока:

class A 
  def run 
    yield
  end
end

a = A.new
a.run do 
  puts "ola"
  next
  puts "hello"
end

Чтобы использовать return, он должен быть расположен непосредственно внутри тела метода.

Но когда вы передаете блок функции, с помощью EventMachine.run do и Fiber.new{, код внутри блока не находится непосредственно внутри функции, а передается в качестве параметра другой функции.Внутри блока вы не можете вызвать return, но вы можете выйти рано с next.

Я предполагаю, что причина, по которой дизайнеры решили, что это потому, что return внутри блока, может вызвать путаницу, еслиблок вернется, или весь метод.

...