From: Eric Mahurin Date: 2005-08-03T10:40:03+09:00 Subject: Re: [RCR] array or with non-array --- Yukihiro Matsumoto wrote: > Hi, > > In message "Re: [RCR] array or with non-array" > on Wed, 3 Aug 2005 07:34:27 +0900, Eric Mahurin > writes: > > |1) methods have multiple functionalities based on the types > of > |the arguments (usually exact class not just respond_to?). > > Usually using duck types, for example "to_str" for > string-like > objects. It it's not, I consider it a bug. Having the the method take any object that implements the to_s is good duck typing, but then we get right back to static typing as soon the the built-in methods use the result of to_s - they require it to be a string. Having many of the built-in methods do a to_s is nothing more than a convenience (you could easily do the same thing by putting a .to_s appended to those arguments). It doesn't really help the arguments be more polymorphic. If I had a class that implemented all of the String methods, it wouldn't be any good to the built-in classes - to_s would still have to return an actual String, not self. But, this wasn't really what my #1 above was about. It was about overloaded methods where the functionality is determined by looking at the type of the arguments. One example would be String#[arg]: str[fixnum] => fixnum or nil str[range] => new_str or nil str[regexp] => new_str or nil str[other_str] => new_str or nil All of these behave very different. The way you figure out what to do is based on type - which goes against the duck-typing philosophy. I think the only advantage of combining all of these functions into one method is convenience. But, by doing so you loose the ability to handle more general duck-typed/polymorphic arguments. I think the []= method has a more legitimate excuse for the amount of overloading - a syntactical one - because there is no other way to make a method that can be assigned to and have arguments (other than the rvalue). RCR #307 would help solve that issue. > |2) even where a method only has one functionality (or the > |multiple functionalites are determined by means other than > arg > |type/capabilities - flags, number of args, etc), many/most > |built-in methods can't take args that have the same > |capabilities as what is excepted - they only take a certain > |type or maybe one derived from it. > > Example, please? > > matz. I think a primary example where I would really like real duck-typing in a built-in would be Regexp#match(str). This requires the arg to be a String. I would really like to have this be able to operate on a file. If I implement a class that walks like, talks like, quacks like a String but really accesses a file (practically did that in my rubyforge cursor project), it wouldn't do any good because Regexp#match only takes a String - period. The Regexp#match method could be implemented to take ANY object that implemented a some subset of the String API. Now you might say that would be really slow, but you could just make that functionality. Implementation-wise, you could special case when the object in a String and do a much faster implementation (but functionally the same as the general version). A side effect of doing it this way is that you'd have two implementations (with a String arg) that should be functionally equivalent and thus great for testing (could be put in a self-checking mode). Eric ____________________________________________________ Start your day with Yahoo! - make it your home page http://www.yahoo.com/r/hs