Interfaces in Ruby

Is there a way to write/inforce interfaces in Ruby like one can using
Abstract Classes in C++ or Interfaces in Java?

If not, how has everyone been approaching this?

//ed

I don’t think C++ abstract classes are that similar to Java interfaces.
I don’t see the need for interfaces in a language with mix-ins. When I
want something like a C++ abstract class, I use a class cluster. Maybe
that’s just my ObjC background showing.

···

On Tuesday, October 15, 2002, at 09:02 PM, Edward Wilson wrote:

Is there a way to write/inforce interfaces in Ruby like one can using
Abstract Classes in C++ or Interfaces in Java?

If not, how has everyone been approaching this?


Cogito Ergo Spud. - I think therefore I yam.

In article 5174eed0.0210151939.2ad2deb1@posting.google.com,

Is there a way to write/inforce interfaces in Ruby like one can using
Abstract Classes in C++ or Interfaces in Java?

If not, how has everyone been approaching this?

//ed

How about:

class AbstractException < Exception
end

class Module
def abstract(*methods)
methods.each { |s|
class_eval(“def #{s}; raise AbstractException,‘#{s} should be
overriden!’; end”)
}
end
end

class MyAbstractClass
abstract :some_method
end

mc = MyAbstractClass.new
mc.some_method
#end

Now if you run this you’ll get:

(eval):1:in `some_method’: some_method should be overriden!
(AbstractException) from abstract.rb:23

Now you can create a subclass of MyClass and override ‘some_method’, like:

class OtherClass < MyAbstractClass
def some_method
puts “OtherClass::some_method”
end
end

oc = OtherClass.new
oc.some_method #=> “OtherClass::some_method”

(Actually, I posted this code before back in March)

Phil

···

Edward Wilson web2ed@yahoo.com wrote:

Here’s something I wrote a while back:

http://rm-f.net/~cout/code/ruby/treasures/RubyTreasures-0.3/lib/hacks/interface.rb.html

but as I use Ruby more and more, I see less and less use for this.

Paul

···

On Wed, Oct 16, 2002 at 01:02:16PM +0900, Edward Wilson wrote:

Is there a way to write/inforce interfaces in Ruby like one can using
Abstract Classes in C++ or Interfaces in Java?

If not, how has everyone been approaching this?

Is there a way to write/inforce interfaces in Ruby like one can using
Abstract Classes in C++ or Interfaces in Java?

If not, how has everyone been approaching this?

I don’t think C++ abstract classes are that similar to Java interfaces.

Not having used Java interfaces extensively, I can’t speak about their
subtleties, but Java interfaces and C++ abstract classes are used for
similar functions. Both are used to say “this class implements this set
of functions.” This is particularly important in C++, since, through
the magic of virtual functions, it allows me to write a single function
that can accept objects of many different types, without using
templates. This is less useful in Ruby, since an object always retains
its type when I pass it as a parameter to a method (whereas in C++ I
only have a reference to the base class).

I don’t see the need for interfaces in a language with mix-ins.

This doesn’t make sense to me. I see interfaces and mixins as
orthogonal concepts; interfaces are used to specify a contract, while
mixins are used to provide additional methods to a class.

When I want something like a C++ abstract class, I use a class
cluster. Maybe that’s just my ObjC background showing.

What is a “class cluster”? Can you provide an example?

Paul

···

On Wed, Oct 16, 2002 at 01:30:04PM +0900, Chris Gehlker wrote:

On Tuesday, October 15, 2002, at 09:02 PM, Edward Wilson wrote:

http://rm-f.net/~cout/code/ruby/treasures/RubyTreasures-0.3/lib/hacks/interface.rb.html

but as I use Ruby more and more, I see less and less use for this.

Paul

This is what I was getting at. Nice code. Why do you feel that this
is not needed in Ruby?

I want to be able to create a specification, actually a bunch of them,
and enforce that subclasses of each would always implement a base set
of methods that could always be counted on to exist. Whoever said
contract gets the point that I’m after. Think JDBC, for those of
you who know Java, you know that JDBC is nothing but a contract that
all vendors must implement in exactly the same way from the API,
internally they are free to do as the wish. I want to enforce this
same kind of contract in my code, not the database layer just the
contract concept. I understand Ruby’s `mixins’ to be a work around
for Ruby’s lack of MI support. I understand Java uses Interfaces to
work around its lack of MI support as well, however this is not my aim
with this post, I’m stricly looking for contract enforcement.

Paul’s code is great, but I was hoping for something `sorta’
built-into Ruby already. I think contract support is needed in large
scall applications, somethig which Ruby could be used for more and
more given the effects of More’s Law and Ruby’s clean OO model.
Abstract Classes in C++, and Java’s Inerfaces are neccessary for
building large scale applications. My shop uses C++ Abstract classes
all the time to enforce contracts; it would be difficult without them.

Thanks for the discussion from everyone thus far…

//ed

I don’t see the need for interfaces in a language with mix-ins.

This doesn’t make sense to me. I see interfaces and mixins as
orthogonal concepts; interfaces are used to specify a contract, while
mixins are used to provide additional methods to a class.

Paul

The confusion arises because if you mix in a module, it effectively becomes
part of the inheritance chain. For instance:

[1,2,3].is_a? Enumerable
(‘a’ … ‘z’).is_a? Enumerable
“dog”.is_a? Enumerable

Thus, the methods of Enumerable can be sent to String, Array, and Range. This
is like a Java interface. More specifically, it’s like one use of an
interface: part of the built-in library advertising capabilities, like
Comparable, Runnable, etc.

The main use for Java interfaces in user code is for business objects, for some
definition of “business”. You learn something about the objects by looking at
the interfaces, whereas with mixins, because they provide functionality, and
the ingenious one Enumerable provides really cool functionality for you for
free, can only tell you what the capabilities of an object are, not much about
its use.

I’ve actually never written a module, but I believe they are meant to be spread
functionality far and wide, whereas Java interfaces are basically for
modelling. There simply is no equivalent in the Ruby language, and do I care?
No.

The original poster should search www.ruby-talk.org for “java interface” if he
wants to see more discussions. (I haven’t tried it, but it’s sure to return a
goldmine.)

Gavin

···

From: “Paul Brannan” pbrannan@atdesk.com

Is there a way to write/inforce interfaces in Ruby like one can using
Abstract Classes in C++ or Interfaces in Java?

If not, how has everyone been approaching this?

I don’t think C++ abstract classes are that similar to Java
interfaces.

Not having used Java interfaces extensively, I can’t speak about their
subtleties, but Java interfaces and C++ abstract classes are used for
similar functions. Both are used to say “this class implements this
set
of functions.” This is particularly important in C++, since, through
the magic of virtual functions, it allows me to write a single function
that can accept objects of many different types, without using
templates. This is less useful in Ruby, since an object always retains
its type when I pass it as a parameter to a method (whereas in C++ I
only have a reference to the base class).

I don’t see the need for interfaces in a language with mix-ins.

This doesn’t make sense to me. I see interfaces and mixins as
orthogonal concepts; interfaces are used to specify a contract, while
mixins are used to provide additional methods to a class.

It’s just that the contract is used as a weak form of multiple
inheritance. At least I’ve never seen it used any other way. And it is
called “Interface Inheritance” because it allows the programmer to add
functionality to a class that is orthogonal to the functionality of the
main inheritance path. For example if bird inherits from animal and
implements flight then a bird ‘is a’ animal but a bird also ‘is a’
flier. In Ruby I’d just make flight a mixin.

When I want something like a C++ abstract class, I use a class
cluster. Maybe that’s just my ObjC background showing.

What is a “class cluster”? Can you provide an example?

Lets start with the hoary example from C++ of the abstract class shape
whose only non-virtual methods are move and resize where resize
operates on a circumscribed rectangle and whose only attributes are the
coordinates of the bounding rectangle. To do something similar in
dynamic languages, you define a class shape with move and resize
methods but you make shape’s new method private. Then you define
concrete constructors such as create_circle_with_radius(r) and
create_rectangle_with_sides(length, width) etc. Of course you derive
circle, rectangle, pentagon and friends from shape. You can call
draw(boundingBox) in shapes move and resize methods so long as every
child of shape defines a draw method.

Shape is called a class cluster because the private constructor
guarantees that any variable referencing a shape is actually
referencing a member of a concrete subclass. Use it as you would an
abstract class.

I hope that helps. It was pretty condensed so ask again if it’s
confusing. I’ll try to provide a better example.

···

On Wednesday, October 16, 2002, at 07:12 AM, Paul Brannan wrote:

On Wed, Oct 16, 2002 at 01:30:04PM +0900, Chris Gehlker wrote:

On Tuesday, October 15, 2002, at 09:02 PM, Edward Wilson wrote:


Cogito Ergo Spud. - I think therefore I yam.

I have to disagree with the statement that something like Interfaces is
needed for large scale systems. Many a Lisp or Smalltalk system has been
built that doesn’t have this specific language concept, and they are in very
mission critical areas that can’t afford failure. Compile time checking is
not an end all be all. Enforcement of these ideas in a dynamic system can be
done in other ways and in Ruby, mixin’s can provide the same end result. A
class is known to implement a given feature set.

It is my understanding as well, that contracts weren’t just about the
methods that a particular class implemented, but that they were also about
things like variables not crossing certain thresholds, values not being of
the wrong type, etc. They were more than interface specification adherence!

···

On 10/16/2002 11:08 PM, in article 5174eed0.0210162008.8eb00c3@posting.google.com, “Edward Wilson” web2ed@yahoo.com wrote:

I think contract support is needed in large
scall applications, somethig which Ruby could be used for more and
more given the effects of More’s Law and Ruby’s clean OO model.
Abstract Classes in C++, and Java’s Inerfaces are neccessary for
building large scale applications. My shop uses C++ Abstract classes
all the time to enforce contracts; it would be difficult without them.

Thanks for the discussion from everyone thus far…

//ed


Sam Griffith Jr.
email: staypufd@mac.com
Web site: http://homepage.mac.com/staypufd/index.html

This is what I was getting at. Nice code. Why do you feel that this
is not needed in Ruby?

See:
[ruby-talk:51906]
[ruby-talk:13709]
[ruby-talk:03591]
[ruby-talk:06405]

There’s probably many many more where those came from.

Whoever said contract gets the point that I’m after. Think JDBC,
for those of you who know Java, you know that JDBC is nothing but a
contract that all vendors must implement in exactly the same way
from the API, internally they are free to do as the wish.

I think I read it somewhere on a wiki.

Paul’s code is great, but I was hoping for something `sorta’
built-into Ruby already. I think contract support is needed in large
scall applications, somethig which Ruby could be used for more and
more given the effects of More’s Law and Ruby’s clean OO model.
Abstract Classes in C++, and Java’s Inerfaces are neccessary for
building large scale applications. My shop uses C++ Abstract classes
all the time to enforce contracts; it would be difficult without them.

The argument I see over and over is that unit testing is an acceptable
and preferable alternative to contracts. I’m not sure whether I agree.

Paul

···

On Thu, Oct 17, 2002 at 01:25:57PM +0900, Edward Wilson wrote:

This doesn’t make sense to me. I see interfaces and mixins as
orthogonal concepts; interfaces are used to specify a contract, while
mixins are used to provide additional methods to a class.

It’s just that the contract is used as a weak form of multiple
inheritance. At least I’ve never seen it used any other way.

I think that MI can be used to implmement the contract, but that does
not mean that the contract is a form of MI.

And it is called “Interface Inheritance” because it allows the
programmer to add functionality to a class that is orthogonal to the
functionality of the main inheritance path. For example if bird
inherits from animal and implements flight then a bird ‘is a’ animal
but a bird also ‘is a’ flier. In Ruby I’d just make flight a mixin.

Interface inheritance does not add any functionality to a class.

The goals behind an interface or abstract class are:

  1. Be able to write a function that can take as a parameter any object
    that inherits from the abstract class (generic programming).
  2. Be able to easily determine whether a given concrete class has a
    particular set of features

In Ruby:

  • #1 is unnecessary in Ruby, because any method can accept any object
    as a parameter.
  • #2 is the source of an ongoing debate on ruby-talk.

If there are other uses for interface inheritance (besides derivatives
of the above), then I am yet to see them in use.

What is a “class cluster”? Can you provide an example?

Lets start with the hoary example from C++ of the abstract class shape
whose only non-virtual methods are move and resize where resize
operates on a circumscribed rectangle and whose only attributes are the
coordinates of the bounding rectangle. To do something similar in
dynamic languages, you define a class shape with move and resize
methods but you make shape’s new method private. Then you define
concrete constructors such as create_circle_with_radius(r) and
create_rectangle_with_sides(length, width) etc. Of course you derive
circle, rectangle, pentagon and friends from shape. You can call
draw(boundingBox) in shapes move and resize methods so long as every
child of shape defines a draw method.

Shape is called a class cluster because the private constructor
guarantees that any variable referencing a shape is actually
referencing a member of a concrete subclass. Use it as you would an
abstract class.

I hope that helps. It was pretty condensed so ask again if it’s
confusing. I’ll try to provide a better example.

Yes, it’s confusing. I tried implementing your example in Ruby, but I
ran into the following problems:

  1. If resize is a method of Shape, then what parameters does it take?
    For a Circle, I would expect it to take a radius, but for a
    Rectangle, I would expect it to take a length and a width.
  2. I could not figure out how to define a concrete constructor for
    Rectangle while still making it impossible to accidentally
    instantiate a Rectangle without going through the factory method
    (if I can’t call Rectangle.new, then neither can the factory
    method).
  3. Having a private constructor in Ruby doesn’t make sense; this is
    the purpose of a Module (you can always instantiate a Class, but
    you can’t always instantiate a Module).

Perhaps if you provide a sample implementation it would be easier to
see.

Paul

···

On Thu, Oct 17, 2002 at 12:45:41AM +0900, Chris Gehlker wrote:

The argument I see over and over is that unit testing is an
acceptable and preferable alternative to contracts. I’m not sure
whether I agree.

Wouldn’t DbC take care of this?

http://www.pragmaticprogrammer.com/ruby/downloads/dbc.html

I mean, I’m not going to pretend that I understand DbC, yet, despite
having read PP, but if an interface is supposed to represent a
contract, why not use real contracts in the code?

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.10.17 at 11.57.01

[Not strictly related to your post, Paul, just blatantly taking some
words as an excuse to go off on a tangent.]

When building contracts, interfaces and all that into a class, it
seems to me that the programmer is trying to carry out two related,
but different tasks: making the object behave in a certain way, and
certifying that indeed it does.

Now some things bug me about that. First, as it has already been
discussed in this group, even if a class implements, say, an interface
that includes openFile(String path), inferring that upon calling a
file will be opened is still a matter of deduction and trust. The
only thing we know for sure is that there is a method called
`openFile’ and that it accepts a String argument.

Second, is certifying a behaviour really a class’s responsibility?

(I imagine posing that question in a Java group and being flamed to
death. In fact, I don’t think I would ever have thought about that if
I hadn’t got a bit of experience in Ruby.)

Think about this: you’re an object from some programming language,
you’ve just got back home after a long day at school where you’ve
learnt lots of things, when someone rings at your door. You go open
it and here’s a guy asking, ``Can you please do X for me?‘’

There are three things you could answer:

``Yes.‘’ (Who taught you said that you can do X, so it must be
true… really?)

``No.‘’ (Who taught you said that you can’t do X, so it must be
true… really?)

``Let’s try.‘’ (They just taught you things. It’s up to who asked
you, to judge if what you can do is enough.)

Now what scenario do you like the best?

Personally I mostly like the third. I’m asking something of
someone, so I’d better ensure that he’s up to it. After that, I trust
him and I don’t keep checking over and over.

Could it be that I haven’t tested him enough? Sure…

Is testing expensive, compared to just trusting his certifications?
Sure…

Will I still keep testing before trusting? Guess it. :slight_smile:

Massimiliano

···

On Fri, Oct 18, 2002 at 12:16:30AM +0900, Paul Brannan wrote:

The argument I see over and over is that unit testing is an acceptable
and preferable alternative to contracts. I’m not sure whether I agree.

The goals behind an interface or abstract class are:

  1. Be able to write a function that can take as a parameter any object
    that inherits from the abstract class (generic programming).
  2. Be able to easily determine whether a given concrete class has a
    particular set of features

In Ruby:

  • #1 is unnecessary in Ruby, because any method can accept any object
    as a parameter.
  • #2 is the source of an ongoing debate on ruby-talk.

Doesn’t the fact that a class mixes in the mixin satisfy goal number 2? I
mean if you have that mixin, then you are implementing a particular set of
features. In the case of the mixin, you get the mixin’s default
implementation and if you’d like you can overload what you want changed for
your particular class. So you know you do implement those features or at
least inherit some default implementation.

The fact that you can inherit default implementations is also something that
makes Ruby’s mixin’s more powerful than Java’s interfaces. And it is also a
point for weak typing. The reason you can’t have Java interfaces provide
default implementations is the strong typing.

Just a thought!

···


Sam Griffith Jr.
email: staypufd@mac.com
Web site: http://homepage.mac.com/staypufd/index.html

On 10/16/2002 4:34 PM, in article 20021016173355.B3400@atdesk.com, “Paul Brannan” pbrannan@atdesk.com wrote:

On Thu, Oct 17, 2002 at 12:45:41AM +0900, Chris Gehlker wrote:

This doesn’t make sense to me. I see interfaces and mixins as
orthogonal concepts; interfaces are used to specify a contract, while
mixins are used to provide additional methods to a class.

It’s just that the contract is used as a weak form of multiple
inheritance. At least I’ve never seen it used any other way.

I think that MI can be used to implmement the contract, but that does
not mean that the contract is a form of MI.

And it is called “Interface Inheritance” because it allows the
programmer to add functionality to a class that is orthogonal to the
functionality of the main inheritance path. For example if bird
inherits from animal and implements flight then a bird ‘is a’ animal
but a bird also ‘is a’ flier. In Ruby I’d just make flight a mixin.

Interface inheritance does not add any functionality to a class.

The goals behind an interface or abstract class are:

  1. Be able to write a function that can take as a parameter any object
    that inherits from the abstract class (generic programming).
  2. Be able to easily determine whether a given concrete class has a
    particular set of features

In Ruby:

  • #1 is unnecessary in Ruby, because any method can accept any object
    as a parameter.
  • #2 is the source of an ongoing debate on ruby-talk.

If there are other uses for interface inheritance (besides derivatives
of the above), then I am yet to see them in use.

What is a “class cluster”? Can you provide an example?

Lets start with the hoary example from C++ of the abstract class shape
whose only non-virtual methods are move and resize where resize
operates on a circumscribed rectangle and whose only attributes are the
coordinates of the bounding rectangle. To do something similar in
dynamic languages, you define a class shape with move and resize
methods but you make shape’s new method private. Then you define
concrete constructors such as create_circle_with_radius(r) and
create_rectangle_with_sides(length, width) etc. Of course you derive
circle, rectangle, pentagon and friends from shape. You can call
draw(boundingBox) in shapes move and resize methods so long as every
child of shape defines a draw method.

Shape is called a class cluster because the private constructor
guarantees that any variable referencing a shape is actually
referencing a member of a concrete subclass. Use it as you would an
abstract class.

I hope that helps. It was pretty condensed so ask again if it’s
confusing. I’ll try to provide a better example.

Yes, it’s confusing. I tried implementing your example in Ruby, but I
ran into the following problems:

  1. If resize is a method of Shape, then what parameters does it take?
    For a Circle, I would expect it to take a radius, but for a
    Rectangle, I would expect it to take a length and a width.
  2. I could not figure out how to define a concrete constructor for
    Rectangle while still making it impossible to accidentally
    instantiate a Rectangle without going through the factory method
    (if I can’t call Rectangle.new, then neither can the factory
    method).
  3. Having a private constructor in Ruby doesn’t make sense; this is
    the purpose of a Module (you can always instantiate a Class, but
    you can’t always instantiate a Module).

Perhaps if you provide a sample implementation it would be easier to
see.

Paul

This doesn’t make sense to me. I see interfaces and mixins as
orthogonal concepts; interfaces are used to specify a contract, while
mixins are used to provide additional methods to a class.

It’s just that the contract is used as a weak form of multiple
inheritance. At least I’ve never seen it used any other way.

I think that MI can be used to implmement the contract, but that does
not mean that the contract is a form of MI.

I was just expressing the conventional wisdom. See for example, Sun’s
Java tutorial or here;
http://research.sun.com/techrep/1993/abstract-21.html

And it is called “Interface Inheritance” because it allows the
programmer to add functionality to a class that is orthogonal to the
functionality of the main inheritance path. For example if bird
inherits from animal and implements flight then a bird ‘is a’ animal
but a bird also ‘is a’ flier. In Ruby I’d just make flight a mixin.

Interface inheritance does not add any functionality to a class.

Agreed.

The goals behind an interface or abstract class are:

  1. Be able to write a function that can take as a parameter any
    object
    that inherits from the abstract class (generic programming).

I don’t agree that an interface, in the Java sense, and an abstract
class, in the Java/C++ sense are synonymous or that an interface has
necessary relationship to generic programming. Generic programming came
out of C++, which has no notion of interface.

  1. Be able to easily determine whether a given concrete class has a
    particular set of features

In Ruby:

  • #1 is unnecessary in Ruby, because any method can accept any object
    as a parameter.
  • #2 is the source of an ongoing debate on ruby-talk.

If there are other uses for interface inheritance (besides derivatives
of the above), then I am yet to see them in use.

I believe the most common uses of the abstract class are:

  1. To provide code clarity and to avoid code duplication
  2. To provide a way of referencing an object who’s type is not
    determined until run time, for example, the elements of a display list
    in a drawing program.

There are also:
3) Idiosyncratic but very clever uses as, for example, in the STL,
where it is somewhat obscured by all the template stuff, and in GNUStep
where it isn’t.

Motivation 2 disappears in dynamic langaguages. 1 and 3 remain.

What is a “class cluster”? Can you provide an example?

Lets start with the hoary example from C++ of the abstract class shape
whose only non-virtual methods are move and resize where resize
operates on a circumscribed rectangle and whose only attributes are
the
coordinates of the bounding rectangle. To do something similar in
dynamic languages, you define a class shape with move and resize
methods but you make shape’s new method private. Then you define
concrete constructors such as create_circle_with_radius(r) and
create_rectangle_with_sides(length, width) etc. Of course you derive
circle, rectangle, pentagon and friends from shape. You can call
draw(boundingBox) in shapes move and resize methods so long as every
child of shape defines a draw method.

Shape is called a class cluster because the private constructor
guarantees that any variable referencing a shape is actually
referencing a member of a concrete subclass. Use it as you would an
abstract class.

I hope that helps. It was pretty condensed so ask again if it’s
confusing. I’ll try to provide a better example.

Yes, it’s confusing. I tried implementing your example in Ruby, but I
ran into the following problems:

  1. If resize is a method of Shape, then what parameters does it take?
    For a Circle, I would expect it to take a radius, but for a
    Rectangle, I would expect it to take a length and a width.

All shapes are resized by dragging a handle on their bounding box. This
is the way real drawing programs work. One would not expect the user to
learn a different resizing method for each type of shape. The bounding
box method is generic. That’s why it belongs in the virtual/cluster
base class.

  1. I could not figure out how to define a concrete constructor for
    Rectangle while still making it impossible to accidentally
    instantiate a Rectangle without going through the factory method
    (if I can’t call Rectangle.new, then neither can the factory
    method).

There is no need to enforce the use of the factory method. What needs
to be enforced is that the program cannot instantiate an instance of
the cluster base class. This corresponds directly to the C++ case where
their is no enforcement of a restriction on directly constructing a
derived concrete class but there is enforcement of the “no
instantiation of virtual classes” rule.

  1. Having a private constructor in Ruby doesn’t make sense; this is
    the purpose of a Module (you can always instantiate a Class, but
    you can’t always instantiate a Module)

Having a private constructor makes sense for cluster base classes and
singleton classes.

Perhaps if you provide a sample implementation it would be easier to

I’ll try and translate my drawing program from ObjC to Ruby.

···

On Wednesday, October 16, 2002, at 02:34 PM, Paul Brannan wrote:

On Thu, Oct 17, 2002 at 12:45:41AM +0900, Chris Gehlker wrote:


Cogito Ergo Spud. - I think therefore I yam.

The intent of an interface is not to cerfity a particular behavior. It
is to certify that the author’s intent is for the class to have a
particular behavior.

Paul

···

On Fri, Oct 18, 2002 at 08:13:18PM +0900, Massimiliano Mirra wrote:

Now some things bug me about that. First, as it has already been
discussed in this group, even if a class implements, say, an interface
that includes openFile(String path), inferring that upon calling a
file will be opened is still a matter of deduction and trust. The
only thing we know for sure is that there is a method called
`openFile’ and that it accepts a String argument.

Second, is certifying a behaviour really a class’s responsibility?

The argument I see over and over is that unit testing is an acceptable
and preferable alternative to contracts. I’m not sure whether I agree.

[Not strictly related to your post, Paul, just blatantly taking some
words as an excuse to go off on a tangent.]

When building contracts, interfaces and all that into a class, it
seems to me that the programmer is trying to carry out two related,
but different tasks: making the object behave in a certain way, and
certifying that indeed it does.

Now some things bug me about that. First, as it has already been
discussed in this group, even if a class implements, say, an interface
that includes openFile(String path), inferring that upon calling a
file will be opened is still a matter of deduction and trust. The
only thing we know for sure is that there is a method called
`openFile’ and that it accepts a String argument.

Second, is certifying a behaviour really a class’s responsibility?

> Massimiliano

Thank you. Finally, this discussion is getting down to it’s philosophical
essence. An object’s behaviour and the certification of that behaviour are
two totally separate concerns. Mixing the code from those two separate
concerns just makes a muddy mess.

···

On Friday 18 October 2002 11:13 am, Massimiliano Mirra wrote:

On Fri, Oct 18, 2002 at 12:16:30AM +0900, Paul Brannan wrote:


Best essay I’ve read in years:

The reason you can’t have Java interfaces provide implementation has
less to do with strong typing and more to do with Java’s disdain for
multiple inheritance. I mix-in implementation in Eiffel all the time,
and Eiffel is more strongly typed than Java.

···

On Wed, 2002-10-16 at 22:05, Sam Griffith wrote:

The fact that you can inherit default implementations is also something that
makes Ruby’s mixin’s more powerful than Java’s interfaces. And it is also a
point for weak typing. The reason you can’t have Java interfaces provide
default implementations is the strong typing.


– Jim Weirich jweirich@one.net http://w3.one.net/~jweirich

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

I don’t agree that an interface, in the Java sense, and an abstract
class, in the Java/C++ sense are synonymous

An abstract class in C++, with all pure virtual methods and no data, is
semantically equivalent to a Java interface[1]. They are often used in
C++ programs in ways similar to Java interfaces.

[…]

There are also:
3) Idiosyncratic but very clever uses as, for example, in the STL,
where it is somewhat obscured by all the template stuff, and in GNUStep
where it isn’t.

I’m not sure what you are refering to here, but it sounds interesting.
Examples?

I’ll try and translate my drawing program [with class cluster examples] >
from ObjC to Ruby.

I, too, am interested in seeing this.

···

On Wed, 2002-10-16 at 22:19, Chris Gehlker wrote:


– Jim Weirich jweirich@one.net http://w3.one.net/~jweirich

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

The goals behind an interface or abstract class are:

  1. Be able to write a function that can take as a parameter any
    object that inherits from the abstract class (generic
    programming).

I don’t agree that an interface, in the Java sense, and an abstract
class, in the Java/C++ sense are synonymous or that an interface has
necessary relationship to generic programming. Generic programming came
out of C++, which has no notion of interface.

I think I was mistaken to call this “generic programming,” which is
similar but different. Must have been too much sugar after lunch. :slight_smile:
I think the correct word is “polymorphism.”

http://www.c2.com/cgi/wiki?PolymorphismExample

I believe the most common uses of the abstract class are:

  1. To provide code clarity and to avoid code duplication

I can agree that abstract classes can help provide clarity. I don’t see
how they avoid code duplication, since pure abstract base classes are
not supposed to have any implementation.

  1. To provide a way of referencing an object who’s type is not
    determined until run time, for example, the elements of a display list
    in a drawing program.

This also falls under polymorphism.

There are also:
3) Idiosyncratic but very clever uses as, for example, in the STL,
where it is somewhat obscured by all the template stuff, and in GNUStep
where it isn’t.

Motivation 2 disappears in dynamic langaguages. 1 and 3 remain.

I can’t think of a case in Ruby where #3 would apply.

There is no need to enforce the use of the factory method. What needs
to be enforced is that the program cannot instantiate an instance of
the cluster base class. This corresponds directly to the C++ case where
their is no enforcement of a restriction on directly constructing a
derived concrete class but there is enforcement of the “no
instantiation of virtual classes” rule.

In Ruby, if the base class has implementation, I would almost certainly
throw it into a Module, because you cannot instantiate a Module. If it
has no implementation (the “Toy” abstract base class in the wiki link
above), then I generally remove it completely.

What would keep you from turning your cluster base class into a Module,
and using it as a mixin?

Paul

···

On Thu, Oct 17, 2002 at 11:19:04AM +0900, Chris Gehlker wrote: