From 895e9b0acd986cf3dba7df60fb00c5ca3607c844 Mon Sep 17 00:00:00 2001 From: jeg2 Date: Sun, 24 Nov 2013 00:44:41 +0000 Subject: * lib/csv.rb: Optimize header hashes by freezing string keys. [ruby-core:58510] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43825 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ lib/csv.rb | 2 ++ test/csv/test_interface.rb | 19 +++++++++++++++++++ test/csv/test_row.rb | 7 ++++++- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 30ee96bae3..9477f5c266 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sun Nov 24 09:37:20 2013 Andrew Vit + + * lib/csv.rb: Optimize header hashes by freezing string keys. + [ruby-core:58510] + Sun Nov 24 09:18:06 2013 Aman Gupta * ext/objspace/objspace_dump.c (dump_object): Use PRIuSIZE to print diff --git a/lib/csv.rb b/lib/csv.rb index d66b84922a..a4d8e3d0a8 100644 --- a/lib/csv.rb +++ b/lib/csv.rb @@ -235,6 +235,7 @@ class CSV # def initialize(headers, fields, header_row = false) @header_row = header_row + headers.each { |h| h.freeze if h.is_a? String } # handle extra headers or fields @row = if headers.size > fields.size @@ -2208,6 +2209,7 @@ class CSV # prepare converted and unconverted copies row = @headers if row.nil? @headers = convert_fields(@headers, true) + @headers.each { |h| h.freeze if h.is_a? String } if @return_headers # return headers return self.class::Row.new(@headers, row, true) diff --git a/test/csv/test_interface.rb b/test/csv/test_interface.rb index ad310fae49..22907d2dd0 100755 --- a/test/csv/test_interface.rb +++ b/test/csv/test_interface.rb @@ -198,6 +198,25 @@ class TestCSV::Interface < TestCSV end end + def test_write_hash_with_string_keys + File.unlink(@path) + + lines = [{a: 1, b: 2, c: 3}, {a: 4, b: 5, c: 6}] + CSV.open( @path, "wb", headers: true ) do |csv| + csv << lines.first.keys + lines.each { |line| csv << line } + end + CSV.open( @path, "rb", headers: true ) do |csv| + csv.each do |line| + csv.headers.each_with_index do |header, h| + keys = line.to_hash.keys + assert_instance_of(String, keys[h]) + assert_same(header, keys[h]) + end + end + end + end + def test_write_hash_with_headers_array File.unlink(@path) diff --git a/test/csv/test_row.rb b/test/csv/test_row.rb index 697c7d56c8..a097fc7200 100755 --- a/test/csv/test_row.rb +++ b/test/csv/test_row.rb @@ -297,7 +297,12 @@ class TestCSV::Row < TestCSV end def test_to_hash - assert_equal({"A" => nil, "B" => 2, "C" => 3}, @row.to_hash) + hash = @row.to_hash + assert_equal({"A" => nil, "B" => 2, "C" => 3}, hash) + hash.keys.each_with_index do |string_key, h| + assert_predicate(string_key, :frozen?) + assert_same(string_key, @row.headers[h]) + end end def test_to_csv -- cgit v1.2.3