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?