Ducktyping ruby

Hi,
Does anyone know is there some ruby configurations that can be done to
make ruby act a little more like a statically typed language���I love
its dynamic nature, but miss the safety that comes from statically typed
languages like java��.

Cheers in advance

That’s what testing frameworks are for :slight_smile:

-PJ

http://www.catb.org/jargon/html/I/If-you-want-X--you-know-where-to-find-it-.html

jackBrody wrote:

Does anyone know is there some ruby configurations that can be done to
make ruby act a little more like a statically typed language���I love
its dynamic nature, but miss the safety that comes from statically typed
languages like java��.

First off, no I don’t know of anything like that, and if you had that it
wouldn’t really be Ruby anymore.

I know the Java folks like to tout their static typing as making things
safer, but it doesn’t really. How often do you have to do a typecast in
Java? Every time you do that you’ve subverted the static type system and
created an opportunity for a type error at runtime. That’s essentially
no different from how Ruby handles things, but it carries a lot more
overhead.

If you want to feel safe, write good tests. Documenting the inputs and
return values of methods is also helpful. To a large extent, a static
type system is just documentation that the compiler forces you to write
in a fashion that is more useful for it than for humans.


Josh S.
http://blog.hasmanythrough.com

Thanks for the useless info John

On Thu, Apr 27, 2006 at 09:20:54PM +0200, Josh S. wrote:
[…]
} I know the Java folks like to tout their static typing as making
things
} safer, but it doesn’t really. How often do you have to do a typecast
in
} Java? Every time you do that you’ve subverted the static type system
and
} created an opportunity for a type error at runtime. That’s essentially
} no different from how Ruby handles things, but it carries a lot more
} overhead.

It is very different. There are tremendous advantages to working in a
language in which static analysis can identify type errors. There are
also
advantages to a dynamically typed language. They are mutually exclusive
(AFAIK), however, and there are good reasons to make different tradeoffs
in
different situations. Rails couldn’t do much of its magic without the
dynamic facilities (e.g. method_missing and const_missing) of Ruby, for
example.

Also, modern Java has done away with most of the typecasting that was
necessary previously. A lot of that had to do with generic collections
that
worked on Objects, and that has been entirely replaced with templated
typesafe collections in Java 1.5. I will agree that the previous
versions
gave up a lot of the advantages of a statically typed language, but the
current version is much better.

} If you want to feel safe, write good tests. Documenting the inputs and
} return values of methods is also helpful. To a large extent, a static
} type system is just documentation that the compiler forces you to
write
} in a fashion that is more useful for it than for humans.

This shows a lack of understanding of programming languages, compilers,
and
static and dynamic analysis. A static type system allows the compiler to
perform analysis of your code that is more rigorous than any amount of
testing. Tests can only test code paths. Static analysis can find bugs
in
code that gets called rarely, or only when other things go wrong, or
never
at all due to bugs elsewhere.

I’m not saying that statically typed languages are better, I’m saying
that
one must understand the tradeoffs. What does one gain by using a
statically
typed language over a dynamically typed language? What does one lose?
Some
people spend years in school learning about it at a fine level of
detail,
others learn enough on their own to get by, and still others learn how
to
use one language and not only genuinely believe that it is the best
language, but that there can actually be a best language. There isn’t.
There are only tradeoffs, which is often summed up as “use the right
tool
for the job.”

} Josh S.
–Greg

On 27 Apr 2006, at 8:45 pm, Gregory S. wrote:

compilers, and
static and dynamic analysis. A static type system allows the
compiler to
perform analysis of your code that is more rigorous than any amount of
testing. Tests can only test code paths. Static analysis can find
bugs in
code that gets called rarely, or only when other things go wrong,
or never
at all due to bugs elsewhere.

If you use test-driven development, there shouldn’t be any code
that isn’t exercised by a test.

Kerry

On Sat, Apr 29, 2006 at 01:34:37PM +0100, Kerry B. wrote:
} On 27 Apr 2006, at 8:45 pm, Gregory S. wrote:
} >} If you want to feel safe, write good tests. Documenting the inputs
} >} and return values of methods is also helpful. To a large extent, a
} >} static type system is just documentation that the compiler forces
you
} >} to write in a fashion that is more useful for it than for humans.
}
} >This shows a lack of understanding of programming languages,
compilers,
} >and static and dynamic analysis. A static type system allows the
} >compiler to perform analysis of your code that is more rigorous than
any
} >amount of testing. Tests can only test code paths. Static analysis
can
} >find bugs in code that gets called rarely, or only when other things
go
} >wrong, or never at all due to bugs elsewhere.
}
} If you use test-driven development, there shouldn’t be any code
} that isn’t exercised by a test.

That is a common misconception. Suppose you have a single method with
four
code paths through it. It is called by another method with four code
paths
through it. That is called by a method with four code paths through it.
To
test it exhaustively, you must write 64 (444) tests. Instead, you have
almost certainly written 12 (4+4+4) tests. Worse, there is a nearly
infinite number of code paths through any dynamically typed code;
calling a
method (which includes many operators) on any argument is itself a
nearly
infinite number of code paths since the actual method called depends on
the
object (and type thereof) passed in.

You absolutely cannot test every possible code path. Without static type
checking you can’t even enumerate all the code paths. The best you can
do
is design and code carefully. TDD is a good way of going about that, but
it
isn’t a silver bullet (nor is anything else).

} Kerry
–Greg

On 29 Apr 2006, at 3:42 pm, Gregory S. wrote:

} If you use test-driven development, there shouldn’t be any code
} that isn’t exercised by a test.

That is a common misconception. Suppose you have a single method
with four
code paths through it. It is called by another method with four
code paths
through it. That is called by a method with four code paths through
it. To
test it exhaustively, you must write 64 (444) tests.

Surely the issue of type checking only comes up at the interfaces
where methods are called? You may have 64 paths in theory, but as
long as you can test that the first method always passes the correct
class of object to the second, and so on, that should be enough for
the real world.

Kerry

On Sat, Apr 29, 2006 at 05:22:15PM +0100, Kerry B. wrote:
} On 29 Apr 2006, at 3:42 pm, Gregory S. wrote:

You missed an attribution here. I did not write the following two lines.

} >} If you use test-driven development, there shouldn’t be any code
} >} that isn’t exercised by a test.
}
} >That is a common misconception. Suppose you have a single method
with
} >four code paths through it. It is called by another method with four
} >code paths through it. That is called by a method with four code
paths
} >through it. To test it exhaustively, you must write 64 (444)
tests.
}
} Surely the issue of type checking only comes up at the interfaces
} where methods are called?

Not necessarily. That was just an example. Consider the following:

class Foo
attr_accessor :bar

def do_something_with_a_string(arg)
fail ‘arg is not a string!’ unless String === arg
return bar.do_something_else(arg)
end

end

Foo#do_something_with_a_string makes sure that its argument is a string,
but what type is bar? And what is returned by do_something_else? You can
decide to implement your own attribute mutators that enforce type
instead
of using attr_accessor, but that gives up much of the power of Ruby.
After
all, the point of duck typing is that you don’t care an object’s type,
just its capabilities.

} You may have 64 paths in theory, but as long as you can test that the
} first method always passes the correct class of object to the second,
} and so on, that should be enough for the real world.

And it often is. Good tests help a lot, and I’m not trying to claim they
are useless. I am trying to explain that exhaustive testing is
impossible
for any nontrivial system. I am also trying to make it clear that only
exhaustive testing is the only way to be certain that a system behaves
correctly in all situations, and that TDD does not change that.

There are no silver bullets. TDD is a good approach, and there are many
other complementary development and testing strategies, including static
analysis, that make it easier to develop correct software. None of them
will catch every bug, and none of them can force a mediocre coder to
produce great code. We all do the best we can at our craft, using the
tools
as best we can and, ideally, for the purposes for which they are best
suited.

If this still doesn’t make sense to you, read this 1986 paper by Fred
Brooks:

http://www-inst.eecs.berkeley.edu/~maratb/readings/NoSilverBullet.html

Yes, it’s two decades old. No, nothing has changed in the basic premises
on
which it was written.

} Kerry
–Greg