ruby_deep_clone 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +13 -5
- data/ext/deep_clone/deep_clone.c +87 -42
- data/ext/deep_clone/extconf.rb +1 -5
- data/lib/deep_clone.rb +1 -1
- metadata +20 -22
- data/deep_clone.gemspec +0 -27
- data/ext/deep_clone/deep_clone.h +0 -67
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YmEwZmJkNDViNTAxMWUzMjFlZWVjOWMxNGMwZTE0MWI3ZDU4ZTU3ZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MjU3ZjYxNjBiMWVkZThjZDE3NzU1NTYzYWZiNjY0ZGRlNjg0NDAxZA==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YWIzODVlZjdlMWUwYmNkMDc1ZGIyMTY0YmJjMjBlNjg3NDQ2NzdiNjYyN2Uz
|
10
|
+
MDE1OTQyYWQ0YmQ5YzQxN2FhMTcyOWI5NTc1OGFhMDlkZTI4MTgxNGUyMGEx
|
11
|
+
Zjk5OTUxNDQ5OTk4OTNhMzk4NDA1YmE5YzBjNDVjNjZiZWFiZGM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Nzg2OWE1YWRkYTZjYzM1NGVjY2E4NGZiMjI1MGIwNDQ3MzM4YTE3OTZhMTkx
|
14
|
+
YTY2YmE0ZGM0ODNhY2MxNzg2YTk5MTI0NmFhNGI2ZWI1NmMwZTc4NDJiNDlj
|
15
|
+
NGQ4OWFkYWRhNGNmNWQxOTJmMmM4ZTc0MzllOGYzMjI4M2Q5M2Q=
|
data/ext/deep_clone/deep_clone.c
CHANGED
@@ -1,25 +1,28 @@
|
|
1
1
|
#include "deep_clone.h"
|
2
|
+
|
2
3
|
int ident = 0;
|
3
4
|
|
4
|
-
void
|
5
|
-
|
6
|
-
#
|
7
|
-
int i;
|
8
|
-
|
5
|
+
void inspect(VALUE val)
|
6
|
+
{
|
7
|
+
#if DC_DEBUG
|
8
|
+
for(int i = 0; i <= ident - 1; ++i)
|
9
|
+
{
|
9
10
|
printf("\t");
|
10
11
|
}
|
12
|
+
|
11
13
|
printf("BEFORE %d ", BUILTIN_TYPE(val));
|
12
14
|
printf("INSPECT: %s\n", RSTRING_PTR(rb_any_to_s(val)));
|
13
15
|
#endif
|
14
16
|
}
|
15
17
|
|
16
|
-
void
|
17
|
-
|
18
|
-
#
|
19
|
-
int i;
|
20
|
-
|
18
|
+
void inspect_kvp(ID key, VALUE val)
|
19
|
+
{
|
20
|
+
#if DC_DEBUG
|
21
|
+
for(int i = 0; i <= ident - 1; ++i)
|
22
|
+
{
|
21
23
|
printf("\t");
|
22
24
|
}
|
25
|
+
|
23
26
|
printf("BEFORE %s %d %d", RSTRING_PTR(rb_inspect(ID2SYM(key))), val);
|
24
27
|
printf("VALUE: %s => %s\n", RSTRING_PTR(rb_inspect(ID2SYM(key))), RSTRING_PTR(rb_any_to_s(val)));
|
25
28
|
#endif
|
@@ -33,60 +36,88 @@ void Init_deep_clone()
|
|
33
36
|
|
34
37
|
static int clone_variable(st_data_t key, st_data_t index, struct dump_call_arg *arg)
|
35
38
|
{
|
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
|
+
|
38
42
|
// Check if value is nil. For some reason, if you "force" an instance value
|
39
43
|
// to nil, the ||= operator won't work.
|
40
|
-
if(!NIL_P(val))
|
44
|
+
if(!NIL_P(val))
|
45
|
+
{
|
46
|
+
rb_ivar_set(arg->obj, (ID) key, clone_object(val, arg->tracker));
|
47
|
+
}
|
48
|
+
|
41
49
|
return ST_CONTINUE;
|
42
50
|
}
|
43
51
|
|
44
52
|
static int hash_each(VALUE key, VALUE value, struct dump_call_arg *arg)
|
45
53
|
{
|
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
|
+
|
47
56
|
return ST_CONTINUE;
|
48
57
|
}
|
49
58
|
|
50
59
|
static VALUE clone_object(VALUE object, VALUE tracker)
|
51
60
|
{
|
52
61
|
if(rb_special_const_p(object))
|
62
|
+
{
|
53
63
|
return object;
|
64
|
+
}
|
54
65
|
|
55
66
|
inspect(object);
|
56
67
|
|
57
68
|
VALUE new_obj;
|
58
69
|
VALUE id = rb_obj_id(object);
|
59
70
|
|
60
|
-
if(st_lookup(RHASH_TBL(tracker), id, 0))
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
+
{
|
65
81
|
case T_ARRAY:
|
66
82
|
new_obj = rb_ary_new2(RARRAY_LEN(object));
|
67
83
|
long len = RARRAY_LEN(object);
|
68
|
-
if(len == 0)
|
69
|
-
|
84
|
+
if(len == 0)
|
85
|
+
{
|
86
|
+
break;
|
87
|
+
}
|
88
|
+
|
89
|
+
rb_hash_aset(tracker, id, new_obj);
|
90
|
+
|
70
91
|
VALUE *ptr = RARRAY_PTR(object);
|
71
|
-
while
|
72
|
-
|
73
|
-
ptr
|
92
|
+
while(len--)
|
93
|
+
{
|
94
|
+
rb_ary_push(new_obj, clone_object(*ptr, tracker));
|
95
|
+
|
96
|
+
++ptr;
|
74
97
|
}
|
98
|
+
|
75
99
|
break;
|
76
100
|
case T_HASH:
|
77
101
|
new_obj = rb_hash_new();
|
78
|
-
rb_hash_aset(tracker,id,new_obj);
|
79
|
-
|
80
|
-
|
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
|
+
|
81
107
|
break;
|
82
108
|
case T_STRING:
|
83
109
|
case T_DATA:
|
84
|
-
if(rb_obj_is_kind_of(object,rb_cNumeric))
|
110
|
+
if(rb_obj_is_kind_of(object, rb_cNumeric))
|
111
|
+
{
|
85
112
|
new_obj = object;
|
86
|
-
}
|
113
|
+
}
|
114
|
+
else
|
115
|
+
{
|
87
116
|
new_obj = rb_obj_clone(object);
|
88
117
|
}
|
89
|
-
|
118
|
+
|
119
|
+
rb_hash_aset(tracker, id, new_obj);
|
120
|
+
|
90
121
|
break;
|
91
122
|
case T_CLASS:
|
92
123
|
case T_MODULE:
|
@@ -100,37 +131,51 @@ static VALUE clone_object(VALUE object, VALUE tracker)
|
|
100
131
|
case T_STRUCT:
|
101
132
|
case T_FILE:
|
102
133
|
new_obj = object;
|
103
|
-
|
134
|
+
|
135
|
+
rb_hash_aset(tracker, id, new_obj);
|
136
|
+
|
104
137
|
break;
|
105
138
|
default:
|
106
|
-
if(rb_obj_is_kind_of(object,rb_cNumeric))
|
139
|
+
if(rb_obj_is_kind_of(object, rb_cNumeric))
|
140
|
+
{
|
107
141
|
new_obj = object;
|
108
|
-
rb_hash_aset(tracker,id,new_obj);
|
109
|
-
}
|
142
|
+
rb_hash_aset(tracker, id, new_obj);
|
143
|
+
}
|
144
|
+
else
|
145
|
+
{
|
110
146
|
new_obj = rb_obj_clone(object);
|
111
147
|
|
112
148
|
// Unfreeze the new object
|
113
149
|
OBJ_UNFREEZE(new_obj);
|
114
150
|
|
115
|
-
rb_hash_aset(tracker,id,new_obj);
|
151
|
+
rb_hash_aset(tracker, id, new_obj);
|
152
|
+
|
116
153
|
st_table *tbl = DC_ROBJECT_IV_INDEX_TBL(object);
|
117
154
|
|
118
|
-
if(tbl)
|
119
|
-
|
120
|
-
|
155
|
+
if(tbl)
|
156
|
+
{
|
157
|
+
struct dump_call_arg arg = { new_obj, tracker, object };
|
158
|
+
TABLE_FOREACH(tbl, clone_variable, (st_data_t) &arg);
|
121
159
|
}
|
122
160
|
|
123
|
-
if(OBJ_FROZEN(object))
|
161
|
+
if(OBJ_FROZEN(object))
|
162
|
+
{
|
163
|
+
OBJ_FREEZE(new_obj);
|
164
|
+
}
|
124
165
|
}
|
166
|
+
|
125
167
|
break;
|
126
168
|
}
|
127
|
-
|
169
|
+
|
170
|
+
--ident;
|
128
171
|
}
|
172
|
+
|
129
173
|
return new_obj;
|
130
174
|
}
|
131
175
|
|
132
|
-
VALUE deep_clone(int argc,VALUE argv)
|
176
|
+
VALUE deep_clone(int argc, VALUE argv)
|
133
177
|
{
|
134
178
|
VALUE tracker = rb_hash_new();
|
135
|
-
|
179
|
+
|
180
|
+
return clone_object(argv, tracker);
|
136
181
|
}
|
data/ext/deep_clone/extconf.rb
CHANGED
data/lib/deep_clone.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'deep_clone/deep_clone'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_deep_clone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthias Balmer
|
@@ -10,50 +10,50 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2016-03-24 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: rake
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: '10.5'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
|
-
- -
|
26
|
+
- - ~>
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version:
|
28
|
+
version: '10.5'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: rake-compiler
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
|
-
- -
|
33
|
+
- - ~>
|
34
34
|
- !ruby/object:Gem::Version
|
35
35
|
version: 0.8.3
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
|
-
- -
|
40
|
+
- - ~>
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: 0.8.3
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
|
-
name:
|
44
|
+
name: rspec
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- -
|
47
|
+
- - ~>
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: '2.99'
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
|
-
- -
|
54
|
+
- - ~>
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
56
|
+
version: '2.99'
|
57
57
|
description: Native implementation to create deep clones of Ruby objects
|
58
58
|
email:
|
59
59
|
- balmma@sysinf.ch
|
@@ -64,33 +64,31 @@ extensions:
|
|
64
64
|
- ext/deep_clone/extconf.rb
|
65
65
|
extra_rdoc_files: []
|
66
66
|
files:
|
67
|
-
- deep_clone.gemspec
|
68
67
|
- ext/deep_clone/deep_clone.c
|
69
|
-
- ext/deep_clone/deep_clone.h
|
70
68
|
- ext/deep_clone/extconf.rb
|
71
69
|
- lib/deep_clone.rb
|
72
70
|
homepage: https://github.com/balmma/ruby-deepclone
|
73
|
-
licenses:
|
71
|
+
licenses:
|
72
|
+
- MIT
|
74
73
|
metadata: {}
|
75
74
|
post_install_message:
|
76
75
|
rdoc_options: []
|
77
76
|
require_paths:
|
78
|
-
- ext
|
79
77
|
- lib
|
80
78
|
required_ruby_version: !ruby/object:Gem::Requirement
|
81
79
|
requirements:
|
82
|
-
- -
|
80
|
+
- - ! '>='
|
83
81
|
- !ruby/object:Gem::Version
|
84
82
|
version: '0'
|
85
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
84
|
requirements:
|
87
|
-
- -
|
85
|
+
- - ! '>='
|
88
86
|
- !ruby/object:Gem::Version
|
89
87
|
version: '0'
|
90
88
|
requirements: []
|
91
89
|
rubyforge_project:
|
92
|
-
rubygems_version: 2.
|
90
|
+
rubygems_version: 2.4.7
|
93
91
|
signing_key:
|
94
|
-
specification_version:
|
92
|
+
specification_version: 4
|
95
93
|
summary: Ruby native deep clone
|
96
94
|
test_files: []
|
data/deep_clone.gemspec
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
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
|
-
|
6
|
-
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"]
|
14
|
-
s.email = ['balmma@sysinf.ch', 'me@andremedeiros.info', 'hi@antw.io']
|
15
|
-
|
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"]
|
21
|
-
|
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"]
|
23
|
-
|
24
|
-
s.add_development_dependency 'rspec', '~> 2.13.0'
|
25
|
-
s.add_development_dependency 'rake-compiler', '~> 0.8.3'
|
26
|
-
s.add_development_dependency 'rake', '~> 10.0.4'
|
27
|
-
end
|
data/ext/deep_clone/deep_clone.h
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
#ifndef DEEP_CLONE_H
|
2
|
-
#define DEEP_CLONE_H
|
3
|
-
|
4
|
-
#include "ruby.h"
|
5
|
-
#include "ruby/st.h"
|
6
|
-
#include "ruby/version.h"
|
7
|
-
|
8
|
-
struct dump_call_arg {
|
9
|
-
VALUE obj;
|
10
|
-
VALUE tracker;
|
11
|
-
VALUE src;
|
12
|
-
};
|
13
|
-
|
14
|
-
// #define DC_DEBUG 0
|
15
|
-
|
16
|
-
#define OBJ_UNFREEZE(x) FL_UNSET((x), FL_FREEZE)
|
17
|
-
|
18
|
-
#ifdef SA_EMPTY
|
19
|
-
|
20
|
-
// Gotta do this because of 1.9.3's falcon patch
|
21
|
-
struct rb_classext_struct {
|
22
|
-
sa_table m_tbl;
|
23
|
-
sa_table iv_tbl;
|
24
|
-
sa_table const_tbl;
|
25
|
-
sa_table iv_index_tbl;
|
26
|
-
};
|
27
|
-
|
28
|
-
#define TABLE_FOREACH sa_foreach
|
29
|
-
#define DC_RCLASS_EXT(c) (RCLASS(c)->ptr)
|
30
|
-
#define DC_RCLASS_IV_INDEX_TBL(c) (&DC_RCLASS_EXT(c)->iv_index_tbl)
|
31
|
-
|
32
|
-
#else
|
33
|
-
// Make it work with vanilla ruby (including 2.0)
|
34
|
-
#define TABLE_FOREACH st_foreach
|
35
|
-
|
36
|
-
#if RUBY_API_VERSION_CODE >= 20100
|
37
|
-
|
38
|
-
// In Ruby 2.1, iv_index_tbl was moved into internal.h and cannot be accessed
|
39
|
-
// directly. We work around this by defining our own RCLASS helpers (since the
|
40
|
-
// rb_classext_struct returned by RCLASS_EXT is also effectively private).
|
41
|
-
typedef struct dc_iv_tbl_classext_struct {
|
42
|
-
struct st_table *iv_index_tbl;
|
43
|
-
} dc_iv_tbl_classext_t;
|
44
|
-
|
45
|
-
#define DC_RCLASS_EXT(c) ((dc_iv_tbl_classext_t *)RCLASS(c)->ptr)
|
46
|
-
#define DC_RCLASS_IV_INDEX_TBL(c) (DC_RCLASS_EXT(c)->iv_index_tbl)
|
47
|
-
|
48
|
-
#else
|
49
|
-
#define DC_RCLASS_IV_INDEX_TBL(c) (RCLASS(c)->iv_index_tbl)
|
50
|
-
#endif
|
51
|
-
#endif
|
52
|
-
|
53
|
-
#define DC_ROBJECT_IV_INDEX_TBL(o) \
|
54
|
-
((RBASIC(o)->flags & ROBJECT_EMBED) ? \
|
55
|
-
DC_RCLASS_IV_INDEX_TBL(rb_obj_class(o)) : \
|
56
|
-
ROBJECT(o)->as.heap.iv_index_tbl)
|
57
|
-
|
58
|
-
VALUE DeepClone = Qnil;
|
59
|
-
|
60
|
-
void Init_deep_clone();
|
61
|
-
static int clone_variable(st_data_t key, st_data_t index, struct dump_call_arg *arg);
|
62
|
-
static int hash_each(VALUE key, VALUE value, struct dump_call_arg *arg);
|
63
|
-
static VALUE clone_object(VALUE object, VALUE tracker);
|
64
|
-
|
65
|
-
VALUE deep_clone(int argc,VALUE argv);
|
66
|
-
|
67
|
-
#endif
|