The problem with run-time type checking

Dossy wrote:

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?

Automated unit tests. You get test coverage and peace of mind with
dynamically typed languages at the same time.

How do automated unit tests help with this? I can’t figure it out.

A function like this:

def escapeHTML(string)
string.gsub(/&/n, ‘&’).gsub(/"/n, ‘"’).gsub(/>/n, ‘>’).gsub(/</n, ‘<’)
end

if passed e.g. an array, will crash when gsub() can’t be called on it. The
problem is that the resulting stack dump is uninformative, requiring the
person calling the function to look at the source code of the function in
order to figure out the problem.

I’m asking when I write a function that depends on its arguments to be a
specific type, how can I make them produce informative stack dumps if the
arguments are the wrong type? I don’t see how unit testing would help the
person writing a library function.

The beauty of Ruby (and OO in general) is being able to make “objects”
… what if you wanted to pass in your own object that wasn’t inherited
from String (and thus, is not a #kind_of? String) but implements the
#gsub method?

Even testing using #respond_to? isn’t foolproof because of
#method_missing

I could think of doing this, which would only raise an exception if the
given object doesn’t implement the #gsub method even using
#method_missing:

def escapeHTML(string)
begin
return gsub(…)
rescue NameError
raise TypeError, “string must be String, not #{string.class}”
end
end

Still, I think it’s too tedious to be doing that sort of thing on just
about every function that accepts parameters that I write… and the
escapeHTML() example is already a relatively trivial one.

Thoughts?

Testing that an object makes correct calls to a library is not the
responsibility of the library writer, it is the responsibility of the
programmer who is using the library.

A programmer should test that their objects implement their
postconditions and invariants correctly, and that their objects meet the
preconditions of other object that they call. One way to do this is to
mock up the environment of the object in order to assert that outgoing
calls are correct when the object is exercised in a test case.

This kind of testing is easiest if libraries are written as collections
of classes that are used through composition, rather than through
inheritance. That is, an object should use your library through an
object reference, rather than through a module of free-floating
functions. This way, programmers using your library can create mock
versions of your classes in their unit tests to ensure that the correct
values are being passed out of their objects.

If you really want to help clients of your library, you can provide a
suite of mock objects that can be used for unit testing client code.

Cheers,
Nat.

···

On Sun, 2002-09-22 at 19:36, Philip Mak wrote:

I’m asking when I write a function that depends on its arguments to be a
specific type, how can I make them produce informative stack dumps if the
arguments are the wrong type? I don’t see how unit testing would help the
person writing a library function.


Dr. Nathaniel Pryce, Technical Director, B13media Ltd.
Studio 3a, 22-24 Highbury Grove, London N5 2EA, UK
http://www.b13media.com

I know I can do this.

obj = Object.new
def obj.test
puts "running the singleton test method"
end
obj.test # executes the singleton method

But what if the name of the method I want to add (such as “test”) isn’t
determined until runtime?
Can I dynamically add a method like that?

I think I found the answer myself. Is there a better way than this?

obj = Object.new
methodName = ‘foo’
methodDef = “def obj.#{methodName}; puts ‘in my method’; end”
eval(methodDef) # to add the method foo to the object obj
obj.foo # to invoke it

···

----- Original Message -----
From: “Mark Volkmann” volkmann2@charter.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Tuesday, October 01, 2002 7:10 PM
Subject: singleton methods with variable method names

I know I can do this.

obj = Object.new
def obj.test
puts “running the singleton test method”
end
obj.test # executes the singleton method

But what if the name of the method I want to add (such as “test”) isn’t
determined until runtime?
Can I dynamically add a method like that?

obj = Object.new
methodName = ‘foo’
methodDef = “def obj.#{methodName}; puts ‘in my method’; end”
eval(methodDef) # to add the method foo to the object obj
obj.foo # to invoke it

To be even more dynamic you can change

obj.foo

to

obj.send(‘foo’)

Farrel

···

DNA Research Group mailto:flifson@cs.uct.ac.za
Dept. of Computer Science http://www.cs.uct.ac.za/~flifson
University of Cape Town +27-21-650-3127

Hi,

But what if the name of the method I want to add (such as “test”) isn’t
determined until runtime?
Can I dynamically add a method like that?

I think I found the answer myself. Is there a better way than this?

obj = Object.new
methodName = ‘foo’
methodDef = “def obj.#{methodName}; puts ‘in my method’; end”
eval(methodDef) # to add the method foo to the object obj
obj.foo # to invoke it

It’s an idiom to create methods dynamically, and if the method
body is determined:

module Test
def test
puts “running the singleton test method”
end
end

obj = Object.new
methodName = ‘foo’
obj.extend(Test)
(class << obj; self; end).module_eval {
alias_method(methodName, :test)
}
obj.foo

You can use Module#define_method in 1.7.

···

At Wed, 2 Oct 2002 12:27:07 +0900, Mark Volkmann wrote:


Nobu Nakada