Skip to content
This repository was archived by the owner on Feb 1, 2022. It is now read-only.

Commit b530f8a

Browse files
author
Jordan Pickwell
committed
Fix #9
1 parent 8f53981 commit b530f8a

File tree

7 files changed

+177
-112
lines changed

7 files changed

+177
-112
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ tmp
33
Makefile
44
*.o
55
*.bundle
6+
*.gem

Gemfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
source :rubygems
1+
source 'https://rubygems.org'
22

33
gemspec

Gemfile.lock

+16-13
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,32 @@
11
PATH
22
remote: .
33
specs:
4-
ruby_deep_clone (0.3.0)
4+
ruby_deep_clone (0.7.0)
55

66
GEM
7-
remote: http://rubygems.org/
7+
remote: https://rubygems.org/
88
specs:
9-
diff-lcs (1.2.1)
10-
rake (10.0.4)
9+
diff-lcs (1.2.5)
10+
rake (10.5.0)
1111
rake-compiler (0.8.3)
1212
rake
13-
rspec (2.13.0)
14-
rspec-core (~> 2.13.0)
15-
rspec-expectations (~> 2.13.0)
16-
rspec-mocks (~> 2.13.0)
17-
rspec-core (2.13.1)
18-
rspec-expectations (2.13.0)
13+
rspec (2.99.0)
14+
rspec-core (~> 2.99.0)
15+
rspec-expectations (~> 2.99.0)
16+
rspec-mocks (~> 2.99.0)
17+
rspec-core (2.99.2)
18+
rspec-expectations (2.99.2)
1919
diff-lcs (>= 1.1.3, < 2.0)
20-
rspec-mocks (2.13.0)
20+
rspec-mocks (2.99.4)
2121

2222
PLATFORMS
2323
ruby
2424

2525
DEPENDENCIES
26-
rake (~> 10.0.4)
26+
rake (~> 10.0)
2727
rake-compiler (~> 0.8.3)
28-
rspec (~> 2.13.0)
28+
rspec (~> 2.13)
2929
ruby_deep_clone!
30+
31+
BUNDLED WITH
32+
1.11.2

deep_clone.gemspec

+18-19
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
Gem::Specification.new do |s|
2-
s.specification_version = 2 if s.respond_to? :specification_version=
3-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4-
s.rubygems_version = '1.3.5'
5-
62
s.name = 'ruby_deep_clone'
7-
s.version = '0.6.0'
8-
s.date = '2014-01-21'
9-
10-
s.summary = "Ruby native deep clone"
11-
s.description = "Native implementation to create deep clones of Ruby objects"
12-
13-
s.authors = ["Matthias Balmer", "Andre Medeiros", "Anthony Williams"]
3+
s.version = '0.7.0'
4+
s.date = '2016-03-23'
5+
6+
s.summary = 'Ruby native deep clone'
7+
s.description = 'Native implementation to create deep clones of Ruby objects'
8+
9+
s.authors = ['Matthias Balmer', 'Andre Medeiros', 'Anthony Williams']
1410
1511

16-
s.homepage = "https://github.com/balmma/ruby-deepclone"
17-
18-
s.extensions = ["ext/deep_clone/extconf.rb"]
19-
20-
s.require_paths = ["ext", "lib"]
12+
s.homepage = 'https://github.com/balmma/ruby-deepclone'
13+
s.license = 'MIT'
14+
15+
#s.specification_version = 2 if s.respond_to? :specification_version=
16+
#s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
2117

22-
s.files = ["deep_clone.gemspec","lib/deep_clone.rb","ext/deep_clone/deep_clone.c","ext/deep_clone/deep_clone.h","ext/deep_clone/extconf.rb"]
18+
s.files = Dir.glob('ext/**/*.{c,rb}') +
19+
Dir.glob('lib/**/*.rb')
20+
21+
s.extensions << 'ext/deep_clone/extconf.rb'
2322

24-
s.add_development_dependency 'rspec', '~> 2.13.0'
23+
s.add_development_dependency 'rake', '~> 10.5'
2524
s.add_development_dependency 'rake-compiler', '~> 0.8.3'
26-
s.add_development_dependency 'rake', '~> 10.0.4'
25+
s.add_development_dependency 'rspec', '~> 2.99'
2726
end

ext/deep_clone/deep_clone.c

+87-42
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
#include "deep_clone.h"
2+
23
int ident = 0;
34

4-
void
5-
inspect(VALUE val) {
6-
#ifdef DC_DEBUG
7-
int i;
8-
for(i = 0; i <= ident-1; i++) {
5+
void inspect(VALUE val)
6+
{
7+
#if DC_DEBUG
8+
for(int i = 0; i <= ident - 1; ++i)
9+
{
910
printf("\t");
1011
}
12+
1113
printf("BEFORE %d ", BUILTIN_TYPE(val));
1214
printf("INSPECT: %s\n", RSTRING_PTR(rb_any_to_s(val)));
1315
#endif
1416
}
1517

16-
void
17-
inspect_kvp(ID key, VALUE val) {
18-
#ifdef DC_DEBUG
19-
int i;
20-
for(i = 0; i <= ident-1; i++) {
18+
void inspect_kvp(ID key, VALUE val)
19+
{
20+
#if DC_DEBUG
21+
for(int i = 0; i <= ident - 1; ++i)
22+
{
2123
printf("\t");
2224
}
25+
2326
printf("BEFORE %s %d %d", RSTRING_PTR(rb_inspect(ID2SYM(key))), val);
2427
printf("VALUE: %s => %s\n", RSTRING_PTR(rb_inspect(ID2SYM(key))), RSTRING_PTR(rb_any_to_s(val)));
2528
#endif
@@ -33,60 +36,88 @@ void Init_deep_clone()
3336

3437
static int clone_variable(st_data_t key, st_data_t index, struct dump_call_arg *arg)
3538
{
36-
VALUE val = rb_ivar_get(arg->obj, (ID)key);
37-
inspect_kvp((ID)key, val);
39+
VALUE val = rb_ivar_get(arg->obj, (ID) key);
40+
inspect_kvp((ID) key, val);
41+
3842
// Check if value is nil. For some reason, if you "force" an instance value
3943
// to nil, the ||= operator won't work.
40-
if(!NIL_P(val)) rb_ivar_set(arg->obj, (ID)key, clone_object(val,arg->tracker));
44+
if(!NIL_P(val))
45+
{
46+
rb_ivar_set(arg->obj, (ID) key, clone_object(val, arg->tracker));
47+
}
48+
4149
return ST_CONTINUE;
4250
}
4351

4452
static int hash_each(VALUE key, VALUE value, struct dump_call_arg *arg)
4553
{
46-
rb_hash_aset(arg->obj,clone_object(key,arg->tracker),clone_object(value,arg->tracker));
54+
rb_hash_aset(arg->obj, clone_object(key, arg->tracker), clone_object(value, arg->tracker));
55+
4756
return ST_CONTINUE;
4857
}
4958

5059
static VALUE clone_object(VALUE object, VALUE tracker)
5160
{
5261
if(rb_special_const_p(object))
62+
{
5363
return object;
64+
}
5465

5566
inspect(object);
5667

5768
VALUE new_obj;
5869
VALUE id = rb_obj_id(object);
5970

60-
if(st_lookup(RHASH_TBL(tracker), id, 0)) {
61-
new_obj = rb_hash_aref(tracker,id);
62-
} else {
63-
ident++;
64-
switch (BUILTIN_TYPE(object)) {
71+
if(st_lookup(RHASH_TBL(tracker), id, 0))
72+
{
73+
new_obj = rb_hash_aref(tracker, id);
74+
}
75+
else
76+
{
77+
++ident;
78+
79+
switch(BUILTIN_TYPE(object))
80+
{
6581
case T_ARRAY:
6682
new_obj = rb_ary_new2(RARRAY_LEN(object));
6783
long len = RARRAY_LEN(object);
68-
if(len == 0) break;
69-
rb_hash_aset(tracker,id,new_obj);
84+
if(len == 0)
85+
{
86+
break;
87+
}
88+
89+
rb_hash_aset(tracker, id, new_obj);
90+
7091
VALUE *ptr = RARRAY_PTR(object);
71-
while (len--) {
72-
rb_ary_push(new_obj,clone_object(*ptr,tracker));
73-
ptr++;
92+
while(len--)
93+
{
94+
rb_ary_push(new_obj, clone_object(*ptr, tracker));
95+
96+
++ptr;
7497
}
98+
7599
break;
76100
case T_HASH:
77101
new_obj = rb_hash_new();
78-
rb_hash_aset(tracker,id,new_obj);
79-
struct dump_call_arg arg = {new_obj,tracker, object};
80-
rb_hash_foreach(object, hash_each, (st_data_t)&arg);
102+
rb_hash_aset(tracker, id, new_obj);
103+
104+
struct dump_call_arg arg = { new_obj, tracker, object };
105+
rb_hash_foreach(object, hash_each, (st_data_t) &arg);
106+
81107
break;
82108
case T_STRING:
83109
case T_DATA:
84-
if(rb_obj_is_kind_of(object,rb_cNumeric)){
110+
if(rb_obj_is_kind_of(object, rb_cNumeric))
111+
{
85112
new_obj = object;
86-
} else {
113+
}
114+
else
115+
{
87116
new_obj = rb_obj_clone(object);
88117
}
89-
rb_hash_aset(tracker,id,new_obj);
118+
119+
rb_hash_aset(tracker, id, new_obj);
120+
90121
break;
91122
case T_CLASS:
92123
case T_MODULE:
@@ -100,37 +131,51 @@ static VALUE clone_object(VALUE object, VALUE tracker)
100131
case T_STRUCT:
101132
case T_FILE:
102133
new_obj = object;
103-
rb_hash_aset(tracker,id,new_obj);
134+
135+
rb_hash_aset(tracker, id, new_obj);
136+
104137
break;
105138
default:
106-
if(rb_obj_is_kind_of(object,rb_cNumeric)){
139+
if(rb_obj_is_kind_of(object, rb_cNumeric))
140+
{
107141
new_obj = object;
108-
rb_hash_aset(tracker,id,new_obj);
109-
} else {
142+
rb_hash_aset(tracker, id, new_obj);
143+
}
144+
else
145+
{
110146
new_obj = rb_obj_clone(object);
111147

112148
// Unfreeze the new object
113149
OBJ_UNFREEZE(new_obj);
114150

115-
rb_hash_aset(tracker,id,new_obj);
151+
rb_hash_aset(tracker, id, new_obj);
152+
116153
st_table *tbl = DC_ROBJECT_IV_INDEX_TBL(object);
117154

118-
if(tbl) {
119-
struct dump_call_arg arg = {new_obj,tracker, object};
120-
TABLE_FOREACH(tbl, clone_variable, (st_data_t)&arg);
155+
if(tbl)
156+
{
157+
struct dump_call_arg arg = { new_obj, tracker, object };
158+
TABLE_FOREACH(tbl, clone_variable, (st_data_t) &arg);
121159
}
122160

123-
if(OBJ_FROZEN(object)) OBJ_FREEZE(new_obj);
161+
if(OBJ_FROZEN(object))
162+
{
163+
OBJ_FREEZE(new_obj);
164+
}
124165
}
166+
125167
break;
126168
}
127-
ident--;
169+
170+
--ident;
128171
}
172+
129173
return new_obj;
130174
}
131175

132-
VALUE deep_clone(int argc,VALUE argv)
176+
VALUE deep_clone(int argc, VALUE argv)
133177
{
134178
VALUE tracker = rb_hash_new();
135-
return clone_object(argv,tracker);
179+
180+
return clone_object(argv, tracker);
136181
}

0 commit comments

Comments
 (0)