Is Array#replace what you're looking for?

Dan

On 8/27/05, David Brady <ruby_talk / shinybit.com> wrote:
> 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?
> 
> 
>