From: Paul Brannan Date: 2002-10-02T22:45:15+09:00 Subject: Re: thoughts on typelessness On Wed, Oct 02, 2002 at 11:31:59AM +0900, GOTO Kentaro wrote: > At Wed, 2 Oct 2002 10:58:08 +0900, > Paul Brannan wrote: > > But in my mind, this is still an explicit conversion, because String#% > > explicitly calls to_s(). > > I don't think that is explicit conversion because we couldn't know > which method would be called. For example, I was surprised by > > % ruby -e 'class A; def to_int() 10 end end; p("%o" % A.new)' > "12" > % ruby17 -e 'class A; def to_int() 10 end end; p("%o" % A.new)' > "12" > % ruby17 -e 'class A; def to_i() 10 end end; p("%o" % A.new)' > "12" > % ruby17 -e 'class A; def to_i() 10 end; def to_int() 0 end end; p("%o" % A.new)' > "0" > % ruby -e 'class A; def to_i() 10 end end; p("%o" % A.new)' > -e:1:in `%': failed to convert A into Integer (TypeError) > from -e:1 I see how this would be confusing. However, I still think this is explicit conversion, because *somebody* has control over what type the object is coerced into. In C/C++, there are situations where the compiler decides what type the object is converted into; this is what C++ programmers generally consider implicit conversion. Even if we wrote a function like: template void foo(T obj) { // Convert the object to a C string, then print it printf("%s\n", obj.c_str()); } this would still be explicit conversion, because the function is choosing to convert the object into a string. However, the following would be implicit conversion, because the compiler makes the decision to convert the object: class String { public: String(char const * s) : s_(s) { } operator char const *() const { return s_; } private: char const * s_; }; void foo(char const * s) { // We already have a C string, so no need to explicitly convert printf("%s\n", s); } int main() { String s("this is a test"); foo(s); } Paul