Customing the Exception class

D

Daniel Berger

Hi all,

I have a program where I want to send all errors to a file. So, I did this:

class Exception
alias :eek:ld_init :initialize
def initialize(arg)
old_init(arg)
File.open("log.txt","a+"){ |fh| fh.puts("Error: #{arg}") }
end
end

This works for most errors, but it doesn't seem to work when the error
is a SystemCallError.

For example, this writes to the log as expected:

print "Some crazy division: "
p 1/0

But this does not:

File.open("non-existant file")

The latter raises an Errno::ENOENT.

Why, if SystemCallError is a subclass of Exception, does my approach not
work? How do I make this work as expected?

Regards,

Dan
 
A

Ara.T.Howard

Hi all,

I have a program where I want to send all errors to a file. So, I did this:

class Exception
alias :eek:ld_init :initialize
def initialize(arg)
old_init(arg)
File.open("log.txt","a+"){ |fh| fh.puts("Error: #{arg}") }
end
end

This works for most errors, but it doesn't seem to work when the error
is a SystemCallError.

For example, this writes to the log as expected:

print "Some crazy division: "
p 1/0

But this does not:

File.open("non-existant file")

The latter raises an Errno::ENOENT.

Why, if SystemCallError is a subclass of Exception, does my approach not
work? How do I make this work as expected?

maybe new?


harp:~ > cat a.rb
class Exception
class << self
alias ____new new
def new(*a, &b)
ret = ____new(*a, &b)
STDERR.puts "new: <#{ a.inspect }>"
ret
end
end
alias ____init initialize
def initialize(*a, &b)
ret = ____init(*a, &b)
STDERR.puts "initialize: <#{ a.inspect }>"
ret
end
end

SystemCallError::new 42

harp:~ > ruby a.rb
new: <[42]>

not sure why...

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================
 
E

Eric Hodel

Hi all,

I have a program where I want to send all errors to a file. So, I
did this:
[snip]
This works for most errors, but it doesn't seem to work when the
error
is a SystemCallError.

For example, this writes to the log as expected:

print "Some crazy division: "
p 1/0

But this does not:

File.open("non-existant file")

The latter raises an Errno::ENOENT.

Why, if SystemCallError is a subclass of Exception, does my
approach not
work? How do I make this work as expected?

maybe new?
[snip]

not sure why...

SystemCallError does not use Exception's initialize:

rb_eSystemCallError = rb_define_class("SystemCallError",
rb_eStandardError);
rb_define_method(rb_eSystemCallError, "initialize",
syserr_initialize, -1);
 
D

Daniel Berger

Eric said:
Hi all,

I have a program where I want to send all errors to a file. So, I
did this:
[snip]
This works for most errors, but it doesn't seem to work when the
error
is a SystemCallError.

For example, this writes to the log as expected:

print "Some crazy division: "
p 1/0

But this does not:

File.open("non-existant file")

The latter raises an Errno::ENOENT.

Why, if SystemCallError is a subclass of Exception, does my
approach not
work? How do I make this work as expected?

maybe new?
[snip]

not sure why...

SystemCallError does not use Exception's initialize:

rb_eSystemCallError = rb_define_class("SystemCallError",
rb_eStandardError);
rb_define_method(rb_eSystemCallError, "initialize",
syserr_initialize, -1);

Yuck. Could it be altered to call super? Or would that cause some
hideous side effect?

Regards

Dan

PS - Sorry if this is a double post - google groups went goofy on me
for a minute.
 
N

nobu.nokada

Hi,

At Sat, 14 May 2005 10:30:29 +0900,
Daniel Berger wrote in [ruby-talk:142610]:
Accurately, syserr_initialize() directly calls exc_initialize()
which implements Execption#initialize.
Yuck. Could it be altered to call super? Or would that cause some
hideous side effect?

Just for efficiency, I guess.


Index: error.c
===================================================================
RCS file: /cvs/ruby/src/ruby/error.c,v
retrieving revision 1.107
diff -U2 -p -r1.107 error.c
--- error.c 18 Mar 2005 03:17:27 -0000 1.107
+++ error.c 14 May 2005 02:32:25 -0000
@@ -387,5 +387,5 @@ exc_exception(argc, argv, self)
if (argc == 1 && self == argv[0]) return self;
exc = rb_obj_clone(self);
- exc_initialize(argc, argv, exc);
+ rb_obj_call_init(exc, argc, argv);

return exc;
@@ -581,5 +581,5 @@ exit_initialize(argc, argv, exc)
--argc;
}
- exc_initialize(argc, argv, exc);
+ rb_call_super(argc, argv);
rb_iv_set(exc, "status", status);
return exc;
@@ -661,5 +661,5 @@ name_err_initialize(argc, argv, self)

name = (argc > 1) ? argv[--argc] : Qnil;
- exc_initialize(argc, argv, self);
+ rb_call_super(argc, argv);
rb_iv_set(self, "name", name);
return self;
@@ -966,5 +966,5 @@ syserr_initialize(argc, argv, self)
mesg = rb_str_new2(err);
}
- exc_initialize(1, &mesg, self);
+ rb_call_super(1, &mesg);
rb_iv_set(self, "errno", error);
return self;
 
D

Daniel Berger

Hi,

At Sat, 14 May 2005 10:30:29 +0900,
Daniel Berger wrote in [ruby-talk:142610]:
Accurately, syserr_initialize() directly calls exc_initialize()
which implements Execption#initialize.
Yuck. Could it be altered to call super? Or would that cause some
hideous side effect?

Just for efficiency, I guess.


Index: error.c
===================================================================
RCS file: /cvs/ruby/src/ruby/error.c,v
retrieving revision 1.107
diff -U2 -p -r1.107 error.c
--- error.c 18 Mar 2005 03:17:27 -0000 1.107
+++ error.c 14 May 2005 02:32:25 -0000
@@ -387,5 +387,5 @@ exc_exception(argc, argv, self)
if (argc == 1 && self == argv[0]) return self;
exc = rb_obj_clone(self);
- exc_initialize(argc, argv, exc);
+ rb_obj_call_init(exc, argc, argv);

return exc;
@@ -581,5 +581,5 @@ exit_initialize(argc, argv, exc)
--argc;
}
- exc_initialize(argc, argv, exc);
+ rb_call_super(argc, argv);
rb_iv_set(exc, "status", status);
return exc;
@@ -661,5 +661,5 @@ name_err_initialize(argc, argv, self)

name = (argc > 1) ? argv[--argc] : Qnil;
- exc_initialize(argc, argv, self);
+ rb_call_super(argc, argv);
rb_iv_set(self, "name", name);
return self;
@@ -966,5 +966,5 @@ syserr_initialize(argc, argv, self)
mesg = rb_str_new2(err);
}
- exc_initialize(1, &mesg, self);
+ rb_call_super(1, &mesg);
rb_iv_set(self, "errno", error);
return self;

Will this patch be applied to the 1.8 branch? I'd like to see it in
1.8.3 but I understand if you'd rather merge it into 1.9 instead.

Regards,

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top