From: Steve Tuckner Date: 2002-10-11T00:22:53+09:00 Subject: Re: Polymorphism, Isomorphism First of all, I think that itis a good idea to be able to check if classes support protocols. But since ruby does not advertise what and how many parameters are required for particular methods, the responds_to_protocol? operation would be pretty weak. For an example if the IO library were described in smalltalk selector way, the protocol would be: foreach: new:mode: pipe popen:mode: ... write: In ruby we only get the method name so that if I define a foreach function def foreach(filename, option1, option2, option3) ... end then it would detect my class as supporting foreach when it really is not compatible. Steve Tuckner -----Original Message----- From: Jim Menard [mailto:jimm@io.com] Sent: Thursday, October 10, 2002 9:55 AM To: ruby-talk ML Subject: Re: Polymorphism, Isomorphism ptkwt@shell1.aracnet.com (Phil Tomson) writes: > In article , Jim Menard wrote: > >I'm most interested in seeing if an object > >responds to a handful of particular methods. That's mostly because I only > >need to know what an object can do when it is an argument passed to a > >method. It's almost a question with a local scope: "can you do a, b, and > >c?" > > Hmmm.... So you're proposing something like: > > ClassA.containsMethods(:foo, :bar, :baz) > > or something similar. Yes. Even better, what about needed_methods = [:foo, :bar, :baz] ClassA.containsMethods(needed_methods) needed_methods can be a simple array, or some class that can (as you suggested) perform set and logical operations. Are we re-inventing protocols? It feels like it. See the code below. [snip] > Or, and now this is getting pretty crazy, what if you get an instance of > an object which represented the union - this would be something very close > to multiple-inheritance or maybe mixin (it would probably share all of > the problems of MI - like if a certain method exists in both 'parent' > classes which one do you take?). Or even an instance of a class which > represents the intersection of two classes - not sure what that would be akin> to - and again you have the problem of determining which method from > which class to choose, so perhaps it would be best to stick to lists of > method names as the result of these logic operations. Sans the logical and set operators, it sounds like a protocol. I think this does what I would want. class Class # Respond true only if this class responds to the instance methods # contained as symbols in array_of_symbols. def responds_to_protocol?(array_of_symbols) return array_of_symbols.detect { | sym | !method_defined?(sym) }.nil? # This may do the same thing, I'm not sure: # return (array_of_symbols & instance_methods).length == array_of_symbols.length end end file_protocol = [:atime, :chmod, :chown] File.responds_to_protocol?(file_protocol) # => true Numeric.responds_to_protocol?(file_protocol) # => false You'd need another method to answer the same question for class methods. This is fun! Yay, Ruby! Jim -- Jim Menard, jimm@io.com, http://www.io.com/~jimm/ "The theory of computation states that all automatons can be emulated by a Turing machine. I have a less abstract but more practical motto: If you can do it on Intel, you can do it damn near anywhere!" -- Eugene O'Neil