Как отменить оценку требуемого файла Ruby?

file1 требует file2, и я хочу иметь возможность отменить оценку file2 при определенных условиях, не выходя из всего процесса.

# file1.rb
  puts "In file 1"
  require 'file2'
  puts "Back in file 1"

# file2.rb
  puts "In file 2"
  # return if some_conditional
  puts "Still in file 2"

При запуске file1 вывод, который я хочу увидеть:

In file 1
In file 2
Back in file 1

Цель состоит в том, чтобы Still in file 2 никогда не печатался, а Back in file 1 печатает. Могу ли я что-нибудь сделать в file2 чтобы сделать это возможным?

Я не могу использовать exit/exit!/abort здесь, потому что Back in file 1 никогда не будет печататься. Я мог бы использовать raise/fail, но для этого мне пришлось бы изменить file1 и rescue сбойное require. Я надеюсь найти способ, который не предполагает изменения file1.

ОБНОВЛЕНИЕ:

Функция "возвращение верхнего уровня" была добавлена.

Ответ 1

ОБНОВЛЕНИЕ:

Функция "возвращение верхнего уровня" была добавлена.

ОРИГИНАЛ:

Комментатор Мэтт отметил, что Feature 4840, которая будет делать именно то, о чем я спрашиваю, обсуждается с июня 2011 года. Кроме того, эта функция все еще обсуждалась в ноябре 2015 года на совещаниях основных групп, посвященных новым функциям Ruby.

Существует много трудностей, связанных с разработкой такой функции; для списка плюсов и минусов, я настоятельно рекомендую проверить обсуждения.

Предложенная функция позволит выйти из требуемого файла при использовании любого из следующих операторов верхнего уровня:

if condition
  return
end

while condition
  # ...
  return
end

begin
  # ...
  return
rescue
  # ...
  return
ensure
  # ...
  return
end

И это не будет выходить из требуемого файла в следующих утверждениях:

class Foo
  return # LocalJumpError
end

def foo
  return # returns from method, not from required file
end

proc do
  return # LocalJumpError
end

x = -> { return } # returns as from lambda, not from required file

Поскольку эта функция остается невыполненной, я присудил награду Стинслагу за успешное решение проблемы (как изначально было написано) письму, если не духу.

Ответ 3

Я не знаю какого-либо официального метода для выхода из требуемых файлов, тем более, что существует несколько методов require (например, требуются патчи для патчей)

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

# file1.rb
puts "In file 1" 
catch(:done) do
    require 'file2' end
puts "Back in file 1"

# file2.rb
puts "In file 2" 
throw :done
puts "Still in file 2" # Never gets called

Ответ 4

Возможно ли использование метода? Он все равно будет разбирать метод, но не будет выполнен. Что-то вроде:

#file1.rb
  puts "In file 1"
  require 'file2'
  puts "Back in file 1"
  a_method

#file2.rb
  puts "In file 2"
  # <= A

  def a_method
    puts "Still in file 2"
  end