February 01, 2005

Quack, quack

If it walks like a duck and quacks like a duck, then it must be a duck.


The type systems of Java and Ruby are very different. First and foremost, Java is more statically-typed than Ruby. Then there or other features that pull them appart, such as the fact that in Ruby everything (or almost) is an object, while in Java there are some things that don't qualify as such (primitive types, functions). But there's a more more fundamental, philosophical, difference; namely, the intention behind the type systems.

First of all, let me make a subtle but important distinction that will help understand what comes next. When I refer to the class of an object, I'm talking about the class it was created from. For instance, in Java, new String() creates an object of class String, just like String.new does in Ruby. The type of an object is the set of roles the object can play. Thus, the type of a class is not the same as the class, but typically includes it.

Java uses inheritance (loosely speaking) as the mechanism for defining the type of an object. An object "is a" X if it implements X. While Ruby also supports inheritance, establishing "is a" relationships is not its main purpose. In Ruby an object is of a certain type if it behaves as that type. Thus the saying "if it walks like a duck and quacks like a duck, then it must be a duck" or as it is commonly called, Duck typing. It must be noted, however, that while Ruby has classes, objects are not explicitly declared of to have a certain type.

So, what, concretely, defines what type an object is in Ruby? Well, that's the wrong question to ask. But if you'd still like to hear an answer, an object, conceptually, is of N! types (made of the subsets of all the combinations of methods exposed by the object), where N is the number of methods exposed by the the object,

In a sense, Ruby shifts the notion of type to the client (the client being the code that uses a given object). Thus, an object is (or not) of the type required by client if it implements the operations required by the client.

Ruby types are more granular as well, with the method being the atomic component of the type. In contrast, Java types are defined class by class, interface by interface.

Of course, this is all possible because Ruby is dynamically typed. That, together with the executable definitions concept I posted about before also allows type to vary by object. In Java, all objects created from the same class have the same type, and that type includes the class. In Ruby that may not be so. Look at this piece of code:

class SomeClass
    def method
        puts "within method"
    end
end

value = SomeClass.new
value.method # prints out "within method"

class << value
    private :method
end

value.method # fails with "NoMethodError: private method `method' called for ...

Labels:

4 Comments:

Blogger Martin said...

Right, that's why I said that in Ruby "everything (or almost)" is an object. I should've probably qualified that statement a little better. Thanks for the observation.

Anyway, even though methods are not objects, blocks are. They can be constructed as such and passed around as arguments to methods. In Java, the only way to do that is to create a class with a method that contains the code you want to pass around (e.g., just like you do with Runnable when creating a Thread). But it is clearly not the same and has some limitations.

February 03, 2005 6:17 AM  
Anonymous Anonymous said...

Block's are 2nd class, not objects proper. Yes, they're an implicit parameter, but you can't return them. To make them proper first class you have to wrap them in a Proc object.

February 05, 2005 6:24 PM  
Blogger Sergio Negrinnie said...

hello great post about Java this information is very useful for me because I want to improve my Adult Dress Up Games website!!!

November 04, 2009 1:14 PM  
Blogger Sergio Negrinnie said...

Hey funny topic!!!! I'm very interesting in Silagra Online do you have some information ???

November 11, 2009 8:35 AM  

Post a Comment

<< Home