mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* hash.c, object.c, struct.c, lib/ostruct.rb: add to_h methods.
[Feature #6276] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35452 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									b05c95d93f
								
							
						
					
					
						commit
						770ddcdfe0
					
				
					 10 changed files with 156 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,8 @@
 | 
			
		|||
Tue Apr 24 12:46:50 2012  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>
 | 
			
		||||
 | 
			
		||||
	* hash.c, object.c, struct.c, lib/ostruct.rb: add to_h methods.
 | 
			
		||||
	  [Feature #6276]
 | 
			
		||||
 | 
			
		||||
Tue Apr 24 10:54:34 2012  NAKAMURA Usaku  <usa@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* test/drb/drbtest.rb ({DRbCore,DRbAry}#teardown}: cannot pass SIGTERM
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										19
									
								
								NEWS
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								NEWS
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -21,7 +21,13 @@ with all sufficient information, see the ChangeLog file.
 | 
			
		|||
    * added method:
 | 
			
		||||
      * added Enumerable#lazy method for lazy enumeration.
 | 
			
		||||
 | 
			
		||||
  * ENV
 | 
			
		||||
    * aliased method:
 | 
			
		||||
      * ENV.to_h is a new alias for ENV.to_hash
 | 
			
		||||
 | 
			
		||||
  * Hash
 | 
			
		||||
    * added method:
 | 
			
		||||
      * added Hash#to_h as explicit conversion method, like Array#to_a.
 | 
			
		||||
    * extended method:
 | 
			
		||||
      * Hash#default_proc= can be passed nil to clear the default proc.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -41,11 +47,20 @@ with all sufficient information, see the ChangeLog file.
 | 
			
		|||
      * added LoadError#path method to return the file name that could not be
 | 
			
		||||
        loaded.
 | 
			
		||||
 | 
			
		||||
  * NilClass
 | 
			
		||||
    * added method:
 | 
			
		||||
      * added nil.to_h which returns {}
 | 
			
		||||
 | 
			
		||||
  * Signal
 | 
			
		||||
    * incompatible changes:
 | 
			
		||||
      * Signal.trap raises ArgumentError when :SEGV, :BUS, :ILL, :FPE, :VTALRM
 | 
			
		||||
        are specified.
 | 
			
		||||
 | 
			
		||||
  * Struct
 | 
			
		||||
    * added method:
 | 
			
		||||
      * added Struct#to_h returning values with keys corresponding to the
 | 
			
		||||
        instance variable names.
 | 
			
		||||
 | 
			
		||||
  * Time
 | 
			
		||||
    * change return value:
 | 
			
		||||
      * Time#to_s returned encoding defaults to US-ASCII but automatically
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +78,10 @@ with all sufficient information, see the ChangeLog file.
 | 
			
		|||
    * Net::IMAP.default_ssl_port
 | 
			
		||||
    * Net::IMAP.default_imaps_port
 | 
			
		||||
 | 
			
		||||
* ostruct
 | 
			
		||||
  * new methods:
 | 
			
		||||
    * OpenStruct#to_h converts the struct to a hash.
 | 
			
		||||
 | 
			
		||||
* pathname
 | 
			
		||||
  * extended method:
 | 
			
		||||
    * Pathname#find returns an enumerator if no block is given.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										29
									
								
								hash.c
									
										
									
									
									
								
							
							
						
						
									
										29
									
								
								hash.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1452,6 +1452,30 @@ rb_hash_to_hash(VALUE hash)
 | 
			
		|||
    return hash;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  call-seq:
 | 
			
		||||
 *     hsh.to_h     -> hsh or new_hash
 | 
			
		||||
 *
 | 
			
		||||
 *  Returns +self+. If called on a subclass of Hash, converts
 | 
			
		||||
 *  the receiver to a Hash object.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
rb_hash_to_h(VALUE hash)
 | 
			
		||||
{
 | 
			
		||||
    if (rb_obj_class(hash) != rb_cHash) {
 | 
			
		||||
	VALUE ret = rb_hash_new();
 | 
			
		||||
	if (!RHASH_EMPTY_P(hash))
 | 
			
		||||
	    RHASH(ret)->ntbl = st_copy(RHASH(hash)->ntbl);
 | 
			
		||||
	if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
 | 
			
		||||
	    FL_SET(ret, HASH_PROC_DEFAULT);
 | 
			
		||||
	}
 | 
			
		||||
	RHASH_IFNONE(ret) = RHASH_IFNONE(hash);
 | 
			
		||||
	return ret;
 | 
			
		||||
    }
 | 
			
		||||
    return hash;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
keys_i(VALUE key, VALUE value, VALUE ary)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -3054,7 +3078,8 @@ env_index(VALUE dmy, VALUE value)
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
 * call-seq:
 | 
			
		||||
 *   ENV.to_hash -> Hash
 | 
			
		||||
 *   ENV.to_hash -> hash
 | 
			
		||||
 *   ENV.to_h    -> hash
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a hash with a copy of the environment variables.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -3333,6 +3358,7 @@ Init_Hash(void)
 | 
			
		|||
    rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0);
 | 
			
		||||
 | 
			
		||||
    rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0);
 | 
			
		||||
    rb_define_method(rb_cHash,"to_h", rb_hash_to_h, 0);
 | 
			
		||||
    rb_define_method(rb_cHash,"to_a", rb_hash_to_a, 0);
 | 
			
		||||
    rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);
 | 
			
		||||
    rb_define_alias(rb_cHash, "to_s", "inspect");
 | 
			
		||||
| 
						 | 
				
			
			@ -3443,6 +3469,7 @@ Init_Hash(void)
 | 
			
		|||
    rb_define_singleton_method(envtbl,"key?", env_has_key, 1);
 | 
			
		||||
    rb_define_singleton_method(envtbl,"value?", env_has_value, 1);
 | 
			
		||||
    rb_define_singleton_method(envtbl,"to_hash", env_to_hash, 0);
 | 
			
		||||
    rb_define_singleton_method(envtbl,"to_h", env_to_hash, 0);
 | 
			
		||||
    rb_define_singleton_method(envtbl,"assoc", env_assoc, 1);
 | 
			
		||||
    rb_define_singleton_method(envtbl,"rassoc", env_rassoc, 1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,6 +100,19 @@ class OpenStruct
 | 
			
		|||
    @table.each_key{|key| new_ostruct_member(key)}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Converts the OpenStruct to a hash with keys representing
 | 
			
		||||
  # each attribute (as symbols) and their corresponding values
 | 
			
		||||
  # Example:
 | 
			
		||||
  #
 | 
			
		||||
  #   require 'ostruct'
 | 
			
		||||
  #   data = OpenStruct.new("country" => "Australia", :population => 20_000_000)
 | 
			
		||||
  #   data.to_h   # => {:country => "Australia", :population => 20000000 }
 | 
			
		||||
  #
 | 
			
		||||
  def to_h
 | 
			
		||||
    @table.dup
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Provides marshalling support for use by the Marshal library. Returning the
 | 
			
		||||
  # underlying Hash table that contains the functions defined as the keys and
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								object.c
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								object.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1057,6 +1057,23 @@ nil_to_a(VALUE obj)
 | 
			
		|||
    return rb_ary_new2(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Document-method: to_h
 | 
			
		||||
 *
 | 
			
		||||
 *  call-seq:
 | 
			
		||||
 *     nil.to_h    -> {}
 | 
			
		||||
 *
 | 
			
		||||
 *  Always returns an empty hash.
 | 
			
		||||
 *
 | 
			
		||||
 *     nil.to_h   #=> {}
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
nil_to_h(VALUE obj)
 | 
			
		||||
{
 | 
			
		||||
    return rb_hash_new();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  call-seq:
 | 
			
		||||
 *    nil.inspect  -> "nil"
 | 
			
		||||
| 
						 | 
				
			
			@ -2896,6 +2913,7 @@ Init_Object(void)
 | 
			
		|||
    rb_define_method(rb_cNilClass, "to_f", nil_to_f, 0);
 | 
			
		||||
    rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0);
 | 
			
		||||
    rb_define_method(rb_cNilClass, "to_a", nil_to_a, 0);
 | 
			
		||||
    rb_define_method(rb_cNilClass, "to_h", nil_to_h, 0);
 | 
			
		||||
    rb_define_method(rb_cNilClass, "inspect", nil_inspect, 0);
 | 
			
		||||
    rb_define_method(rb_cNilClass, "&", false_and, 1);
 | 
			
		||||
    rb_define_method(rb_cNilClass, "|", false_or, 1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										26
									
								
								struct.c
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								struct.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -586,6 +586,31 @@ rb_struct_to_a(VALUE s)
 | 
			
		|||
    return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_PTR(s));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  call-seq:
 | 
			
		||||
 *     struct.to_h     -> hash
 | 
			
		||||
 *
 | 
			
		||||
 *  Returns the values for this instance as a hash with keys
 | 
			
		||||
 *  corresponding to the instance variable name.
 | 
			
		||||
 *
 | 
			
		||||
 *     Customer = Struct.new(:name, :address, :zip)
 | 
			
		||||
 *     joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
 | 
			
		||||
 *     joe.to_h[:address]   #=> "123 Maple, Anytown NC"
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
rb_struct_to_h(VALUE s)
 | 
			
		||||
{
 | 
			
		||||
    VALUE h = rb_hash_new();
 | 
			
		||||
    VALUE members = rb_struct_members(s);
 | 
			
		||||
    long i;
 | 
			
		||||
 | 
			
		||||
    for (i=0; i<RSTRUCT_LEN(s); i++) {
 | 
			
		||||
	rb_hash_aset(h, rb_ary_entry(members, i), RSTRUCT_PTR(s)[i]);
 | 
			
		||||
    }
 | 
			
		||||
    return h;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* :nodoc: */
 | 
			
		||||
VALUE
 | 
			
		||||
rb_struct_init_copy(VALUE copy, VALUE s)
 | 
			
		||||
| 
						 | 
				
			
			@ -961,6 +986,7 @@ Init_Struct(void)
 | 
			
		|||
    rb_define_method(rb_cStruct, "inspect", rb_struct_inspect, 0);
 | 
			
		||||
    rb_define_alias(rb_cStruct,  "to_s", "inspect");
 | 
			
		||||
    rb_define_method(rb_cStruct, "to_a", rb_struct_to_a, 0);
 | 
			
		||||
    rb_define_method(rb_cStruct, "to_h", rb_struct_to_h, 0);
 | 
			
		||||
    rb_define_method(rb_cStruct, "values", rb_struct_to_a, 0);
 | 
			
		||||
    rb_define_method(rb_cStruct, "size", rb_struct_size, 0);
 | 
			
		||||
    rb_define_method(rb_cStruct, "length", rb_struct_size, 0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,4 +73,16 @@ class TC_OpenStruct < Test::Unit::TestCase
 | 
			
		|||
    assert_raise(NoMethodError) { o[:foo] }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_to_h
 | 
			
		||||
    h = {name: "John Smith", age: 70, pension: 300}
 | 
			
		||||
    os = OpenStruct.new(h)
 | 
			
		||||
    to_h = os.to_h
 | 
			
		||||
    assert_equal(h, to_h)
 | 
			
		||||
 | 
			
		||||
    to_h[:age] = 71
 | 
			
		||||
    assert_equal(70, os.age)
 | 
			
		||||
    assert_equal(70, h[:age])
 | 
			
		||||
 | 
			
		||||
    assert_equal(h, OpenStruct.new("name" => "John Smith", "age" => 70, pension: 300).to_h)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -327,6 +327,10 @@ class TestEnv < Test::Unit::TestCase
 | 
			
		|||
    assert_equal(h, ENV.to_hash)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_to_h
 | 
			
		||||
    assert_equal(ENV.to_hash, ENV.to_h)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_reject
 | 
			
		||||
    h1 = {}
 | 
			
		||||
    ENV.each_pair {|k, v| h1[k] = v }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ class TestHash < Test::Unit::TestCase
 | 
			
		|||
  # From rubicon
 | 
			
		||||
 | 
			
		||||
  def setup
 | 
			
		||||
    @cls = Hash
 | 
			
		||||
    @cls ||= Hash
 | 
			
		||||
    @h = @cls[
 | 
			
		||||
      1 => 'one', 2 => 'two', 3 => 'three',
 | 
			
		||||
      self => 'self', true => 'true', nil => 'nil',
 | 
			
		||||
| 
						 | 
				
			
			@ -631,6 +631,20 @@ class TestHash < Test::Unit::TestCase
 | 
			
		|||
  def test_to_hash
 | 
			
		||||
    h = @h.to_hash
 | 
			
		||||
    assert_equal(@h, h)
 | 
			
		||||
    assert_instance_of(@cls, h)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_to_h
 | 
			
		||||
    h = @h.to_h
 | 
			
		||||
    assert_equal(@h, h)
 | 
			
		||||
    assert_instance_of(Hash, h)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_nil_to_h
 | 
			
		||||
    h = nil.to_h
 | 
			
		||||
    assert_equal({}, h)
 | 
			
		||||
    assert_nil(h.default)
 | 
			
		||||
    assert_nil(h.default_proc)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_to_s
 | 
			
		||||
| 
						 | 
				
			
			@ -932,4 +946,14 @@ class TestHash < Test::Unit::TestCase
 | 
			
		|||
      assert_not_equal(h.hash, h.invert.hash, feature4262)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class TestSubHash < TestHash
 | 
			
		||||
    class SubHash < Hash
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def setup
 | 
			
		||||
      @cls = SubHash
 | 
			
		||||
      super
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -263,4 +263,10 @@ class TestStruct < Test::Unit::TestCase
 | 
			
		|||
    end
 | 
			
		||||
    assert_equal("Insecure: can't modify #{st}::S", error.message, bug5036)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_to_h
 | 
			
		||||
    klass = Struct.new(:a, :b, :c, :d, :e, :f)
 | 
			
		||||
    o = klass.new(1, 2, 3, 4, 5, 6)
 | 
			
		||||
    assert_equal({a:1, b:2, c:3, d:4, e:5, f:6}, o.to_h)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue