CSc 372 - Comparative Programming Languages
33 : Ruby -- Types
Christian Collberg
Department of Computer Science
University of Arizona
- Some call it static checking, type safety,
strict type-checking, strong typing,...
- It does have some advantages:
- You catch certain errors at compile time which
you now can be sure won't occur at run-time:
arithmetic between the wrong types, wrong
number of arguments to functions, etc.
- Simple errors that appear during code
refactoring are easily caught and fixed.
- The more the compiler knows about your
code, the better optimized code it can
produce.
- Types serve as comments to the programmer,
reminding him/her of what types of arguments
a method was designed to take.
- But:
- Even Java has many errors which cannot be
caught until run-time, such as ClassCastException
and ArrayBoundsException.
- Sometimes you need more flexibility, and
it can be hard to work around a strict
typechecker.
- On the one hand, on the other hand:
- Less static type-checking may make programs
faster to write, but it may also make
them harder to maintain.
- A program is written once, but read and
re-written many times -- types can help
someone unfamliar with the code to
understand it quicker.
- The type of an object is defined by what it can do.
- If an object walks like a duck, and talks
like a duck, let's treat it like it's a duck!
- We call this Duck Typing.
- Here's a simple class that logs data
by appending it to a file:
class Logger
def initialize()
@f = File.open("logfile", "w")
end
def log(message)
@f << message
end
end
l = Logger.new
l.log("Ducks ahoy!\n")
- Or a string, which also knows the
« message.
- Notice that the only change we had to make
was to the statement that creates the f-object.
class Logger
def initialize()
@f = ""
end
def log(message)
@f << message
end
end
- Or an array, which also responds to the
« message:
class Logger
def initialize()
@f = []
end
def log(message)
@f << message
end
end
l = Logger.new
l.log("Ducks ahoy!\n")
- If you absolutely want to check types,
you should really check whether an object
responds to a particular message or not:
class Logger
def initialize()
@f = {}
end
def log(message)
unless @f.respond_to?(:<<)
fail TypeError.new("log needs <<")
end
@f << message
end
end
- Of course, all we're checking here is that
there's a method by the name of «,
we know nothing about what arguments it takes,
what it does to those arguments, etc, so
this is pretty weak checking.
- Read Chapter 23, page 365-377, in
Programming Ruby -- The Pragmatic
Programmers Guide, by Dave Thomas.
From http://www.dailymail.co.uk/pages/live/articles/news/news.html?in_article_id=464768
Christian S. Collberg
2007-11-14