hoodie 0.3.21 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aa629d2fbc64caec2a47adfdfbd5d0930f223926
4
- data.tar.gz: 15954ba0a1aa24f20a862d4cbd44f2e3e5c8fc69
3
+ metadata.gz: e83cfa47334c8e94fa85098671646220f6c68712
4
+ data.tar.gz: 1ac0f613e7637ccb84207e66aa134b75c67c9bdf
5
5
  SHA512:
6
- metadata.gz: 4f477b059a41adb9ebd0cdc32fcf35cb05c14061ba7bdd219710440d58645beb8ccb39bee84bd90a21e3694a617c8c8c54e0de222e09cdab9c998eae7cfba5e5
7
- data.tar.gz: 0637b892a292050aff2dc3f1ac5ba64a5ea30d58f53406c8e4d0bf17304e68ef84c08e0c8bc205a8820a5c69dcc0e9a0b126d21dddbc086eb525d300c1b41eb4
6
+ metadata.gz: 9a09de6da5bc364aea2c32178386be400b90d2aaa25e0f67c427c995cac31f7e0c62a85222adfbe878ba48488a96d645639d93d87971607ba03735970855555f
7
+ data.tar.gz: dea4407f8d58b047b222f3e061be98091f2208327a293d006c0720f3064144731c5e11844df931bc4a52590fe5deef9f3657037004b70410df315fe0ff3fd482
data/.gitattributes ADDED
@@ -0,0 +1,17 @@
1
+ # Autodetect text files
2
+ * text=auto
3
+
4
+ # Make sure unix shell scripts use the correct line endings
5
+ *.sh eol=lf
6
+
7
+ # ...Unless the name matches the following
8
+ # overriding patterns
9
+
10
+ # Definitively text files
11
+ *.txt text
12
+ *.c text
13
+ *.h text
14
+
15
+ # Ensure those won't be messed up with
16
+ *.jpg binary
17
+ *.data binary
data/.gitignore ADDED
@@ -0,0 +1,193 @@
1
+ # Created by http://www.gitignore.io
2
+
3
+ ### OSX ###
4
+ .DS_Store
5
+ .AppleDouble
6
+ .LSOverride
7
+
8
+ # Icon must end with two \r
9
+ Icon
10
+
11
+
12
+ # Thumbnails
13
+ ._*
14
+
15
+ # Files that might appear on external disk
16
+ .Spotlight-V100
17
+ .Trashes
18
+
19
+ # Directories potentially created on remote AFP share
20
+ .AppleDB
21
+ .AppleDesktop
22
+ Network Trash Folder
23
+ Temporary Items
24
+ .apdisk
25
+
26
+
27
+ ### Windows ###
28
+ # Windows image file caches
29
+ Thumbs.db
30
+ ehthumbs.db
31
+
32
+ # Folder config file
33
+ Desktop.ini
34
+
35
+ # Recycle Bin used on file shares
36
+ $RECYCLE.BIN/
37
+
38
+ # Windows Installer files
39
+ *.cab
40
+ *.msi
41
+ *.msm
42
+ *.msp
43
+
44
+ # Windows shortcuts
45
+ *.lnk
46
+
47
+
48
+ ### Linux ###
49
+ *~
50
+
51
+ # KDE directory preferences
52
+ .directory
53
+
54
+
55
+ ### Vagrant ###
56
+ .vagrant/
57
+
58
+
59
+ ### Packer ###
60
+ # Cache objects
61
+ packer_cache/
62
+
63
+ # For built boxes
64
+ *.box
65
+
66
+
67
+ ### TextMate ###
68
+ *.tmproj
69
+ *.tmproject
70
+ tmtags
71
+ tmtagsHistory
72
+
73
+ ### SublimeText ###
74
+ # workspace files are user-specific
75
+ *.sublime-workspace
76
+
77
+ # project files should be checked into the repository, unless a significant
78
+ # proportion of contributors will probably not be using SublimeText
79
+ # *.sublime-project
80
+
81
+ #sftp configuration file
82
+ sftp-config.json
83
+
84
+
85
+ ### vim ###
86
+ [._]*.s[a-w][a-z]
87
+ [._]s[a-w][a-z]
88
+ *.un~
89
+ Session.vim
90
+ .netrwhist
91
+ *~
92
+
93
+
94
+ ### Emacs ###
95
+ # -*- mode: gitignore; -*-
96
+ *~
97
+ \#*\#
98
+ /.emacs.desktop
99
+ /.emacs.desktop.lock
100
+ *.elc
101
+ auto-save-list
102
+ tramp
103
+ .\#*
104
+
105
+ # Org-mode
106
+ .org-id-locations
107
+ *_archive
108
+
109
+ # flymake-mode
110
+ *_flymake.*
111
+
112
+ # eshell files
113
+ /eshell/history
114
+ /eshell/lastdir
115
+
116
+ # elpa packages
117
+ /elpa/
118
+
119
+ # reftex files
120
+ *.rel
121
+
122
+ # AUCTeX auto folder
123
+ /auto/
124
+
125
+
126
+ ### ChefCookbook ###
127
+ .vagrant
128
+ /cookbooks
129
+
130
+ # Bundler
131
+ bin/*
132
+ .bundle/*
133
+
134
+ .kitchen/
135
+ .kitchen.local.yml
136
+ .chef-runner/
137
+
138
+
139
+ ### Ruby ###
140
+ *.gem
141
+ *.rbc
142
+ /.config
143
+ /coverage/
144
+ /InstalledFiles
145
+ /pkg/
146
+ /spec/reports/
147
+ /test/tmp/
148
+ /test/version_tmp/
149
+ /tmp/
150
+
151
+ ## Specific to RubyMotion:
152
+ .dat*
153
+ .repl_history
154
+ build/
155
+
156
+ ## Documentation cache and generated files:
157
+ /.yardoc/
158
+ /_yardoc/
159
+ /doc/
160
+ /rdoc/
161
+
162
+ ## Environment normalisation:
163
+ /.bundle/
164
+ /lib/bundler/man/
165
+
166
+ # for a library or gem, you might want to ignore these files since the code is
167
+ # intended to run in multiple environments; otherwise, check them in:
168
+ # Gemfile.lock
169
+ # .ruby-version
170
+ # .ruby-gemset
171
+
172
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
173
+ .rvmrc
174
+
175
+
176
+ ### Tags ###
177
+ # Ignore tags created by etags, ctags, gtags (GNU global) and cscope
178
+ TAGS
179
+ !TAGS/
180
+ tags
181
+ !tags/
182
+ gtags.files
183
+ GTAGS
184
+ GRTAGS
185
+ GPATH
186
+ cscope.files
187
+ cscope.out
188
+ cscope.in.out
189
+ cscope.po.out
190
+ .bundle
191
+ vendor/bundle
192
+ vendor/cache
193
+ Gemfile.lock
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
-
data/Rakefile CHANGED
@@ -13,4 +13,3 @@ RuboCop::RakeTask.new(:rubocop) do |task|
13
13
  end
14
14
 
15
15
  task default: [:spec, :rubocop, :build, :install]
16
-
data/hoodie.gemspec CHANGED
@@ -1,16 +1,16 @@
1
1
  # encoding: utf-8
2
2
  lib = File.expand_path('../lib/', __FILE__)
3
- $:.unshift lib unless $:.include?(lib)
3
+ $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
4
4
 
5
- require "hoodie/version"
5
+ require 'hoodie/version'
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = 'hoodie'
9
9
  s.version = Hoodie::VERSION
10
10
  s.platform = Gem::Platform::RUBY
11
- s.date = Time.now.strftime("%Y-%m-%d")
11
+ s.date = Time.now.strftime('%Y-%m-%d')
12
12
  s.summary = 'Pragmatic hoodie concurrency hipster with ruby'
13
- s.description = "A collection of hipster methods and hoodie tools to make even the nerdy rubyist look cool"
13
+ s.description = 'A collection of hipster methods and hoodie tools to make even the nerdy rubyist look cool'
14
14
  s.authors = ['Stefano Harding']
15
15
  s.email = 'riddopic@gmail.com'
16
16
  s.homepage = 'https://github.com/riddopic/hoodie'
@@ -19,12 +19,13 @@ Gem::Specification.new do |s|
19
19
  s.files = `git ls-files`.split
20
20
  s.test_files = `git ls-files spec/*`.split
21
21
 
22
- s.add_dependency('anemone', [">= 0.7.2"])
22
+ s.add_runtime_dependency 'anemone', '>= 0.7.2'
23
+ s.add_runtime_dependency 'hitimes'
23
24
 
24
- s.add_development_dependency 'rubocop', '~> 0.26.0'
25
- s.add_development_dependency 'rake', '~> 10.3.2'
25
+ s.add_development_dependency 'rubocop', '~> 0.26.0'
26
+ s.add_development_dependency 'rake', '~> 10.3.2'
26
27
  s.add_development_dependency 'coveralls', '~> 0.7.1'
27
- s.add_development_dependency 'rspec', '~> 3.1.0'
28
- s.add_development_dependency 'fuubar', '~> 2.0.0'
29
- s.add_development_dependency 'timecop', '~> 0.7.1'
28
+ s.add_development_dependency 'rspec', '~> 3.1.0'
29
+ s.add_development_dependency 'fuubar', '~> 2.0.0'
30
+ s.add_development_dependency 'timecop', '~> 0.7.1'
30
31
  end
data/lib/hoodie/hash.rb CHANGED
@@ -137,7 +137,7 @@ class Hash
137
137
  end
138
138
 
139
139
  def recursive_merge(other)
140
- hash = self.dup
140
+ hash = dup
141
141
  other.each do |key, value|
142
142
  myval = self[key]
143
143
  if value.is_a?(Hash) && myval.is_a?(Hash)
@@ -0,0 +1,94 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ #
5
+ # Copyright (C) 2014 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
+ # implied. See the License for the specific language governing
17
+ # permissions and limitations under the License.
18
+ #
19
+
20
+ module Hoodie::IdentityMap
21
+ def self.enabled=(flag)
22
+ Thread.current[:identity_map_enabled] = flag
23
+ end
24
+
25
+ def self.enabled
26
+ Thread.current[:identity_map_enabled]
27
+ end
28
+
29
+ def self.enabled?
30
+ enabled == true
31
+ end
32
+
33
+ def self.repository
34
+ Thread.current[:identity_map] ||= {}
35
+ end
36
+
37
+ def self.clear
38
+ repository.clear
39
+ end
40
+
41
+ def self.include?(object)
42
+ repository.keys.include?(object.id)
43
+ end
44
+
45
+ def self.use
46
+ old, self.enabled = enabled, true
47
+ yield if block_given?
48
+ ensure
49
+ self.enabled = old
50
+ clear
51
+ end
52
+
53
+ def self.without
54
+ old, self.enabled = enabled, false
55
+ yield if block_given?
56
+ ensure
57
+ self.enabled = old
58
+ end
59
+
60
+ module ClassMethods
61
+ def get(id, options = nil)
62
+ get_from_identity_map(id) || super
63
+ end
64
+
65
+ def get_from_identity_map(id)
66
+ IdentityMap.repository[id] if IdentityMap.enabled?
67
+ end
68
+ private :get_from_identity_map
69
+
70
+ def load(id, attrs)
71
+ if IdentityMap.enabled? && instance = IdentityMap.repository[id]
72
+ instance
73
+ else
74
+ super.tap { |doc| doc.add_to_identity_map }
75
+ end
76
+ end
77
+ end
78
+
79
+ def save(options={})
80
+ super.tap { |result| add_to_identity_map if result }
81
+ end
82
+
83
+ def delete
84
+ super.tap { remove_from_identity_map }
85
+ end
86
+
87
+ def add_to_identity_map
88
+ IdentityMap.repository[id] = self if IdentityMap.enabled?
89
+ end
90
+
91
+ def remove_from_identity_map
92
+ IdentityMap.repository.delete(id) if IdentityMap.enabled?
93
+ end
94
+ end
@@ -23,7 +23,6 @@ require 'hoodie/stash' unless defined?(Stash)
23
23
  # method so it doesn't need to be re-computed every time that method
24
24
  # is called.
25
25
  module Memoizable
26
-
27
26
  # Create a new memoized method. To use, extend class with Memoizable,
28
27
  # then, in initialize, call memoize
29
28
  #
@@ -23,7 +23,7 @@ module Hoodie
23
23
  INCOMPREHENSIBLE_ERROR = nil
24
24
  rescue LoadError => err
25
25
  raise unless err.to_s.include?('openssl')
26
- warn "Oea pieoYreb h wYoerh dl hwsnhoib r Lrbea tbte wbnaetvoouahe h rbe."
26
+ warn 'Oea pieoYreb h wYoerh dl hwsnhoib r Lrbea tbte wbnaetvoouahe h rbe.'
27
27
  warn "olorbvtelYShnSben irrSwoet eto eihSrLoS'do n See wLiape."
28
28
  INCOMPREHENSIBLE_ERROR = err
29
29
  end
@@ -38,7 +38,7 @@ module Hoodie
38
38
 
39
39
  def self.check_platform_can_discombobulate!
40
40
  return true unless INCOMPREHENSIBLE_ERROR
41
- raise INCOMPREHENSIBLE_ERROR.class, "b0rked! #{INCOMPREHENSIBLE_ERROR}"
41
+ fail INCOMPREHENSIBLE_ERROR.class, "b0rked! #{INCOMPREHENSIBLE_ERROR}"
42
42
  end
43
43
 
44
44
  # Befuddle the given string
@@ -49,7 +49,7 @@ module Hoodie
49
49
  # @return [String] befuddleed text, suitable for deciphering with
50
50
  # Obfuscate#enlighten (decrypt)
51
51
  #
52
- def self.befuddle plaintext, befuddle_pass, options = {}
52
+ def self.befuddle(plaintext, befuddle_pass, options = {})
53
53
  cipher = new_cipher :befuddle, befuddle_pass, options
54
54
  cipher.iv = iv = cipher.random_iv
55
55
  ciphertext = cipher.update(plaintext)
@@ -65,7 +65,7 @@ module Hoodie
65
65
  #
66
66
  # @return [String] the enlightened plaintext
67
67
  #
68
- def self.enlighten enc_ciphertext, befuddle_pass, options = {}
68
+ def self.enlighten(enc_ciphertext, befuddle_pass, options = {})
69
69
  iv_and_ciphertext = Base64.decode64(enc_ciphertext)
70
70
  cipher = new_cipher :enlighten, befuddle_pass, options
71
71
  cipher.iv, ciphertext = separate_iv_and_ciphertext(cipher, iv_and_ciphertext)
@@ -74,7 +74,7 @@ module Hoodie
74
74
  plaintext
75
75
  end
76
76
 
77
- private # P R O P R I E T À P R I V A T A divieto di accesso
77
+ protected # A T T E N Z I O N E A R E A P R O T E T T A
78
78
 
79
79
  # Cipher create machine do, befuddle engage, enlighten. Dials set
80
80
  # direction to infinity
@@ -82,7 +82,7 @@ module Hoodie
82
82
  # @param [:befuddle, :enlighten] to befuddle or enlighten
83
83
  # @param [String] befuddle_pass secret sauce to enlighten with
84
84
  #
85
- def self.new_cipher direction, befuddle_pass, options = {}
85
+ def self.new_cipher(direction, befuddle_pass, options = {})
86
86
  check_platform_can_discombobulate!
87
87
  cipher = OpenSSL::Cipher::Cipher.new(ESOTERIC_TYPE)
88
88
  case direction
@@ -90,30 +90,30 @@ module Hoodie
90
90
  cipher.encrypt
91
91
  when :enlighten
92
92
  cipher.decrypt
93
- else raise "Bad cipher direction #{direction}"
93
+ else fail "Bad cipher direction #{direction}"
94
94
  end
95
95
  cipher.key = befuddle_key(befuddle_pass, options)
96
96
  cipher
97
97
  end
98
98
 
99
99
  # vector inspect encoder serialize prepend initialization message
100
- def self.combine_iv_and_ciphertext iv, message
101
- message.force_encoding("BINARY") if message.respond_to?(:force_encoding)
102
- iv.force_encoding("BINARY") if iv.respond_to?(:force_encoding)
100
+ def self.combine_iv_and_ciphertext(iv, message)
101
+ message.force_encoding('BINARY') if message.respond_to?(:force_encoding)
102
+ iv.force_encoding('BINARY') if iv.respond_to?(:force_encoding)
103
103
  iv + message
104
104
  end
105
105
 
106
106
  # front vector initialization, encoded pull message
107
- def self.separate_iv_and_ciphertext cipher, iv_and_ciphertext
107
+ def self.separate_iv_and_ciphertext(cipher, iv_and_ciphertext)
108
108
  idx = cipher.iv_len
109
- [ iv_and_ciphertext[0..(idx-1)], iv_and_ciphertext[idx..-1] ]
109
+ [iv_and_ciphertext[0..(idx - 1)], iv_and_ciphertext[idx..-1]]
110
110
  end
111
111
 
112
112
  # Convert the befuddle_pass passphrase into the key used for
113
113
  # befuddletion
114
- def self.befuddle_key befuddle_pass, options={}
114
+ def self.befuddle_key(befuddle_pass, _options = {})
115
115
  befuddle_pass = befuddle_pass.to_s
116
- raise 'Missing befuddled password!' if befuddle_pass.empty?
116
+ fail 'Missing befuddled password!' if befuddle_pass.empty?
117
117
  # 256 beers on the wall, keys for cipher required of aes cbc
118
118
  Digest::SHA256.digest(befuddle_pass)
119
119
  end
data/lib/hoodie/rash.rb CHANGED
@@ -103,7 +103,7 @@ module Anemone
103
103
  key = ::File.basename(file, '.*').downcase.to_sym
104
104
  type = ::File.extname(file)[1..-1].downcase.to_sym
105
105
  id = Hoodie::Obfuscate.befuddle(file, Digest::MD5.hexdigest(body.to_s))
106
- utime = Time::now.to_i
106
+ utime = Time.now.to_i
107
107
  key = { key => { type => {
108
108
  id: id,
109
109
  file: file,
@@ -119,7 +119,7 @@ module Anemone
119
119
  utime: utime,
120
120
  md5_digest: Digest::MD5.hexdigest(body.to_s),
121
121
  sha256_digest: Digest::SHA256.hexdigest(body.to_s)
122
- }}}
122
+ } } }
123
123
  end
124
124
  end
125
125
  end
@@ -20,9 +20,9 @@
20
20
  require 'tmpdir'
21
21
 
22
22
  module DiskStash
23
- # Disk stashing method variable caching hash, string, array store.
24
- class Cache
25
- include Enumerable
23
+ # Disk stashing method variable caching hash, string, array store.
24
+ class Cache
25
+ include Enumerable
26
26
 
27
27
  # @return [String] location of DiskStash::Cache.store
28
28
  #
@@ -35,29 +35,29 @@ module DiskStash
35
35
  # @return nothing.
36
36
  #
37
37
  def initialize(store = file_store)
38
- @store = store
38
+ @store = store
39
39
  _ensure_store_directory
40
40
  end
41
41
 
42
- # Clear the whole stash or the value of a key
43
- #
44
- # @param key [Symbol, String] (optional) string or symbol
42
+ # Clear the whole stash or the value of a key
43
+ #
44
+ # @param key [Symbol, String] (optional) string or symbol
45
45
  # representing the key to clear
46
- #
47
- # @return [Hash] with a key, return the value it had, without
46
+ #
47
+ # @return [Hash] with a key, return the value it had, without
48
48
  # returns {}
49
- #
49
+ #
50
50
  def clear!(key = nil)
51
51
  if key.nil?
52
52
  ::Dir[::File.join(store, '*.cache')].each do |file|
53
53
  ::File.delete(file)
54
54
  end
55
55
  else
56
- ::File.delete(cache_file(key)) if ::File.exists?(cache_file(key))
56
+ ::File.delete(cache_file(key)) if ::File.exist?(cache_file(key))
57
57
  end
58
58
  end
59
59
 
60
- # Retrieves the value for a given key, if nothing is set,
60
+ # Retrieves the value for a given key, if nothing is set,
61
61
  # returns nil
62
62
  #
63
63
  # @param key [Symbol, String] representing the key
@@ -68,11 +68,11 @@ module DiskStash
68
68
  if key.is_a? Array
69
69
  hash = {}
70
70
  key.each do |k|
71
- hash[k] = Marshal::load(_read_cache_file(k))
71
+ hash[k] = Marshal.load(_read_cache_file(k))
72
72
  end
73
73
  hash unless hash.empty?
74
74
  else
75
- Marshal::load(_read_cache_file(key))
75
+ Marshal.load(_read_cache_file(key))
76
76
  end
77
77
  rescue Errno::ENOENT
78
78
  nil # key hasn't been created
@@ -89,15 +89,15 @@ module DiskStash
89
89
  # @return nothing.
90
90
  #
91
91
  def []=(key, value)
92
- _write_cache_file(key, Marshal::dump(value))
92
+ _write_cache_file(key, Marshal.dump(value))
93
93
  end
94
94
 
95
- # returns path to cache file with 'key'
96
- def cache_file key
97
- ::File.join(store, key.to_s + '.cache')
98
- end
95
+ # returns path to cache file with 'key'
96
+ def cache_file(key)
97
+ ::File.join(store, key.to_s + '.cache')
98
+ end
99
99
 
100
- private # P R O P R I E T À P R I V A T A divieto di accesso
100
+ private # P R O P R I E T À P R I V A T A divieto di accesso
101
101
 
102
102
  # return Chef tmpfile path if running under Chef, else return OS
103
103
  # temp path. On Winders Dir.tmpdir returns the correct path.
@@ -114,7 +114,7 @@ module DiskStash
114
114
  # backslashes are used everywhere
115
115
  #
116
116
  def win_friendly_path(path)
117
- system_drive = ENV['SYSTEMDRIVE'] ? ENV['SYSTEMDRIVE'] : ""
117
+ system_drive = ENV['SYSTEMDRIVE'] ? ENV['SYSTEMDRIVE'] : ''
118
118
  path = ::File.join(system_drive, path)
119
119
  path.gsub!(::File::SEPARATOR, (::File::ALT_SEPARATOR || '\\'))
120
120
  end
@@ -130,20 +130,20 @@ module DiskStash
130
130
 
131
131
  def _read_cache_file(key)
132
132
  mode = OS.windows? ? 'rb' : 'r'
133
- f = ::File.open(cache_file(key), mode)
134
- f.flock(::File::LOCK_SH)
135
- out = f.read
136
- f.close
137
- out
133
+ f = ::File.open(cache_file(key), mode)
134
+ f.flock(::File::LOCK_SH)
135
+ out = f.read
136
+ f.close
137
+ out
138
138
  end
139
139
 
140
- def read_cache_mtime(key)
141
- nil unless ::File.exists?(cache_file(key))
142
- ::File.mtime(cache_file(key))
143
- end
140
+ def read_cache_mtime(key)
141
+ nil unless ::File.exist?(cache_file(key))
142
+ ::File.mtime(cache_file(key))
143
+ end
144
144
 
145
- def _ensure_store_directory
146
- ::Dir.mkdir(store) unless ::File.directory?(store)
147
- end
148
- end
145
+ def _ensure_store_directory
146
+ ::Dir.mkdir(store) unless ::File.directory?(store)
147
+ end
148
+ end
149
149
  end
@@ -94,7 +94,7 @@ module MemStash
94
94
  #
95
95
  # @yield the string key and value.
96
96
  #
97
- def each(&block)
97
+ def each(&_block)
98
98
  @store.each { |k, v| yield(k, v) }
99
99
  end
100
100
 
data/lib/hoodie/stash.rb CHANGED
@@ -23,7 +23,6 @@ require 'hoodie/memoizable' unless defined?(Memoizable)
23
23
 
24
24
  # Define the basic cache and default store objects
25
25
  module Stash
26
-
27
26
  # check if we're using a version if Ruby that supports caller_locations
28
27
  NEW_CALL = Kernel.respond_to? 'caller_locations'
29
28