require 'facets/core/kernel/assign_with'

module Kernel

  # Set instance vars using another object.
  #
  #   class O
  #     attr_accessor :d
  #     def initialize( a, b, c, d)
  #       @a = a
  #       @b = b
  #       @c = c
  #       @d = d
  #     end
  #   end
  #   o1 = O.new(1,2,3,4)
  #   o2 = O.new(0,0,0,0)
  #
  #   o2.assign_from( o1, '@a', '@b', '@c', '@d' )
  #   o2.instance_eval{ @a }  #=> 1
  #   o2.instance_eval{ @b }  #=> 2
  #   o2.instance_eval{ @c }  #=> 3
  #   o2.instance_eval{ @d }  #=> 4
  #
  # See also #assign_with.
  #
  def assign_from(obj, *fields)
    force = false
    case fields.last when true, false, nil
      force = fields.pop
    end

    unless fields.empty?
      fields.each do |k|
        var = k.to_s
        var = var.slice(0,1) == '@' ? var : "@#{var}"
        if obj.instance_variables.include?(var)
          self.instance_variable_set( var, obj.instance_variable_get(var) )
        end
      end
    else
      if force
        fields = obj.instance_variables
      else
        fields = instance_variables | obj.instance_variables
      end
      fields.each do |var|
        instance_variable_set( var, obj.instance_variable_get(var) )
      end
    end

    return self
  end

end



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

  require 'test/unit'

  class TCKernel < Test::Unit::TestCase

    def test_assign_from
      o = Object.new
      o.instance_eval{ @z=0; @a=1; @b=2 } #; @@a=3 }
      assign_from( o, "z", "@a", "@b" ) #, "@@a" )
      assert_equal( 1, @a )
      assert_equal( 2, @b )
      #assert_equal( 3, @@a )
    end

  end

=end
