# = elementor.rb
#
# == Copyright (c) 2006 Thomas Sawyer
#
#   Ruby License
#
#   This module is free software. You may use, modify, and/or redistribute this
#   software under the same terms as Ruby.
#
#   This program is distributed in the hope that it will be useful, but WITHOUT
#   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#   FOR A PARTICULAR PURPOSE.
#
# == Authors and Contributors
#
# * Thomas Sawyer

# Author::    Thomas Sawyer
# Copyright:: Copyright (c) 2006 Thomas Sawyer
# License::   Ruby License

require 'facets/core/kernel/object_class'

# = Elementor
#
# Elementor is an Array which applies calls elementwise.
# Depending on the mode the call will return a
# new elementor, the same elementor, a new array,
# or the orignal array transformed.

class Elementor

  private :to_s  #*( instance_methods - [ 'object_class' ] )

  def initialize( an_array, mode=nil )
    @array = an_array
    @mode = mode
  end

  def to_a ; p @array ; @array ; end
  def to_ary ; p @array; @array ; end

  def each( *args, &block )
    @array.each( *args, &block )
  end

  def ==( other )
    @array == other.to_ary
  end

  def method_missing( sym, *args, &block )
    c = @array.collect { |e| e.send( sym, *args, &block ) }
    case @mode
    when :array
      c
    when :inplace_array
      @array.replace( c )
      #@array.collect! { |e| e.send( sym, *args, &block ) }
      @array
    when :inplace
      @array.replace( c )
      self
    else
      object_class.new( c )
    end
  end

end


class Array

  def to_elementor
    Elementor.new( self )
  end

  def to_elementor!
    Elementor.new( self, :inplace )
  end

  def every
    Elementor.new( self, :array )
  end

  def every!
    Elementor.new( self, :inplace_array )
  end

end


#  _____         _
# |_   _|__  ___| |_
#   | |/ _ \/ __| __|
#   | |  __/\__ \ |_
#   |_|\___||___/\__|
#
=begin test

  require 'test/unit'

  class TCElementor < Test::Unit::TestCase

    def test_to_elementor
      e = [1,2,3].to_elementor
      assert_equal( [4,5,6], e + 3 )
      assert_equal( [0,1,2], e - 1 )
    end

    def test_to_elementor_str
      e = [1,2,3].to_elementor
      assert_equal( ['1','2','3'], e.to_s )
    end

    def test_to_elementor!
      e = [1,2,3].to_elementor!
      e + 3
      assert_equal( [4,5,6], e )
    end

    def test_every
      a = [1,2,3]
      assert_equal( [4,5,6], a.every + 3 )
      assert_equal( [0,1,2], a.every - 1 )
      assert_equal( ['1','2','3'], a.every.to_s )
    end

    def test_every!
      a = [1,2,3]
      a.every! + 3
      assert_equal( [4,5,6], a )
    end

  end

=end
