xamplr 1.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.
Files changed (142) hide show
  1. data/CHANGES.txt +13 -0
  2. data/LICENSE +3 -0
  3. data/README.rdoc +26 -0
  4. data/README.rdoc.orig +118 -0
  5. data/Rakefile +85 -0
  6. data/VERSION.yml +4 -0
  7. data/examples/random-people-shared-addresses/Makefile +16 -0
  8. data/examples/random-people-shared-addresses/batch-load-users.rb +83 -0
  9. data/examples/random-people-shared-addresses/find-mentions.rb +47 -0
  10. data/examples/random-people-shared-addresses/find-people-by-address.rb +104 -0
  11. data/examples/random-people-shared-addresses/optimise.rb +16 -0
  12. data/examples/random-people-shared-addresses/people.rb +35 -0
  13. data/examples/random-people-shared-addresses/query.rb +75 -0
  14. data/examples/random-people-shared-addresses/query2.rb +73 -0
  15. data/examples/random-people-shared-addresses/random-names.csv +10000 -0
  16. data/examples/random-people-shared-addresses/settings.rb +3 -0
  17. data/examples/random-people-shared-addresses/what-to-query-on.rb +82 -0
  18. data/examples/random-people-shared-addresses/xampl-gen.rb +36 -0
  19. data/examples/random-people-shared-addresses/xml/people.xml +14 -0
  20. data/examples/random-people/Makefile +16 -0
  21. data/examples/random-people/batch-load-users.rb +61 -0
  22. data/examples/random-people/optimise.rb +16 -0
  23. data/examples/random-people/people.rb +22 -0
  24. data/examples/random-people/query.rb +73 -0
  25. data/examples/random-people/query2.rb +73 -0
  26. data/examples/random-people/random-names.csv +10000 -0
  27. data/examples/random-people/rawtc.rb +91 -0
  28. data/examples/random-people/settings.rb +3 -0
  29. data/examples/random-people/what-to-query-on.rb +80 -0
  30. data/examples/random-people/xampl-gen.rb +36 -0
  31. data/examples/random-people/xml/people.xml +11 -0
  32. data/examples/read-testing/Makefile +10 -0
  33. data/examples/read-testing/load.rb +65 -0
  34. data/examples/read-testing/read.rb +51 -0
  35. data/examples/read-testing/rrr.rb +87 -0
  36. data/examples/read-testing/settings.rb +2 -0
  37. data/examples/read-testing/xampl-gen.rb +36 -0
  38. data/examples/read-testing/xml/text.xml +8 -0
  39. data/examples/tokyo-cabinet-experimental/expt-query.rb +42 -0
  40. data/examples/tokyo-cabinet-experimental/expt-query2.rb +42 -0
  41. data/examples/tokyo-cabinet-experimental/expt-query3.rb +41 -0
  42. data/examples/tokyo-cabinet-experimental/expt-reader.rb +32 -0
  43. data/examples/tokyo-cabinet-experimental/expt.rb +61 -0
  44. data/examples/tokyo-cabinet-experimental/xampl-gen.rb +36 -0
  45. data/examples/tokyo-cabinet-experimental/xml/tcx.xml +6 -0
  46. data/lib/xampl-generator.rb +3 -0
  47. data/lib/xampl.rb +3 -0
  48. data/lib/xamplr-generator.rb +10 -0
  49. data/lib/xamplr.rb +37 -0
  50. data/lib/xamplr/README-POSSIBLE-PROBLEMS +5 -0
  51. data/lib/xamplr/TODO +1 -0
  52. data/lib/xamplr/exceptions.rb +97 -0
  53. data/lib/xamplr/from-xml-orig.rb +350 -0
  54. data/lib/xamplr/from-xml.rb +439 -0
  55. data/lib/xamplr/gen-elements.xml +6230 -0
  56. data/lib/xamplr/gen.elements.xml +108 -0
  57. data/lib/xamplr/generate-elements.rb +15 -0
  58. data/lib/xamplr/generator.rb +5 -0
  59. data/lib/xamplr/graphml-out.rb +470 -0
  60. data/lib/xamplr/handwritten/example.rb +698 -0
  61. data/lib/xamplr/handwritten/hand-example.rb +533 -0
  62. data/lib/xamplr/handwritten/test-handwritten.rb +873 -0
  63. data/lib/xamplr/indexed-array.rb +115 -0
  64. data/lib/xamplr/mixins.rb +397 -0
  65. data/lib/xamplr/my.gen.elements.xml +461 -0
  66. data/lib/xamplr/notifications.rb +57 -0
  67. data/lib/xamplr/obsolete/fsdb.rb +62 -0
  68. data/lib/xamplr/persist-to-xml.rb +249 -0
  69. data/lib/xamplr/persistence.rb +522 -0
  70. data/lib/xamplr/persistence.rb.more_thread_safe +771 -0
  71. data/lib/xamplr/persistence.rb.partially_thread_safe +763 -0
  72. data/lib/xamplr/persister.rb +310 -0
  73. data/lib/xamplr/persisters/caches.rb +186 -0
  74. data/lib/xamplr/persisters/caching.rb +172 -0
  75. data/lib/xamplr/persisters/filesystem.rb +60 -0
  76. data/lib/xamplr/persisters/in-memory.rb +180 -0
  77. data/lib/xamplr/persisters/simple.rb +59 -0
  78. data/lib/xamplr/persisters/tokyo-cabinet.rb +641 -0
  79. data/lib/xamplr/simpleTemplate/danger.rx +4 -0
  80. data/lib/xamplr/simpleTemplate/obsolete/input-c.r4 +35 -0
  81. data/lib/xamplr/simpleTemplate/obsolete/play.r6.txt +12 -0
  82. data/lib/xamplr/simpleTemplate/obsolete/play_more.r6.txt +20 -0
  83. data/lib/xamplr/simpleTemplate/obsolete/test001.r5 +8 -0
  84. data/lib/xamplr/simpleTemplate/obsolete/test002.r5 +13 -0
  85. data/lib/xamplr/simpleTemplate/obsolete/test003.r5 +37 -0
  86. data/lib/xamplr/simpleTemplate/old/r6.000.rb +122 -0
  87. data/lib/xamplr/simpleTemplate/old/r6.001.rb +145 -0
  88. data/lib/xamplr/simpleTemplate/play.r6 +12 -0
  89. data/lib/xamplr/simpleTemplate/play_more.r6 +20 -0
  90. data/lib/xamplr/simpleTemplate/play_noblanks.r6 +21 -0
  91. data/lib/xamplr/simpleTemplate/playq.r6 +16 -0
  92. data/lib/xamplr/simpleTemplate/r6.rb +87 -0
  93. data/lib/xamplr/simpleTemplate/simple-template.rb +75 -0
  94. data/lib/xamplr/templates/child.template +47 -0
  95. data/lib/xamplr/templates/child_indexed.template +89 -0
  96. data/lib/xamplr/templates/child_modules.template +5 -0
  97. data/lib/xamplr/templates/element_classes.template +11 -0
  98. data/lib/xamplr/templates/element_data.template +282 -0
  99. data/lib/xamplr/templates/element_empty.template +285 -0
  100. data/lib/xamplr/templates/element_mixed.template +277 -0
  101. data/lib/xamplr/templates/element_simple.template +276 -0
  102. data/lib/xamplr/templates/package.template +26 -0
  103. data/lib/xamplr/test-support/Makefile +47 -0
  104. data/lib/xamplr/test-support/bench-cache.rb +80 -0
  105. data/lib/xamplr/test-support/bench-script.rb +21 -0
  106. data/lib/xamplr/test-support/bench.rb +116 -0
  107. data/lib/xamplr/test-support/bench2.rb +132 -0
  108. data/lib/xamplr/test-support/test-cache.rb +147 -0
  109. data/lib/xamplr/test-support/test-data/binding.xml +7 -0
  110. data/lib/xamplr/test-support/test-data/example.xml +14 -0
  111. data/lib/xamplr/test-support/test-data/internationalization-utf8.txt +1 -0
  112. data/lib/xamplr/test-support/test-data/labels.xml +37 -0
  113. data/lib/xamplr/test-support/test-data/labels001.xml +38 -0
  114. data/lib/xamplr/test-support/test-deep-change.rb +135 -0
  115. data/lib/xamplr/test-support/test-elements.rb +109 -0
  116. data/lib/xamplr/test-support/test-indexed-array.rb +169 -0
  117. data/lib/xamplr/test-support/test-misc.rb +73 -0
  118. data/lib/xamplr/test-support/test-names.rb +67 -0
  119. data/lib/xamplr/test-support/test-rollback.rb +106 -0
  120. data/lib/xamplr/test-support/test.rb +1504 -0
  121. data/lib/xamplr/to-ruby.rb +220 -0
  122. data/lib/xamplr/to-xml.rb +158 -0
  123. data/lib/xamplr/version.rb +67 -0
  124. data/lib/xamplr/visitor.rb +140 -0
  125. data/lib/xamplr/visitors.rb +573 -0
  126. data/lib/xamplr/xampl-generator.rb +533 -0
  127. data/lib/xamplr/xampl-hand-generated.rb +1535 -0
  128. data/lib/xamplr/xampl-module.rb +36 -0
  129. data/lib/xamplr/xampl-object-internals.rb +6 -0
  130. data/lib/xamplr/xampl-object.rb +202 -0
  131. data/lib/xamplr/xampl-persisted-object.rb +122 -0
  132. data/lib/xamplr/xml-text.rb +117 -0
  133. data/lib/xamplr/xml/document.xml +7 -0
  134. data/lib/xamplr/xml/elements.xml +101 -0
  135. data/lib/xamplr/xml/elements000.xml +73 -0
  136. data/lib/xamplr/xml/example.xml +23 -0
  137. data/lib/xamplr/xml/options.xml +12 -0
  138. data/lib/xamplr/xml/uche.xml +38 -0
  139. data/lib/xamplr/yEd-sample.graphml +300 -0
  140. data/test/test_helper.rb +10 -0
  141. data/test/xamplr_test.rb +7 -0
  142. metadata +245 -0
@@ -0,0 +1,172 @@
1
+ module Xampl
2
+
3
+ require "fileutils"
4
+ require "xamplr/persisters/caches"
5
+
6
+ class AbstractCachingPersister < Persister
7
+
8
+ def initialize(root, name=nil, format=nil, capacity=DEFAULT_CAPACITY)
9
+ super(name, format)
10
+
11
+ raise XamplException.new(:name_required) unless name
12
+
13
+ @root_dir = File.join(root, name)
14
+ @repo_root = root
15
+ @repo_name = name
16
+
17
+ @capacity = capacity
18
+ @cache = {}
19
+ @new_cache = {}
20
+ end
21
+
22
+ def fresh_cache
23
+ return XamplCache.new(@capacity)
24
+ end
25
+
26
+ def sync_done
27
+ if @new_cache then
28
+ @new_cache.each do |name1, map1|
29
+ if map1 then
30
+ cache_map1 = @cache[name1]
31
+ @cache[name1] = cache_map1 = {} unless cache_map1
32
+ map1.each do |name2, map2|
33
+ if map2 then
34
+ cache_map2 = cache_map1[name2]
35
+ #cache_map1[name2] = cache_map2 = {} unless cache_map2
36
+ cache_map1[name2] = cache_map2 = fresh_cache unless cache_map2
37
+
38
+ #cache_map2.merge!(map2)
39
+ map2.each do |pid, xampl|
40
+ cache_map2[pid] = xampl
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ @new_cache = {}
48
+ end
49
+
50
+ def rollback_cleanup
51
+ @new_cache.each do |name, map|
52
+ if map then
53
+ map.each do |name2, map2|
54
+ if map2 then
55
+ map2.each do |pid, xampl|
56
+ @changed.delete(xampl)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ @changed.each do |xampl, ignore|
62
+ xampl.force_load
63
+ end
64
+ @new_cache = {}
65
+ super
66
+ end
67
+ end
68
+
69
+ def cache(xampl)
70
+ Xampl.store_in_map(@new_cache, xampl) { xampl }
71
+ xampl.introduce_persister(self)
72
+ end
73
+
74
+ def uncache(xampl)
75
+ @changed.delete(xampl)
76
+ Xampl.remove_from_map(@cache, xampl)
77
+ return Xampl.remove_from_map(@new_cache, xampl)
78
+ end
79
+
80
+ def clear_cache
81
+ @cache = {}
82
+ @new_cache = {}
83
+ end
84
+
85
+ def write_to_cache(xampl)
86
+ # puts "WRITE TO CACHE (#{xampl})"
87
+ return Xampl.store_in_cache(@cache, xampl, self) { xampl }
88
+ end
89
+
90
+ def read_from_cache(klass, pid, target=nil)
91
+ xampl = Xampl.lookup_in_map(@cache, klass, pid)
92
+ if xampl then
93
+ if target and target != xampl then
94
+
95
+ puts "#{File.basename(__FILE__)} #{__LINE__} CACHE CONFLICT:: klass: #{ klass }, pid: #{ pid }, target: #{ target }, cached: #{ xampl }"
96
+ dump(@cache)
97
+ caller(0).each { | trace | puts " #{trace}"}
98
+
99
+ target.invalidate
100
+ raise XamplException.new(:cache_conflict)
101
+ end
102
+ unless xampl.load_needed then
103
+ @cache_hits = @cache_hits + 1
104
+ return xampl, target
105
+ end
106
+ return xampl, xampl
107
+ end
108
+
109
+ xampl = Xampl.lookup_in_map(@new_cache, klass, pid)
110
+ if xampl then
111
+ if target and target != xampl then
112
+ target.invalidate
113
+ raise XamplException.new(:cache_conflict)
114
+ end
115
+ unless xampl.load_needed then
116
+ @cache_hits = @cache_hits + 1
117
+ return xampl, target
118
+ end
119
+ return xampl, xampl
120
+ end
121
+
122
+ return nil, target
123
+ end
124
+
125
+ def dump(cache)
126
+ puts "DUMP CACHE"
127
+ cache.each do | k, v |
128
+ puts "--- [[#{k}]]"
129
+ v.each do | kk, vv |
130
+ puts "--- --- [[#{kk}]]"
131
+ puts vv.print
132
+ end
133
+ end
134
+ end
135
+
136
+ def read(klass, pid, target=nil)
137
+ # puts "#{File.basename(__FILE__)} #{__LINE__} READ:: klass: #{klass} pid: #{pid} target: [[#{target}]], PM: #{ self }"
138
+
139
+ xampl, target = read_from_cache(klass, pid, target)
140
+ return xampl if xampl and !target
141
+
142
+ representation = read_representation(klass, pid)
143
+ return nil unless representation
144
+
145
+ xampl = nil
146
+ begin
147
+ #puts "ABSTRACT_READ[#{__LINE__}]:: klass: #{klass} pid: #{pid} target: #{target}"
148
+ xampl = realise(representation, target)
149
+ return nil unless xampl
150
+ rescue Exception => e
151
+ puts "FAILED TO READ -- persister: #{name} klass: #{klass} pid: #{pid} target: #{target}"
152
+ puts "Exception: #{e}"
153
+ print e.backtrace.join("\n")
154
+ #sleep 10
155
+ raise e
156
+ end
157
+
158
+ # puts "#{File.basename(__FILE__)} #{__LINE__} STORE IN CACHE:: xampl: #{xampl }, persister: #{ self }"
159
+ # dump(@cache)
160
+
161
+ Xampl.store_in_cache(@cache, xampl, self) { xampl }
162
+ xampl.introduce_persister(self)
163
+
164
+ @read_count = @read_count + 1
165
+ xampl.changes_accepted
166
+ @changed.delete(xampl)
167
+
168
+ return xampl
169
+ end
170
+ end
171
+ end
172
+
@@ -0,0 +1,60 @@
1
+ module Xampl
2
+
3
+ require 'xamplr/version'
4
+
5
+ require "fileutils"
6
+ require "xamplr/persisters/caching"
7
+
8
+ class FilesystemPersister < AbstractCachingPersister
9
+
10
+ def initialize(name=nil, format=nil, root=File.join(".", "repo"))
11
+ super(root, name, format)
12
+ end
13
+
14
+ def FilesystemPersister.kind
15
+ :filesystem
16
+ end
17
+
18
+ def kind
19
+ FilesystemPersister.kind
20
+ end
21
+
22
+ def version(stream)
23
+ catch(:refuse_to_version) do
24
+ Version.new(@repo_name, @repo_root).make(stream)
25
+ end
26
+ end
27
+
28
+
29
+ def write(xampl)
30
+ #raise XamplException.new(:no_index_so_no_persist) unless xampl.get_the_index or xampl.ignore_when_no_index
31
+ raise XamplException.new("no_index_so_no_persist [#{xampl.class.name}]") unless xampl.get_the_index or xampl.ignore_when_no_index
32
+ return unless xampl.get_the_index
33
+
34
+ place = File.join(@root_dir, xampl.class.name.split("::"))
35
+
36
+ FileUtils.mkdir_p(place) unless File.exist?(place)
37
+
38
+ place = File.join(place, xampl.get_the_index)
39
+
40
+ representation = represent(xampl)
41
+ if representation then
42
+ File.open(place, "w"){ | out | out.puts representation }
43
+ @write_count = @write_count + 1
44
+ end
45
+ xampl.changes_accepted
46
+ return true
47
+ end
48
+
49
+ def read_representation(klass, pid)
50
+ place = File.join(@root_dir, klass.name.split("::"), pid)
51
+
52
+ return nil unless File.exist?(place)
53
+ representation = File.read(place)
54
+ return representation
55
+ end
56
+ end
57
+
58
+ Xampl.register_persister_kind(FilesystemPersister)
59
+ end
60
+
@@ -0,0 +1,180 @@
1
+ module Xampl
2
+
3
+ require "xamplr/persisters/caches"
4
+
5
+ class InMemoryPersister < Persister
6
+
7
+ def initialize(name=nil, format=nil, capacity=20)
8
+ super(name, format)
9
+
10
+ @module_map = {}
11
+ @capacity = capacity
12
+ @cache = {}
13
+ @new_cache = {}
14
+ end
15
+
16
+ def InMemoryPersister.kind
17
+ :in_memory
18
+ end
19
+
20
+ def kind
21
+ InMemoryPersister.kind
22
+ end
23
+
24
+ def fresh_cache
25
+ return XamplCache.new(@capacity)
26
+ end
27
+
28
+ def sync_done
29
+ if @new_cache then
30
+ @new_cache.each{ | name1, map1 |
31
+ if map1 then
32
+ cache_map1 = @cache[name1]
33
+ @cache[name1] = cache_map1 = {} unless cache_map1
34
+ map1.each{ | name2, map2 |
35
+ if map2 then
36
+ cache_map2 = cache_map1[name2]
37
+ cache_map1[name2] = cache_map2 = self.fresh_cache unless cache_map2
38
+
39
+ map2.each{ | pid, xampl |
40
+ cache_map2[pid] = xampl
41
+ }
42
+ end
43
+ }
44
+ end
45
+ }
46
+ end
47
+ @new_cache = {}
48
+ end
49
+
50
+ def rollback_cleanup
51
+ @new_cache.each{ | name, map |
52
+ if map then
53
+ map.each{ | name2, map2 |
54
+ if map2 then
55
+ map2.each{ | pid, xampl |
56
+ @changed.delete(xampl)
57
+ xampl.invalidate
58
+ }
59
+ end
60
+ }
61
+ end
62
+ }
63
+ @changed.each{ | xampl, ignore|
64
+ xampl.force_load
65
+ }
66
+ @new_cache = {}
67
+ super
68
+ end
69
+
70
+ def cache(xampl)
71
+ return Xampl.store_in_map(@new_cache, xampl) { xampl }
72
+ end
73
+
74
+ def uncache(xampl)
75
+ @changed.delete(xampl)
76
+ Xampl.remove_from_map(@cache, xampl)
77
+ return Xampl.remove_from_map(@new_cache, xampl)
78
+ end
79
+
80
+ def clear_cache
81
+ @new_cache = {}
82
+ @cache = {}
83
+ end
84
+
85
+ def write(xampl)
86
+ raise XamplException.new(:no_index_so_no_persist) unless xampl.get_the_index
87
+ #return false unless xampl.get_the_index
88
+
89
+ if Xampl.store_in_map(@module_map, xampl) { represent(xampl) } then
90
+ @write_count = @write_count + 1
91
+ xampl.changes_accepted
92
+ return true
93
+ else
94
+ return false
95
+ end
96
+ end
97
+
98
+ def read_from_cache(klass, pid, target=nil)
99
+ xampl = Xampl.lookup_in_map(@cache, klass, pid)
100
+ if xampl then
101
+ if target and target != xampl then
102
+ target.invalidate
103
+ raise XamplException.new(:cache_conflict)
104
+ end
105
+ unless xampl.load_needed then
106
+ @cache_hits = @cache_hits + 1
107
+ return xampl, target
108
+ end
109
+ return xampl, xampl
110
+ end
111
+
112
+ xampl = Xampl.lookup_in_map(@new_cache, klass, pid)
113
+ if xampl then
114
+ if target and target != xampl then
115
+ target.invalidate
116
+ raise XamplException.new(:cache_conflict)
117
+ end
118
+ unless xampl.load_needed then
119
+ @cache_hits = @cache_hits + 1
120
+ return xampl, target
121
+ end
122
+ return xampl, xampl
123
+ end
124
+
125
+ return nil, target
126
+ end
127
+
128
+ def xxread_from_cache(klass, pid, target=nil)
129
+ xampl = Xampl.lookup_in_map(@cache, klass, pid)
130
+ if (nil != xampl) then
131
+ puts "READ CACHE pid #{pid} -- #{target} #{xampl}" if target and target != xampl
132
+ if target and target != xampl then
133
+ target.invalidate
134
+ raise XamplException.new(:cache_conflict)
135
+ end
136
+ unless xampl.load_needed then
137
+ @cache_hits = @cache_hits + 1
138
+ return xampl
139
+ end
140
+ target = xampl
141
+ end
142
+
143
+ xampl = Xampl.lookup_in_map(@new_cache, klass, pid)
144
+ if (nil != xampl) then
145
+ puts "READ CACHE pid #{pid} -- #{target} #{xampl}" if target and target != xampl
146
+ if target and target != xampl then
147
+ target.invalidate
148
+ raise XamplException.new(:cache_conflict)
149
+ end
150
+ unless xampl.load_needed then
151
+ @cache_hits = @cache_hits + 1
152
+ return xampl
153
+ end
154
+ target = xampl
155
+ end
156
+
157
+ return xampl
158
+ end
159
+
160
+ def read(klass, pid, target=nil)
161
+ xampl, target = read_from_cache(klass, pid, target)
162
+ return xampl if xampl and !target
163
+
164
+ representation = Xampl.lookup_in_map(@module_map, klass, pid)
165
+ return nil unless representation
166
+
167
+ xampl = realise(representation, target)
168
+ Xampl.store_in_cache(@cache, xampl, self) { xampl }
169
+ xampl.introduce_persister(self)
170
+
171
+ @read_count = @read_count + 1
172
+ xampl.changes_accepted
173
+ @changed.delete(xampl)
174
+ return xampl
175
+ end
176
+ end
177
+
178
+ Xampl.register_persister_kind(InMemoryPersister)
179
+ end
180
+
@@ -0,0 +1,59 @@
1
+ module Xampl
2
+
3
+ class SimplePersister < Persister
4
+
5
+ def initialize(name=nil, format=nil)
6
+ super(name, format)
7
+
8
+ @module_map = {}
9
+ @cache = {}
10
+ end
11
+
12
+ def SimplePersister.kind
13
+ :simple
14
+ end
15
+
16
+ def kind
17
+ SimplePersister.kind
18
+ end
19
+
20
+ def sync_done
21
+ end
22
+
23
+ def has_changed(xampl)
24
+ throw :mixed_persisters unless self == xampl.persister
25
+ end
26
+
27
+ def cache(xampl)
28
+ return Xampl.store_in_map(@cache, xampl) { xampl }
29
+ end
30
+
31
+ def uncache(xampl)
32
+ end
33
+
34
+ def clear_cache
35
+ throw :really_bad_idea, "clearing the cache in a simple persister looses information"
36
+ end
37
+
38
+ def write(xampl)
39
+ return true
40
+ end
41
+
42
+ def read(klass, pid, target=nil)
43
+ xampl = Xampl.lookup_in_map(@cache, klass, pid)
44
+
45
+ if (nil != xampl) then
46
+ if target and target != xampl then
47
+ target.invalidate
48
+ throw(:cache_conflict)
49
+ end
50
+ throw(:load_unsupported) if xampl.load_needed
51
+ end
52
+
53
+ return xampl
54
+ end
55
+ end
56
+
57
+ Xampl.register_persister_kind(SimplePersister)
58
+ end
59
+