How to know the exit status within at_exit() block?

Hi, my program invokes “exit true” or “exit false” and I want to catch
such return code into at_exit() block, but I don’t know how to do
that.

I would like something as:

at_exit(exit_status) {
puts “exiting with status #{status}”
}

if SOMETHING
exit true
else
exit false
end

Of course I call “exit” from lof of clases/modules under my project so
I cannot use a local scope variable “status” (and I wouldn’t like to
use a global variable).

Thanks for any suggestion.

On Mon, Jan 31, 2011 at 5:09 PM, Iaki Baz C. [email protected]
wrote:

Thanks for any suggestion.


Iaki Baz C.
[email protected]

How about stick your own exit method before Kernel in the lookup chain

class Object
private
def exit(status=true)
at_exit {
puts “exiting with status #{status}”
}
super
end
end

On Jan 31, 2011, at 15:09, Iaki Baz C. wrote:

Hi, my program invokes “exit true” or “exit false” and I want to catch
such return code into at_exit() block, but I don’t know how to do
that.

ruby -e ‘at_exit { p $!.status }; exit 1’

On Tue, Feb 1, 2011 at 12:09 AM, Iaki Baz C. [email protected]
wrote:

Hi, my program invokes “exit true” or “exit false” and I want to catch
such return code into at_exit() block, but I don’t know how to do
that.

exit false
end

You are aware that you can simplify that to

exit SOMETHING

are you?

Of course I call “exit” from lof of clases/modules under my project so
I cannot use a local scope variable “status” (and I wouldn’t like to
use a global variable).

First of all: IMHO that is bad practice because it prevents your code
to be used in different situations (i.e. reduces modularity). The
proper way would be to raise exceptions and deal with them
appropriately. You can even omit the handling on top level and get
appropriate exit codes of the process (i.e. 0 for the regular case, 1
for error):

$ ruby19 -e ‘raise “f”’; echo $?
-e:1:in `': f (RuntimeError)
1
$ ruby19 -e ‘nil’; echo $?
0
$

However, you can do what you want with a rescue clause:

begin

main code

rescue SystemExit => e
puts “exiting with status #{e.status}”
raise
rescue Exception => e
puts “exiting with status 1”
raise
else
puts “exiting with status 0”
end

Kind regards

robert

2011/2/1 Eric H. [email protected]:

Hi, my program invokes “exit true” or “exit false” and I want to catch
such return code into at_exit() block, but I don’t know how to do
that.

ruby -e ‘at_exit { p $!.status }; exit 1’

Really interesting. However, it fails if exit() is called outside of the
scope:

irb> at_exit { p “$!.inspect = #{$!.inspect}” }
#Proc:0x000000019f99c0@:1(irb)
irb> exit 1
“$!.inspect = nil”

So $! is nil and I cannot get $!.status.

2011/2/1 Josh C. [email protected]:

end
That could work. Then I need to store status in an Object attribute or
a global variable so I can also check it within at_exit block.

Thanks.

2011/2/1 Robert K. [email protected]:

You are aware that you can simplify that to

exit SOMETHING

are you?

Yes, but I want to inspect the exit status code into the block
provided to at_exit().

main code

rescue SystemExit => e
puts “exiting with status #{e.status}”
raise
rescue Exception => e
puts “exiting with status 1”
raise
else
puts “exiting with status 0”
end

Using “rescue SystemExit => e” seems indeed appropriate. Let me play a
bit with it.

Thanks a lot.

2011/2/2 Robert K. [email protected]:

end

to

exit SOMETHING

or maybe this if you want to ensure the value is boolean

exit !!SOMETHING

Ok, perhaps I should clarify that SOMETHING is not the existing status
code but any other kind of condition.

On Wed, Feb 2, 2011 at 12:58 PM, Iaki Baz C. [email protected]
wrote:

exit false
Ok, perhaps I should clarify that SOMETHING is not the existing status
code but any other kind of condition.

I know.

robert

On Wed, Feb 2, 2011 at 11:49 AM, Iaki Baz C. [email protected]
wrote:

2011/2/1 Robert K. [email protected]:

You are aware that you can simplify that to

exit SOMETHING

are you?

Yes, but I want to inspect the exit status code into the block
provided to at_exit().

This is completely unrelated to how you call exit. I pointed out
that you can simplify

if SOMETHING
exit true
else
exit false
end

to

exit SOMETHING

or maybe this if you want to ensure the value is boolean

exit !!SOMETHING

Cheers

robert

On Wed, Feb 2, 2011 at 4:46 AM, Iaki Baz C. [email protected] wrote:

irb> at_exit { p “$!.inspect = #{$!.inspect}” }

It probably doesn’t work in IRB, because IRB wraps calls to exit

irb> method :exit
=> #<Method: Object(IRB::ExtendCommandBundle)#exit>

I think that using $! is probably what you should do.

2011/2/2 Josh C. [email protected]:

Really interesting. However, it fails if exit() is called outside of the
scope:

irb> at_exit { p “$!.inspect = #{$!.inspect}” }
#Proc:0x000000019f99c0@:1(irb)
irb> exit 1
“$!.inspect = nil”

So $! is nil and I cannot get $!.status.

It probably doesn’t work in IRB, because IRB wraps calls to exit

irb> method :exit
=> #<Method: Object(IRB::ExtendCommandBundle)#exit>

I think that using $! is probably what you should do.

You are right, however I’ve realized that in case of exiting without
invoking “exit” or “exit!” (i.e. exiting due to a signal) then $! is
not a SystemExit instance, but an Interrupt instance (and it doesn’t
have “status” method).

For example:


at_exit { p “$!.inspect = #{$!.inspect}” }

sleep 10

If you run this program and press Ctrl+C prior to 10 seconds you get:

“$!.inspect = Interrupt”

So, at_exit block is executed but $! is not a SystemExit instance. I
could trap the signals however.

Thanks.

On Feb 2, 2011, at 02:46, Iaki Baz C. wrote:

#Proc:0x000000019f99c0@:1(irb)
irb> exit 1
“$!.inspect = nil”

So $! is nil and I cannot get $!.status.

It is irb’s fault:

$ cat t.rb
def x
at_exit { p $!.status }
end

def y
exit 2
end

x
y
$ ruby t.rb
2

On Feb 2, 2011, at 06:34, Iaki Baz C. wrote:

sleep 10

If you run this program and press Ctrl+C prior to 10 seconds you get:

“$!.inspect = Interrupt”

So, at_exit block is executed but $! is not a SystemExit instance. I
could trap the signals however.

Yes,

if SystemExit === $! then end

On Feb 3, 2011, at 4:13 AM, Iaki Baz C. wrote:

if SystemExit === $! then end

Thanks. I wonder if $! can be anything else apart from SystemExit and Interrupt.

Yes:

$ ruby -e ‘at_exit { p $! }’
nil
$ ruby -e ‘at_exit { p $! }; raise’
RuntimeError
-e:1: unhandled exception
$

2011/2/3 Eric H. [email protected]:

If you run this program and press Ctrl+C prior to 10 seconds you get:

“$!.inspect = Interrupt”

So, at_exit block is executed but $! is not a SystemExit instance. I
could trap the signals however.

Yes,

if SystemExit === $! then … end

Thanks. I wonder if $! can be anything else apart from SystemExit and
Interrupt.

2011/2/4 Eric H. [email protected]:

$ ruby -e ‘at_exit { p $! }’
nil
$ ruby -e ‘at_exit { p $! }; raise’
RuntimeError
-e:1: unhandled exception

Great :slight_smile: