Как заставить LocalJumpError возвращаться в Ruby? - PullRequest
1 голос
/ 01 декабря 2010

Моя функция bar получает блок, и я хотел бы запустить этот блок, не позволяя ему return.Как мне это сделать, изменив только bar ниже и сохранив все остальное, включая foo, без изменений?

def bar()
  yield
end
def foo()
  bar do
    p "it"
    return  # This works. But I'd like to get LocalJumpError.
  end
end
foo

Ответы [ 3 ]

1 голос
/ 02 декабря 2010

Если после yield требуется выполнить какой-либо код "очистки", тогда вы можете использовать begin, а затем ensure.

1 голос
/ 01 декабря 2010

Ну, вы получаете LocalJumpError, когда вы пытаетесь передать блок с return на Proc (в отличие от lambda).

Вы можете обойтись без изменения foo за исключением того, как он называется, если вы сделаете что-то вроде

def bar()
  Proc.new
end

def foo()
  bar do
    p "it"
    return
  end
end

foo[]

Это дает LocalJumpError.

В любом случае, эта статья может помочь.

Редактировать: return в процедуре будет возвращаться из внешнего метода, а не из анонимного метода в блоке. Возможно, вы сможете установить флаг, который вы можете проверить в bar, чтобы увидеть, если он вернулся преждевременно:

bar_finished = false

def bar(&block)
  proc = Proc.new &block
  l.call
  bar_finished = true
end

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

0 голосов
/ 06 декабря 2010

На основании предложений других ответов мне удалось решить проблему:

def bar()
  has_returned = true
  begin
    x = yield
    has_returned = false
    x
  rescue
    has_returned = false
    raise
  ensure
    raise LocalJumpError if has_returned
  end
end
def foo()
  bar do
    p "it"
    return  # This makes bar raise a LocalJumpError.
  end
end
foo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...