简体   繁体   English

Ruby-忽略代码中的“退出”

[英]Ruby - ignore “exit” in code

Consider this code: 考虑以下代码:

class Bar
  def initialize
    puts 'Hi from class Bar.'
    exit
  end
end


class Foo
  def initialize
    loop {
      case $stdin.gets.chomp
      when 'foo'
        puts 'Hi from class Foo.'
      when 'bar'
        Bar.new
      end
    }
  end
end

Can I ignore the exit in class Bar somehow? 我可以以某种方式忽略Bar类的退出吗?

It terminates my loop. 它终止了我的循环。 I don't want that. 我不要

Note - the real code base is much larger and more complicated than that. 注意-实际的代码库比这更大,更复杂。 But it boils down to this question whether I can ignore exit() or not. 但这归结为我是否可以忽略exit()的问题。

loop {
  begin
    Bar.new
  rescue SystemExit
    p $!  #: #<SystemExit: exit>
  end
}

This will print #<SystemExit: exit> in an infinite loop, without ever exiting. 这将无限循环打印#<SystemExit: exit> ,而不会退出。

One hackish way to define an exit method in context: 在上下文中定义exit方法的一种怪诞方式:

class Bar; def exit; end; end

This works because exit in the initializer will be resolved as self.exit 1 . 之所以有效,是因为初始化程序中的exit将被解析为self.exit 1 In addition, this approach allows using the object after it has been created, as in: b = B.new . 另外,这种方法允许在对象创建后使用它,如: b = B.new

But really, one shouldn't be doing this: don't have exit (or even puts ) there to begin with. 但实际上, 应该这样做:首先不要exit (甚至puts )。

(And why is there an "infinite" loop and/or user input in an intiailizer? This entire problem is primarily the result of poorly structured code.) (以及为什么intiailizer中会出现“无限”循环和/或用户输入?整个问题主要是代码结构不良的结果。)


1 Remember Kernel#exit is only a method. 1记住Kernel#exit 只是一种方法。 Since Kernel is included in every Object, then it's merely the case that exit normally resolves to Object#exit . 由于内核包含在每个对象中,因此仅exit通常会解析为Object#exit However, this can be changed by introducing an overridden method as shown - nothing fancy. 但是,可以通过引入如图所示的覆盖方法来更改它-没什么花哨的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM