From: matz@... (Yukihiro Matsumoto) Date: 2000-09-08T01:23:24+09:00 Subject: [ruby-talk:03242] Re: Questions re: "new" "+=" etc. Hi, In message "[ruby-talk:03234] Questions re: "new" "+=" etc." on 00/06/09, hal9000@hypermetrics.com writes: |Firstly: | |I was trying to create an object that could be added |to itself. I tried to implement the + operator, and |I discovered that I could not invoke "new" from |within the class -- see line (e). I assume this is |a feature -- but why? You have to know that instance methods and class methods are totally different things in Ruby, unlike some languages. (e) tries to invoke an instance method named `new', not a class method. | def + (other) | case other.type.to_s | when "Wocka" | Wocka(@data + other.data) # Line (b) |# self.type.new(@data + other.data) # Line (c) |# type.new(@data + other.data) # Line (d) |# new(@data + other.data) # Line (e) | when "Fixnum" | Wocka(@data + other) | else | raise "Adding an unsupported type to a Wocka object." | end | end |Secondly: | |Since I implemented the + operator, the += operator |should have been created for me. (And it was, as I |confirmed.) First of all, += is not a redefinable operator methods. a += b is a syntax sugar for a = a + b. This does not mean Ruby create a += method automagically. Since it's not a method, defined? does not check += method. And I feel something weird if a + b alters the status of a. For example, Array#+ returns a concatenated array, but does not alter the operands, on the other hand, Array#concat append the element to the array. |Thirdly: | |Line (i) requires parens -- not sure why -- see line (j). |This tells me Wocka::+ is NOT defined. Lines (i) and (j) checks for a class method named `+', which is not defined. Line (k) checks for `+=', which is not a valid method name. This explains why lines (k) and (m) raises error. Line (l) checks for x's instance method named `+', which is what you want to check, thus returns the value you expected. |# if defined? Wocka::+ # Line (i) |if defined? (Wocka::+) # Line (j) | print "Wocka::+ is defined\n" |else | print "Wocka::+ is NOT defined\n" |end | |# if defined?(Wocka::+=) # Line (k) |# print "Wocka::+= is defined\n" |# else |# print "Wocka::+= is NOT defined\n" |# end | | |if defined?(x.+) # Line (l) | print "x.+ is defined\n" |else | print "x.+ is NOT defined\n" |end | |# if defined?(x.+=) # Line (m) |# print "x.+= is defined\n" |# else |# print "x.+= is NOT defined\n" |# end Hope this helps matz.