1

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?

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.

0

2 Answers 2

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

This will print #<SystemExit: exit> in an infinite loop, without ever exiting.

Sign up to request clarification or add additional context in comments.

3 Comments

does this prevent the script from exiting?
@rogerdpack: Yes, it does. Updated my answer.
Thanks, I think this is the best solution to handle exits from other code.
2

One hackish way to define an exit method in context:

class Bar; def exit; end; end

This works because exit in the initializer will be resolved as self.exit1. In addition, this approach allows using the object after it has been created, as in: b = B.new.

But really, one shouldn't be doing this: don't have exit (or even puts) there to begin with.

(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.)


1 Remember Kernel#exit is only a method. Since Kernel is included in every Object, then it's merely the case that exit normally resolves to Object#exit. However, this can be changed by introducing an overridden method as shown - nothing fancy.

5 Comments

While exit can be overridden, should it is the real question. I can imagine some nasty bugs down the road for that codebase. Exit has a specific purpose and expected behavior and changing it would be really irritating.
@theTinMan I agree. A added emphasis to "shouldn't" .. at least the behavior is confined to B or a subclass.
"> don't have exit (or even puts) there to begin with" - What if you are not in control over code written by someone else?
Interesting solution but not clean - I do not want to redefine exit in my project. I merely want other classes to not exit when they think they should want to do so - I don't want to allow them to exit when they think I should exit. The earlier solution to rescue SystemExit seems clearer and cleaner than redefining or aliasing exit.
@user722915 You don't need to redefine exit in the project: it is only changed in the B class. And I agree it's not "clean", but this entire problem isn't clean and the fundamental broken design should be fixed. This is the only way I know of to use the result of the method call/initializer. Catching the exception unwinds the stack, which makes B.new (read: this code) seem like even more of a joke if instances of B are never meant to be used.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.