ruby_deep_clone 0.2.0

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.
@@ -0,0 +1,27 @@
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.2.0'
8
+ s.date = '2013-04-03'
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"]
14
+ s.email = ['balmma@sysinf.ch', 'me@andremedeiros.info']
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
@@ -0,0 +1,79 @@
1
+ #include "deep_clone.h"
2
+
3
+ void Init_deep_clone()
4
+ {
5
+ DeepClone = rb_define_module("DeepClone");
6
+ rb_define_module_function(DeepClone, "clone", deep_clone, 1);
7
+ }
8
+
9
+ static int clone_variable(st_data_t key, st_data_t index, struct dump_call_arg *arg)
10
+ {
11
+ VALUE val = ROBJECT_IVPTR(arg->src)[(long)index];
12
+ rb_ivar_set(arg->obj, key, clone_object(val,arg->tracker));
13
+ return ST_CONTINUE;
14
+ }
15
+
16
+ static int hash_each(VALUE key, VALUE value, struct dump_call_arg *arg)
17
+ {
18
+ rb_hash_aset(arg->obj,clone_object(key,arg->tracker),clone_object(value,arg->tracker));
19
+ return ST_CONTINUE;
20
+ }
21
+
22
+ static VALUE clone_object(VALUE object, VALUE tracker)
23
+ {
24
+ if(rb_special_const_p(object))
25
+ return object;
26
+
27
+ VALUE new_obj;
28
+ VALUE id = rb_obj_id(object);
29
+
30
+ if(st_lookup(RHASH_TBL(tracker), id, 0)) {
31
+ new_obj = rb_hash_aref(tracker,id);
32
+ } else {
33
+ switch (BUILTIN_TYPE(object)) {
34
+ case T_ARRAY:
35
+ new_obj = rb_ary_new2(RARRAY_LEN(object));
36
+ long len = RARRAY_LEN(object);
37
+ rb_hash_aset(tracker,id,new_obj);
38
+ VALUE *ptr = RARRAY_PTR(object);
39
+ while (len--) {
40
+ rb_ary_push(new_obj,clone_object(*ptr,tracker));
41
+ ptr++;
42
+ }
43
+ break;
44
+ case T_HASH:
45
+ new_obj = rb_hash_new();
46
+ rb_hash_aset(tracker,id,new_obj);
47
+ struct dump_call_arg arg = {new_obj,tracker, object};
48
+ rb_hash_foreach(object, hash_each, (st_data_t)&arg);
49
+ break;
50
+ case T_STRING:
51
+ case T_DATA:
52
+ new_obj = rb_obj_clone(object);
53
+ rb_hash_aset(tracker,id,new_obj);
54
+ break;
55
+ case T_CLASS:
56
+ case T_MODULE:
57
+ case T_REGEXP:
58
+ new_obj = object;
59
+ rb_hash_aset(tracker,id,new_obj);
60
+ break;
61
+ default:
62
+ new_obj = rb_obj_clone(object);
63
+ rb_hash_aset(tracker,id,new_obj);
64
+ st_table *tbl = ROBJECT_IV_INDEX_TBL(object);
65
+ if(tbl) {
66
+ struct dump_call_arg arg = {new_obj,tracker, object};
67
+ TABLE_FOREACH(tbl, clone_variable, (st_data_t)&arg);
68
+ }
69
+ break;
70
+ }
71
+ }
72
+ return new_obj;
73
+ }
74
+
75
+ VALUE deep_clone(int argc,VALUE argv)
76
+ {
77
+ VALUE tracker = rb_hash_new();
78
+ return clone_object(argv,tracker);
79
+ }
@@ -0,0 +1,49 @@
1
+ #ifndef DEEP_CLONE_H
2
+ #define DEEP_CLONE_H
3
+
4
+ #include "ruby.h"
5
+ #include "ruby/st.h"
6
+
7
+ struct dump_call_arg {
8
+ VALUE obj;
9
+ VALUE tracker;
10
+ VALUE src;
11
+ };
12
+
13
+ #ifdef SA_EMPTY
14
+
15
+ // Gotta do this because of 1.9.3's falcon patch
16
+ struct rb_classext_struct {
17
+ sa_table m_tbl;
18
+ sa_table iv_tbl;
19
+ sa_table const_tbl;
20
+ sa_table iv_index_tbl;
21
+ };
22
+
23
+ #define TABLE_FOREACH sa_foreach
24
+ #define RCLASS_EXT(c) (RCLASS(c)->ptr)
25
+ #define RCLASS_IV_INDEX_TBL(c) (&RCLASS_EXT(c)->iv_index_tbl)
26
+
27
+ #else
28
+
29
+ // Make it work with vanilla ruby (including 2.0)
30
+ #ifndef TABLE_FOREACH
31
+ #define TABLE_FOREACH st_foreach
32
+ #endif
33
+
34
+ #ifndef RCLASS_IV_INDEX_TBL
35
+ #define RCLASS_IV_INDEX_TBL(c) (RCLASS(c)->iv_index_tbl)
36
+ #endif
37
+
38
+ #endif
39
+
40
+ VALUE DeepClone = Qnil;
41
+
42
+ void Init_deep_clone();
43
+ static int clone_variable(st_data_t key, st_data_t index, struct dump_call_arg *arg);
44
+ static int hash_each(VALUE key, VALUE value, struct dump_call_arg *arg);
45
+ static VALUE clone_object(VALUE object, VALUE tracker);
46
+
47
+ VALUE deep_clone(int argc,VALUE argv);
48
+
49
+ #endif
@@ -0,0 +1,7 @@
1
+ require 'mkmf'
2
+
3
+ extension_name = 'deep_clone'
4
+
5
+ dir_config(extension_name)
6
+
7
+ create_makefile(extension_name)
data/lib/deep_clone.rb ADDED
@@ -0,0 +1 @@
1
+ require "deep_clone/deep_clone"
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_deep_clone
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matthias Balmer
9
+ - Andre Medeiros
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-04-03 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 2.13.0
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: 2.13.0
31
+ - !ruby/object:Gem::Dependency
32
+ name: rake-compiler
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 0.8.3
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 0.8.3
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 10.0.4
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 10.0.4
63
+ description: Native implementation to create deep clones of Ruby objects
64
+ email:
65
+ - balmma@sysinf.ch
66
+ - me@andremedeiros.info
67
+ executables: []
68
+ extensions:
69
+ - ext/deep_clone/extconf.rb
70
+ extra_rdoc_files: []
71
+ files:
72
+ - deep_clone.gemspec
73
+ - lib/deep_clone.rb
74
+ - ext/deep_clone/deep_clone.c
75
+ - ext/deep_clone/deep_clone.h
76
+ - ext/deep_clone/extconf.rb
77
+ homepage: https://github.com/balmma/ruby-deepclone
78
+ licenses: []
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - ext
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 1.8.24
99
+ signing_key:
100
+ specification_version: 2
101
+ summary: Ruby native deep clone
102
+ test_files: []