juno 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. data/README.md +2 -277
  2. data/juno.gemspec +6 -5
  3. data/lib/juno.rb +3 -122
  4. metadata +23 -307
  5. data/.gitignore +0 -6
  6. data/.travis.yml +0 -30
  7. data/Gemfile +0 -56
  8. data/LICENSE +0 -20
  9. data/Rakefile +0 -33
  10. data/SPEC.md +0 -71
  11. data/benchmarks/run.rb +0 -180
  12. data/lib/juno/adapters/activerecord.rb +0 -74
  13. data/lib/juno/adapters/cassandra.rb +0 -89
  14. data/lib/juno/adapters/cookie.rb +0 -35
  15. data/lib/juno/adapters/couch.rb +0 -57
  16. data/lib/juno/adapters/datamapper.rb +0 -76
  17. data/lib/juno/adapters/dbm.rb +0 -25
  18. data/lib/juno/adapters/file.rb +0 -60
  19. data/lib/juno/adapters/fog.rb +0 -51
  20. data/lib/juno/adapters/gdbm.rb +0 -25
  21. data/lib/juno/adapters/hbase.rb +0 -64
  22. data/lib/juno/adapters/leveldb.rb +0 -35
  23. data/lib/juno/adapters/localmemcache.rb +0 -26
  24. data/lib/juno/adapters/lruhash.rb +0 -83
  25. data/lib/juno/adapters/memcached.rb +0 -11
  26. data/lib/juno/adapters/memcached_dalli.rb +0 -51
  27. data/lib/juno/adapters/memcached_native.rb +0 -52
  28. data/lib/juno/adapters/memory.rb +0 -32
  29. data/lib/juno/adapters/mongo.rb +0 -50
  30. data/lib/juno/adapters/null.rb +0 -30
  31. data/lib/juno/adapters/pstore.rb +0 -58
  32. data/lib/juno/adapters/redis.rb +0 -56
  33. data/lib/juno/adapters/riak.rb +0 -57
  34. data/lib/juno/adapters/sdbm.rb +0 -35
  35. data/lib/juno/adapters/sequel.rb +0 -67
  36. data/lib/juno/adapters/sqlite.rb +0 -61
  37. data/lib/juno/adapters/tokyocabinet.rb +0 -41
  38. data/lib/juno/adapters/yaml.rb +0 -15
  39. data/lib/juno/base.rb +0 -62
  40. data/lib/juno/builder.rb +0 -39
  41. data/lib/juno/cache.rb +0 -78
  42. data/lib/juno/expires.rb +0 -47
  43. data/lib/juno/lock.rb +0 -44
  44. data/lib/juno/logger.rb +0 -86
  45. data/lib/juno/proxy.rb +0 -72
  46. data/lib/juno/stack.rb +0 -72
  47. data/lib/juno/transformer.rb +0 -176
  48. data/lib/juno/version.rb +0 -5
  49. data/lib/rack/cache/juno.rb +0 -93
  50. data/lib/rack/juno_cookies.rb +0 -64
  51. data/lib/rack/session/juno.rb +0 -63
  52. data/spec/generate.rb +0 -1068
  53. data/spec/helper.rb +0 -78
  54. data/spec/juno/adapter_activerecord_spec.rb +0 -27
  55. data/spec/juno/adapter_cassandra_spec.rb +0 -13
  56. data/spec/juno/adapter_cookie_spec.rb +0 -13
  57. data/spec/juno/adapter_couch_spec.rb +0 -13
  58. data/spec/juno/adapter_datamapper_spec.rb +0 -44
  59. data/spec/juno/adapter_dbm_spec.rb +0 -13
  60. data/spec/juno/adapter_file_spec.rb +0 -13
  61. data/spec/juno/adapter_fog_spec.rb +0 -18
  62. data/spec/juno/adapter_gdbm_spec.rb +0 -13
  63. data/spec/juno/adapter_hbase_spec.rb +0 -13
  64. data/spec/juno/adapter_leveldb_spec.rb +0 -13
  65. data/spec/juno/adapter_localmemcache_spec.rb +0 -13
  66. data/spec/juno/adapter_lruhash_spec.rb +0 -26
  67. data/spec/juno/adapter_memcached_dalli_spec.rb +0 -14
  68. data/spec/juno/adapter_memcached_native_spec.rb +0 -14
  69. data/spec/juno/adapter_memcached_spec.rb +0 -14
  70. data/spec/juno/adapter_memory_spec.rb +0 -34
  71. data/spec/juno/adapter_mongo_spec.rb +0 -13
  72. data/spec/juno/adapter_pstore_spec.rb +0 -16
  73. data/spec/juno/adapter_redis_spec.rb +0 -14
  74. data/spec/juno/adapter_riak_spec.rb +0 -17
  75. data/spec/juno/adapter_sdbm_spec.rb +0 -13
  76. data/spec/juno/adapter_sequel_spec.rb +0 -13
  77. data/spec/juno/adapter_sqlite_spec.rb +0 -13
  78. data/spec/juno/adapter_tokyocabinet_bdb_spec.rb +0 -13
  79. data/spec/juno/adapter_tokyocabinet_hdb_spec.rb +0 -13
  80. data/spec/juno/adapter_yaml_spec.rb +0 -16
  81. data/spec/juno/cache_file_memory_spec.rb +0 -29
  82. data/spec/juno/cache_memory_null_spec.rb +0 -18
  83. data/spec/juno/expires_file_spec.rb +0 -71
  84. data/spec/juno/expires_memory_spec.rb +0 -49
  85. data/spec/juno/lock_spec.rb +0 -37
  86. data/spec/juno/null_adapter_spec.rb +0 -22
  87. data/spec/juno/proxy_expires_memory_spec.rb +0 -51
  88. data/spec/juno/proxy_redis_spec.rb +0 -18
  89. data/spec/juno/simple_activerecord_spec.rb +0 -45
  90. data/spec/juno/simple_activerecord_with_expires_spec.rb +0 -46
  91. data/spec/juno/simple_cassandra_spec.rb +0 -46
  92. data/spec/juno/simple_couch_spec.rb +0 -45
  93. data/spec/juno/simple_couch_with_expires_spec.rb +0 -46
  94. data/spec/juno/simple_datamapper_spec.rb +0 -47
  95. data/spec/juno/simple_datamapper_with_expires_spec.rb +0 -48
  96. data/spec/juno/simple_datamapper_with_repository_spec.rb +0 -47
  97. data/spec/juno/simple_dbm_spec.rb +0 -45
  98. data/spec/juno/simple_dbm_with_expires_spec.rb +0 -46
  99. data/spec/juno/simple_file_spec.rb +0 -45
  100. data/spec/juno/simple_file_with_expires_spec.rb +0 -46
  101. data/spec/juno/simple_fog_spec.rb +0 -50
  102. data/spec/juno/simple_fog_with_expires_spec.rb +0 -52
  103. data/spec/juno/simple_gdbm_spec.rb +0 -45
  104. data/spec/juno/simple_gdbm_with_expires_spec.rb +0 -46
  105. data/spec/juno/simple_hashfile_spec.rb +0 -45
  106. data/spec/juno/simple_hashfile_with_expires_spec.rb +0 -46
  107. data/spec/juno/simple_hbase_spec.rb +0 -45
  108. data/spec/juno/simple_hbase_with_expires_spec.rb +0 -46
  109. data/spec/juno/simple_leveldb_spec.rb +0 -45
  110. data/spec/juno/simple_leveldb_with_expires_spec.rb +0 -46
  111. data/spec/juno/simple_localmemcache_spec.rb +0 -45
  112. data/spec/juno/simple_localmemcache_with_expires_spec.rb +0 -46
  113. data/spec/juno/simple_lruhash_spec.rb +0 -45
  114. data/spec/juno/simple_lruhash_with_expires_spec.rb +0 -46
  115. data/spec/juno/simple_memcached_dalli_spec.rb +0 -46
  116. data/spec/juno/simple_memcached_native_spec.rb +0 -46
  117. data/spec/juno/simple_memcached_spec.rb +0 -46
  118. data/spec/juno/simple_memory_spec.rb +0 -45
  119. data/spec/juno/simple_memory_with_compress_spec.rb +0 -45
  120. data/spec/juno/simple_memory_with_expires_spec.rb +0 -46
  121. data/spec/juno/simple_memory_with_json_key_serializer_spec.rb +0 -32
  122. data/spec/juno/simple_memory_with_json_md5_key_serializer_spec.rb +0 -32
  123. data/spec/juno/simple_memory_with_json_serializer_spec.rb +0 -22
  124. data/spec/juno/simple_memory_with_json_value_serializer_spec.rb +0 -29
  125. data/spec/juno/simple_memory_with_prefix_spec.rb +0 -45
  126. data/spec/juno/simple_memory_with_quicklz_compress_spec.rb +0 -45
  127. data/spec/juno/simple_mongo_spec.rb +0 -45
  128. data/spec/juno/simple_mongo_with_expires_spec.rb +0 -46
  129. data/spec/juno/simple_null_spec.rb +0 -32
  130. data/spec/juno/simple_pstore_spec.rb +0 -45
  131. data/spec/juno/simple_pstore_with_expires_spec.rb +0 -46
  132. data/spec/juno/simple_redis_spec.rb +0 -46
  133. data/spec/juno/simple_riak_spec.rb +0 -49
  134. data/spec/juno/simple_riak_with_expires_spec.rb +0 -50
  135. data/spec/juno/simple_sdbm_spec.rb +0 -45
  136. data/spec/juno/simple_sdbm_with_expires_spec.rb +0 -46
  137. data/spec/juno/simple_sequel_spec.rb +0 -45
  138. data/spec/juno/simple_sequel_with_expires_spec.rb +0 -46
  139. data/spec/juno/simple_sqlite_spec.rb +0 -45
  140. data/spec/juno/simple_sqlite_with_expires_spec.rb +0 -46
  141. data/spec/juno/simple_tokyocabinet_spec.rb +0 -45
  142. data/spec/juno/simple_tokyocabinet_with_expires_spec.rb +0 -46
  143. data/spec/juno/simple_yaml_spec.rb +0 -44
  144. data/spec/juno/simple_yaml_with_expires_spec.rb +0 -45
  145. data/spec/juno/stack_file_memory_spec.rb +0 -20
  146. data/spec/juno/stack_memory_file_spec.rb +0 -19
  147. data/spec/juno/transformer_bencode_spec.rb +0 -25
  148. data/spec/juno/transformer_bert_spec.rb +0 -25
  149. data/spec/juno/transformer_bson_spec.rb +0 -25
  150. data/spec/juno/transformer_bzip2_spec.rb +0 -22
  151. data/spec/juno/transformer_json_spec.rb +0 -25
  152. data/spec/juno/transformer_lzma_spec.rb +0 -22
  153. data/spec/juno/transformer_lzo_spec.rb +0 -22
  154. data/spec/juno/transformer_marshal_base64_spec.rb +0 -48
  155. data/spec/juno/transformer_marshal_escape_spec.rb +0 -48
  156. data/spec/juno/transformer_marshal_hmac_spec.rb +0 -48
  157. data/spec/juno/transformer_marshal_md5_spec.rb +0 -48
  158. data/spec/juno/transformer_marshal_md5_spread_spec.rb +0 -48
  159. data/spec/juno/transformer_marshal_prefix_spec.rb +0 -48
  160. data/spec/juno/transformer_marshal_rmd160_spec.rb +0 -48
  161. data/spec/juno/transformer_marshal_sha1_spec.rb +0 -48
  162. data/spec/juno/transformer_marshal_sha256_spec.rb +0 -48
  163. data/spec/juno/transformer_marshal_sha384_spec.rb +0 -48
  164. data/spec/juno/transformer_marshal_sha512_spec.rb +0 -48
  165. data/spec/juno/transformer_marshal_uuencode_spec.rb +0 -48
  166. data/spec/juno/transformer_msgpack_spec.rb +0 -25
  167. data/spec/juno/transformer_ox_spec.rb +0 -46
  168. data/spec/juno/transformer_quicklz_spec.rb +0 -22
  169. data/spec/juno/transformer_snappy_spec.rb +0 -22
  170. data/spec/juno/transformer_tnet_spec.rb +0 -25
  171. data/spec/juno/transformer_yaml_spec.rb +0 -46
  172. data/spec/juno/transformer_zlib_spec.rb +0 -22
  173. data/spec/junospecs.rb +0 -2284
  174. data/spec/rack/cache_juno_spec.rb +0 -355
  175. data/spec/rack/juno_cookies_spec.rb +0 -81
  176. data/spec/rack/session_juno_spec.rb +0 -305
@@ -1,35 +0,0 @@
1
- require 'leveldb'
2
-
3
- module Juno
4
- module Adapters
5
- # LevelDB backend
6
- # @api public
7
- class LevelDB < Memory
8
- # Constructor
9
- #
10
- # @param [Hash] options
11
- #
12
- # Options:
13
- # * :dir - Database path
14
- # * All other options passed to LevelDB::DB#new
15
- def initialize(options = {})
16
- raise ArgumentError, 'Option :dir is required' unless options[:dir]
17
- @memory = ::LevelDB::DB.new(options[:dir])
18
- end
19
-
20
- def key?(key, options = {})
21
- @memory.includes?(key)
22
- end
23
-
24
- def clear(options = {})
25
- @memory.each {|k,v| delete(k, options) }
26
- self
27
- end
28
-
29
- def close
30
- @memory.close
31
- nil
32
- end
33
- end
34
- end
35
- end
@@ -1,26 +0,0 @@
1
- require 'localmemcache'
2
-
3
- module Juno
4
- module Adapters
5
- # LocalMemCache backend
6
- # @api public
7
- class LocalMemCache < Memory
8
- # Constructor
9
- #
10
- # @param [Hash] options
11
- #
12
- # Options:
13
- # * :file - Database file
14
- def initialize(options = {})
15
- raise ArgumentError, 'Option :file is required' unless options[:file]
16
- @memory = ::LocalMemCache.new(:filename => options[:file])
17
- end
18
-
19
- def delete(key, options = {})
20
- value = load(key, options)
21
- @memory.delete(key)
22
- value
23
- end
24
- end
25
- end
26
- end
@@ -1,83 +0,0 @@
1
- module Juno
2
- module Adapters
3
- # LRUHash backend
4
- #
5
- # Based on Hashery::LRUHash but simpler and measures memory usage instead of hash size.
6
- #
7
- # @api public
8
- class LRUHash < Base
9
- # Constructor
10
- #
11
- # @param [Hash] options
12
- #
13
- # Options:
14
- # * :max_size - Maximum byte size of hash values (default 1024000)
15
- def initialize(options = {})
16
- @max_size = options[:max_size] || 1024000
17
- clear
18
- end
19
-
20
- def key?(key, options = {})
21
- @entry.key?(key)
22
- end
23
-
24
- def load(key, options = {})
25
- if entry = @entry[key]
26
- entry.insert_after(@list)
27
- entry.value
28
- end
29
- end
30
-
31
- def store(key, value, options = {})
32
- if entry = @entry[key]
33
- @size -= entry.value.bytesize
34
- else
35
- @entry[key] = entry = Entry.new
36
- entry.key = key
37
- end
38
- entry.value = value
39
- @size += entry.value.bytesize
40
- entry.insert_after(@list)
41
- delete(@list.prev.key) while @list.next != @list.prev && @size > @max_size
42
- value
43
- end
44
-
45
- def delete(key, options = {})
46
- if entry = @entry.delete(key)
47
- @size -= entry.value.bytesize
48
- entry.unlink
49
- entry.value
50
- end
51
- end
52
-
53
- def clear(options = {})
54
- @entry, @size = {}, 0
55
- @list = Entry.new
56
- @list.prev = @list.next = @list
57
- self
58
- end
59
-
60
- private
61
-
62
- class Entry
63
- attr_accessor :key, :value, :prev, :next
64
-
65
- def unlink
66
- @prev.next = @next if @prev
67
- @next.prev = @prev if @next
68
- @prev = @next = nil
69
- end
70
-
71
- def insert_after(entry)
72
- if entry.next != self
73
- unlink
74
- @next = entry.next
75
- @prev = entry
76
- entry.next.prev = self
77
- entry.next = self
78
- end
79
- end
80
- end
81
- end
82
- end
83
- end
@@ -1,11 +0,0 @@
1
- module Juno
2
- module Adapters
3
- begin
4
- require 'juno/adapters/memcached_native'
5
- Memcached = MemcachedNative
6
- rescue LoadError
7
- require 'juno/adapters/memcached_dalli'
8
- Memcached = MemcachedDalli
9
- end
10
- end
11
- end
@@ -1,51 +0,0 @@
1
- require 'dalli'
2
-
3
- module Juno
4
- module Adapters
5
- # Memcached backend (using gem dalli)
6
- # @api public
7
- class MemcachedDalli < Base
8
- # Constructor
9
- #
10
- # @param [Hash] options
11
- #
12
- # Options:
13
- # * :server - Memcached server (default localhost:11211)
14
- # * Other options passed to Dalli::Client#new
15
- def initialize(options = {})
16
- server = options.delete(:server) || 'localhost:11211'
17
- @cache = ::Dalli::Client.new(server, options)
18
- end
19
-
20
- def load(key, options = {})
21
- value = @cache.get(key)
22
- if value && options.include?(:expires)
23
- store(key, value, options)
24
- else
25
- value
26
- end
27
- end
28
-
29
- def store(key, value, options = {})
30
- @cache.set(key, value, options[:expires])
31
- value
32
- end
33
-
34
- def delete(key, options = {})
35
- value = @cache.get(key)
36
- @cache.delete(key)
37
- value
38
- end
39
-
40
- def clear(options = {})
41
- @cache.flush_all
42
- self
43
- end
44
-
45
- def close
46
- @cache.close
47
- nil
48
- end
49
- end
50
- end
51
- end
@@ -1,52 +0,0 @@
1
- require 'memcached'
2
-
3
- module Juno
4
- module Adapters
5
- # Memcached backend (using gem memcached)
6
- # @api public
7
- class MemcachedNative < Base
8
- # Constructor
9
- #
10
- # @param [Hash] options
11
- #
12
- # Options:
13
- # * :server - Memcached server (default localhost:11211)
14
- # * :namespace - Key namespace
15
- # * Other options passed to Memcached#new
16
- def initialize(options = {})
17
- server = options.delete(:server) || 'localhost:11211'
18
- options.merge!(:prefix_key => options.delete(:namespace)) if options[:namespace]
19
- @default_ttl = options[:default_ttl] || 604800
20
- @cache = ::Memcached.new(server, options)
21
- end
22
-
23
- def load(key, options = {})
24
- value = @cache.get(key, false)
25
- if value && options.include?(:expires)
26
- store(key, value, options)
27
- else
28
- value
29
- end
30
- rescue ::Memcached::NotFound
31
- end
32
-
33
- def delete(key, options = {})
34
- value = @cache.get(key, false)
35
- @cache.delete(key)
36
- value
37
- rescue ::Memcached::NotFound
38
- end
39
-
40
- def store(key, value, options = {})
41
- # TTL must be Fixnum
42
- @cache.set(key, value, options[:expires] || @default_ttl, false)
43
- value
44
- end
45
-
46
- def clear(options = {})
47
- @cache.flush
48
- self
49
- end
50
- end
51
- end
52
- end
@@ -1,32 +0,0 @@
1
- module Juno
2
- module Adapters
3
- # Memory backend using a hash to store the entries
4
- # @api public
5
- class Memory < Base
6
- def initialize(options = {})
7
- @memory = {}
8
- end
9
-
10
- def key?(key, options = {})
11
- @memory.has_key?(key)
12
- end
13
-
14
- def load(key, options = {})
15
- @memory[key]
16
- end
17
-
18
- def store(key, value, options = {})
19
- @memory[key] = value
20
- end
21
-
22
- def delete(key, options = {})
23
- @memory.delete(key)
24
- end
25
-
26
- def clear(options = {})
27
- @memory.clear
28
- self
29
- end
30
- end
31
- end
32
- end
@@ -1,50 +0,0 @@
1
- require 'mongo'
2
-
3
- module Juno
4
- module Adapters
5
- # MongoDB backend
6
- # @api public
7
- class Mongo < Base
8
- # Constructor
9
- #
10
- # @param [Hash] options
11
- #
12
- # Options:
13
- # * :collection - MongoDB collection name (default juno)
14
- # * :host - MongoDB server host (default localhost)
15
- # * :port - MongoDB server port (default mongodb default port)
16
- # * :db - MongoDB database (default juno)
17
- def initialize(options = {})
18
- collection = options.delete(:collection) || 'juno'
19
- host = options.delete(:host) || 'localhost'
20
- port = options.delete(:port) || ::Mongo::Connection::DEFAULT_PORT
21
- db = options.delete(:db) || 'juno'
22
- connection = ::Mongo::Connection.new(host, port, options)
23
- @collection = connection.db(db).collection(collection)
24
- end
25
-
26
- def load(key, options = {})
27
- value = @collection.find_one('_id' => key)
28
- value ? value['value'].to_s : nil
29
- end
30
-
31
- def delete(key, options = {})
32
- value = load(key, options)
33
- @collection.remove('_id' => key) if value
34
- value
35
- end
36
-
37
- def store(key, value, options = {})
38
- @collection.update({ '_id' => key },
39
- { '_id' => key, 'value' => ::BSON::Binary.new(value) },
40
- { :upsert => true })
41
- value
42
- end
43
-
44
- def clear(options = {})
45
- @collection.remove
46
- self
47
- end
48
- end
49
- end
50
- end
@@ -1,30 +0,0 @@
1
- module Juno
2
- module Adapters
3
- # Null backend which doesn't store anything
4
- # @api public
5
- class Null < Base
6
- def initialize(options = {})
7
- end
8
-
9
- def key?(key, options = {})
10
- false
11
- end
12
-
13
- def load(key, options = {})
14
- nil
15
- end
16
-
17
- def store(key, value, options = {})
18
- value
19
- end
20
-
21
- def delete(key, options = {})
22
- nil
23
- end
24
-
25
- def clear(options = {})
26
- self
27
- end
28
- end
29
- end
30
- end
@@ -1,58 +0,0 @@
1
- require 'pstore'
2
-
3
- module Juno
4
- module Adapters
5
- # PStore backend
6
- # @api public
7
- class PStore < Base
8
- # Constructor
9
- #
10
- # @param [Hash] options
11
- #
12
- # Options:
13
- # * :file - PStore file
14
- def initialize(options = {})
15
- raise ArgumentError, 'Option :file is required' unless options[:file]
16
- FileUtils.mkpath(::File.dirname(options[:file]))
17
- @pstore = new_store(options)
18
- end
19
-
20
- def key?(key, options = {})
21
- @pstore.transaction(true) { @pstore.root?(key) }
22
- end
23
-
24
- def load(key, options = {})
25
- @pstore.transaction(true) { @pstore[key] }
26
- end
27
-
28
- def delete(key, options = {})
29
- @pstore.transaction { @pstore.delete(key) }
30
- end
31
-
32
- def store(key, value, options = {})
33
- @pstore.transaction { @pstore[key] = value }
34
- end
35
-
36
- def clear(options = {})
37
- @pstore.transaction do
38
- @pstore.roots.each do |key|
39
- @pstore.delete(key)
40
- end
41
- end
42
- self
43
- end
44
-
45
- protected
46
-
47
- if RUBY_VERSION > '1.9'
48
- def new_store(options)
49
- ::PStore.new(options[:file], options[:threadsafe])
50
- end
51
- else
52
- def new_store(options)
53
- ::PStore.new(options[:file])
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,56 +0,0 @@
1
- require 'redis'
2
-
3
- module Juno
4
- module Adapters
5
- # Redis backend
6
- # @api public
7
- class Redis < Base
8
- # Constructor
9
- #
10
- # @param [Hash] options passed to Redis#new
11
- def initialize(options = {})
12
- @redis = ::Redis.new(options)
13
- end
14
-
15
- def key?(key, options = {})
16
- if @redis.exists(key)
17
- if expires = options[:expires]
18
- @redis.expire(key, expires)
19
- end
20
- true
21
- else
22
- false
23
- end
24
- end
25
-
26
- def load(key, options = {})
27
- value = @redis.get(key)
28
- if value && (expires = options[:expires])
29
- @redis.expire(key, expires)
30
- end
31
- value
32
- end
33
-
34
- def delete(key, options = {})
35
- if value = load(key, options)
36
- @redis.del(key)
37
- value
38
- end
39
- end
40
-
41
- def store(key, value, options = {})
42
- if expires = options[:expires]
43
- @redis.setex(key, expires, value)
44
- else
45
- @redis.set(key, value)
46
- end
47
- value
48
- end
49
-
50
- def clear(options = {})
51
- @redis.flushdb
52
- self
53
- end
54
- end
55
- end
56
- end