From: Tim Hunter Date: 2002-09-23T21:17:41+09:00 Subject: Re: The problem with run-time type checking Regarding question 1, it seems to me that libraries must "crash" when garbage is passed in. At least I've never seen a library that didn't. The task for the library developer is to crash in a way that makes it easy - or at least possible - for the library developer to fix the problem. Regarding (2), It seems to me that the problem isn't that the method got an Array instead of a String, the problem is that the method got an object that doesn't have the expected type. That is, the object doesn't respond to the set of messages (gsub, in this case) the method needs to send it. Presumably any object that responds to gsub would be acceptable to the method. Testing .responds_to? is klunky, too. From the library user's point-of-view, the fact that you can't send gsub to str is not very useful. Such a message is only useful to the library developer. A useful message for the user explains the error in terms the user can understand (with perhaps detailed background information along with the primary message). I don't know what this method does, but I'm guessing that it adds escape characters to its string argument. Assuming that, what's wrong with begin str.gsub... rescue raise ArgumentError, "Can't add escape characters to #{str}: $!" end On Sun, 22 Sep 2002 02:40:00 -0400, Philip Mak wrote: > One problem that I find crops up in Ruby, but doesn't really happen in > Perl (since Perl has only one kind of scalar) or compiled languages like > Java/C (since the type is checked at compile time) is that many > libraries (e.g. from RAA) will crash if you pass a variable with the > wrong type to a method, but rather than telling you that it was your > fault, the stack dump just shows an error occuring on a line inside the > library, which then requires you to look at the source code of the > library in order to find out what you did wrong (IMHO, libraries should > work like black boxes). > > For example, in the 'cgi' library, CGI.escapeHTML(str) calls str.gsub. > If you pass an array to it by accident, you'll get a crash: > > NameError: private method `gsub' called for [1, 2, 3]:Array > from /usr/local/lib/ruby/1.6/cgi.rb:260:in `escapeHTML' from > (irb):7 > > rather than seeing a more friendly error message like "expected String, > got Array". A programmer faced with the above error message probably has > to go into cgi.rb, look at line 260, and then figure out that he was > supposed to pass a String to CGI.escapeHTML but passed something else. > > Regarding this, I have two questions: > > (1) Is it bad programming practice to write a library that can crash if > garbage is passed in? > > (2) How do I program libraries in a friendly fashion? Should I do stuff > like: > > raise "Expected String, got #{str.class}" unless str.kind_of?(String) > > Then again, doing (2) seems to add a significant amount of extra code I > have to write. In typed languages, I just need to specify what type a > variable should be; not have to write a whole line to raise an exception > if the variable isn't the right type. > > Does anyone have a better idea?