dynamic classes and duck typing

Adam D. Ruppe destructionator at gmail.com
Thu Dec 3 10:24:03 PST 2009


On Wed, Dec 02, 2009 at 11:50:23AM +0000, retard wrote:
> The case I commented on was about fetching values from a db IIRC.

What happened to me was the value got returned as the incorrect type, stored,
and used later where it threw the exception..

Conceptual code here:

===

def getPermission(userid)
begin
    return $db.query("select whatever from table where id = ?", userid);
end

def getPermissionNeeded(operation)
begin
    return $db.query("select whatever from table where id = ?", operation.id);
end

===

The most common way the code used it was like this:

if(getPermission(user) == getPermissionNeeded(op)
 || user == User.ROOT)
    op.run; // works - the db functions return equal strings in both cases


The bug was here:

if(getPermission(user) >= getPermissionNeeded(op)) // this throws at runtime
    op.run;  // never reached, users complain


If the functions were defined like they would be in D:

int getPermission(int user) {
	return db.query(...);
}

The real source of the bug - that the database query didn't give me the 
expected type - would have been located in the fraction of a second it takes
for the compiler to run its most trivial checks.

That really is similar to putting in an out contract:
	assert(getPermission is int);
	or probably better:
	assert(getPermission >= 0);

But it is a) required, so I'm not allowed to get lazy about it and b) just
plain easier, so laziness won't affect it anyway.


(Or hell, if it was PHP, the weak typing would have converted both to integer
 at that line and it would work. But weak typing comes with its own slippery
 bugs.)

Thanks to the dynamic duck typing, the code worked most the time, but failed
miserably where I deviated ever so slightly.


The fix in the ruby was easy enough, once the bug was found:
	return db.query(...).to_i

The same thing dmd would have forced me to do to make it compile, but the
important difference is dmd would have found the bug for me, not an end user.


It just goes to prove that you can't just forget about types in your
code just because it is dynamic.

-- 
Adam D. Ruppe
http://arsdnet.net



More information about the Digitalmars-d mailing list