trans. (T. Onoma) wrote:
> Here's a coding challenge you.
> 
> The R language has the following nifty features for working with arrays. To 
> what degree can you get Ruby to do the same? 

Here's my take. I haven't wrapped it up in a nice module, but it solves 
the sample problems you gave:


class Elements
	include Enumerable
	
	attr_reader :array
	
	def initialize(array, indices = nil)
		@array = array
		@indices = indices
		@indices = (0... / array.size).to_a unless @indices
	end
	
	def method_missing(symbol, *args)
		res = []
		@indices.each {|i|
			res << @array[i].send(symbol, *args)
		}
		return Elements.new(res)
	end
	
	def to_s
		res = ""
		@indices.each {|i|
			res << @array[i].to_s << " "
		}
		return res
	end
	
	def indices(x)
		res = []
		if x.respond_to?(:call)
			@indices.each {|i| res << i if x.call(@array[i])}
		elsif x.respond_to?(:each)
			x.each {|i| res << @indices[i] }
		else
			res << x
		end
		return res
	end
	
	def [] (x)
		return Elements.new(@array, indices(x))
	end
	
	def []= (x,y)
		ind = indices(x)
		if y.respond_to?(:each_with_index)
			y.each_with_index {|v, i| @array[ ind[i] ] = v }
		else
			ind.each {|i| @array[i] = y}
		end
	end
	
	def each
		@indices.each {|i| yield @array[i]}
	end
end

class Array
	def elements
		return Elements.new(self)
	end
end

a = (1..10).to_a
a = a.elements

b = a + 5
puts b

c = b
pos = [0, 1, 2, 4, 6]
c[pos] = c[pos] * 10
puts c

d = c
d[ proc {|x| x % 2 == 0} ] = -1
puts d