From: David Brady Date: 2005-08-28T11:18:53+09:00 Subject: Reopening with a bang: cannot assign to self Hello, I'm writing some code that benefits from extending Array. One of the methods wants to be a bang method. How do I reassign the contents of an Array from within it? (I recognize that subclassing Array might be more proper, but I think the problem exists in the subclass as well.) class Array # returns copy of array, with each value divided by the sum of # the array elements. e.g. [1,2,2] => [0.2, 0.4, 0.4]. # (this code works fine) def normalize total = Float( self.inject {|x,y| x+y} ) self.collect {|x| x/total} end # returns modified array unless array.sum == 1.0, in which case # array is not modified and method returns nil # (this code does not work: syntax error - cannot assign to self) def normalize! total = Float( self.inject {|x,y| x+y} ) if total.zero? nil else self = self.collect {|x| x/total} end end end I can work around the problem by iterating and using self.[]= but the collect is so much cleaner, I have to wonder if there's not a way to use it. Hrm, I've just found "Array#collect!", which will do the trick I need, but I still wonder what the proper Ruby idiom is for extending a class with a bang method that essentially modifies or replaces the entire contents of the object, when there isn't an accessor method. For example, how would you do "Fixnum#div!(x)", e.g. the equivalend of f /= x? I recognize that this entire line of reasoning may be the result of wrongheaded thinking about Ruby. If so, please enlighten me. -dB -- David Brady ruby_talk@shinybit.com I'm feeling really surreal today... OR AM I?