From: Chris Uzdavinis Date: 2001-08-12T08:03:58+09:00 Subject: [ruby-talk:19553] Re: order and freedom in Ruby (was: Re: Re: the wayclass variables work) "Nat Pryce" writes: > It depends what you mean by "significant meaning"... :-) :) > Inheritance has no relationship to type in Ruby (or Smalltalk or > other dynamically typed OO languages). Type is defined by, and only > by, the messages that an object understands at any given > time. Exactly. > Inheritance is merely a convenience mechanism for reusing some or > all of an implementation defined by another class. Inherited > implementation can affect the type of objects instantiated from the > derived class, but that can be overridden at any time. Yes, it's a temporal relationship. Just like humans, we inherit genes from our parents, but we can come out VERY different. Unlike humans, a ruby object can change its genes. > In Ruby, instead of defining classes or interfaces, you define > protocols that objects should speak, and define those protocols > outside the language. This is interesting. What distinction do you make between protocol and interface? Can the protocol be independent from the interface? > You can then define useful classes or modules that implement those > protocols, but a programmer can just as easily write the protocol > from scratch. Yes, in that regard, every ruby function is like a C++ function template. (Gotta make those C++ comparisons...!) template void foo(T arg) { /*...*/ } Rather than an "interface" which is a fixed, hard coded set of requirments, of which perhaps only a subset is actually used, templates use what they call the "concept" approach. ANY arg can be passed in provided that it supports all the necessary concepts which the code places on it. (The difference is a compile-time check is made, rather than runtime.) > An simple example of this kind of protocol is the relationship > between the methods hash and eql? or the Enumerable mixin requiring > the existence of the each method. These are good examples. Do you think that when we write Ruby code that this type of mindset should be the primary kind of issues we think about? How would you suggest we recover when an argument does not support the protocol? Since Ruby is dynamic, object x may not support it now, but if you try again later it might. Or vice versa. There certainly is an element of uncertainty introduced along with all the dynamic capabilities. The trick is keeping it balanced to where you can know what's going on but still have flexibility. I still have this uneasy feeling, though, that nothing can ever be completely trusted, because perfectly working code can easily be broken by other code in another file which is completely unrelated to it. It seems you have to really know everything that is going on in a program to know if it's going to work. Though there are Modules to kind of separate things, it's not truly modular since if your code and mine are running in the same program, my code can break yours, and vice versa. The risk to me is not all just type, but behavior too. In a big application it's unreasonable to expect everyone to study every line of every file that everyone else is working on. So when someone modifies the behavior of Array class such that [] becomes 1-based, for example, he breaks MY working code, which hasn't changed. -- Chris