In article <20050130152440.A4430 / cs.mcgill.ca>, Navindra Umanee <navindra / cs.mcgill.ca> wrote: > Yukihiro Matsumoto <matz / ruby-lang.org> wrote: > > |Okay, so object.class will supposedly tell you what class an object > > |is... but you can override that method and nobody really cares. So > > |Ruby doesn't guarantee anything about type safety. > > > > Define "type safety" here. I consider it as that every type error can > > be found (at run time), and no fatal error (e.g. segmentation fault) > > can be caused by type mismatch. > > > > What is yours? Ability to tell an object's class? Inability to > > change the class of an object at run time? > > Thinking about it, I think my problem is that I didn't have a proper > concept of what a type is in Ruby. However, if I revert back to duck > typing as a concept, I finally get a definition: > > In Ruby, an object is of type Duck if: > > (1) The object walks like a duck. > (2) The object quacks like a duck. > > Since Ruby always makes sure an object is of type Duck if it needs a > duck, Ruby is type safe. > > Duck typing is a loose concept however as shown in the previous > discussions (an object can be an arbitrary number of types and/or > types overlap), and I am not sure if you can call such a thing strong > typing although Ruby is type safe within the definition of duck > typing. > > Cheers, > Navin. Hi Navin., I think you're making the mistake of equating objects and object references. Objects have a specific type, and the type of an object doesn't change. Variables, on the other hand, are just object references. The object they refer to changes with assignment. If you fire up irb, you can check the type of a given object by sending it the "type" message. For example: irb(main):001:0> (2**30 - 1).type => Fixnum irb(main):002:0> (2**30).type => Bignum If I assign the part of the first expression in parentheses to a variable x, then x now refers to a variable of type Fixnum: irb(main):003:0> x = (2**30 - 1) => 1073741823 irb(main):004:0> x.type => Fixnum If I add 1 and store the result in x, the variable x now references an object of type Bignum: irb(main):005:0> x = x + 1 => 1073741824 irb(main):006:0> x.type => Bignum The type of object "1073741823" hasn't changed: irb(main):007:0> 1073741823.type => Fixnum but x no longer references that object. It's important to note that an expression can yield a type which is different than the types of the operands within that expression, e.g., <Fixnum> + <Fixnum> can yield a <Fixnum> or <Bignum>. If the result is assigned to a variable, the variable seems to change type if you equate a reference with the thing being referenced. In Java, you have objects and primitives, which are distinct types of things that can't be intermixed. Java requires you to declare the type associated with a variable to avoid the kind of insanity which would occur if you started trying to send messages to primitives. That results in ugliness such as Arrays.sort(), which has to have many overloaded implementations - one for Objects, and one each for each type of primitive. Contrast with Ruby, where any array can be sorted as long as the elements respond to <=> or you provide a block to be used for comparisons. Getting back to the subject line - In Java, the distinction between primitives and objects requires that variables be declared with a type. I think it takes Java programmers a while to realize that in Ruby variables are always object references, so the "everything is an object" philosophy means that type declarations are unnecessary. --paul