attic 1.0.0.pre.RC2 → 1.0.0.pre.RC3
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 +4 -4
- data/attic.gemspec +1 -1
- data/lib/attic/class_methods.rb +2 -0
- data/lib/attic/instance_methods.rb +29 -2
- data/lib/attic.rb +18 -8
- data/try/20_accessing_tryouts.rb +9 -8
- data/try/25_string_tryouts.rb +6 -6
- data/try/30_nometaclass_tryouts.rb +8 -0
- metadata +1 -2
- data/lib/attic/core_ext.rb +0 -70
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd963a291df8b9b731adac87c5886f9f25b83606c7a171347d0e6e8396c98533
|
4
|
+
data.tar.gz: '0113974e4554b99b6061005f7d0218398592384d7bcd85f2fe4899b0d51232e9'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92fcb090695086fcfa85472d69f8f2631054c035c99f3024f7cebc67b730e418c6ed650f2c8042f4c6882e6782c1febea6fc73768c43258e6e84d28d6219c149
|
7
|
+
data.tar.gz: a22f7131a2aca63c30bde0546c3ad0fdf77ef095b3d2cd5ed23853da02b314535c26771a900df059de056a76e32d50ad5e4802eab943736e9b423719ad036731
|
data/attic.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "attic"
|
3
|
-
s.version = "1.0.0-
|
3
|
+
s.version = "1.0.0-RC3"
|
4
4
|
s.summary = "When in doubt, store it in the attic"
|
5
5
|
s.description = "Attic: a place to hide metadata about the class or variable itself (e.g. SHA hash summaries)."
|
6
6
|
s.authors = ["Delano Mandelbaum"]
|
data/lib/attic/class_methods.rb
CHANGED
@@ -8,12 +8,39 @@ module Attic
|
|
8
8
|
module InstanceMethods
|
9
9
|
|
10
10
|
def attic
|
11
|
-
raise
|
11
|
+
raise NoSingletonError, self, caller unless attic?
|
12
12
|
|
13
13
|
singleton_class
|
14
14
|
|
15
15
|
rescue TypeError
|
16
|
-
|
16
|
+
NoSingletonError.add_member self
|
17
|
+
end
|
18
|
+
|
19
|
+
# A quick way to check if this object instance already has a
|
20
|
+
# dedicated singleton class. We like to know this upfront
|
21
|
+
# because this is where our attic variables are to be stored.
|
22
|
+
def attic?
|
23
|
+
return false if NoSingletonError.member? self
|
24
|
+
|
25
|
+
# NOTE: Calling this on an object for the first time lazily
|
26
|
+
# creates a singleton class for itself. Another way of doing
|
27
|
+
# the same thing is to attempt defining a singleton method
|
28
|
+
# for the object. In either case, objects that cannot have
|
29
|
+
# cannot have a dedicated singleton class (e.g. nil, true,
|
30
|
+
# false) will raise a TypeError. We rescue this and add the
|
31
|
+
# object to the NoSingletonError list so we don't keep
|
32
|
+
# trying to access its singleton class over and over.
|
33
|
+
#
|
34
|
+
# NOTE 2: Module#singleton_class? is only available for
|
35
|
+
# modules and classes (which are also modules); it is not
|
36
|
+
# available for instances of classes.
|
37
|
+
#
|
38
|
+
!singleton_class.nil?
|
39
|
+
|
40
|
+
rescue TypeError
|
41
|
+
# Remember for next time.
|
42
|
+
NoSingletonError.add_member self
|
43
|
+
false
|
17
44
|
end
|
18
45
|
|
19
46
|
def attic_variables
|
data/lib/attic.rb
CHANGED
@@ -100,7 +100,7 @@ require_relative "attic/instance_methods"
|
|
100
100
|
# nil.attic.object_id #=> 800
|
101
101
|
#
|
102
102
|
module Attic
|
103
|
-
VERSION = '0.
|
103
|
+
VERSION = '1.0.0-RC3'.freeze unless defined?(VERSION)
|
104
104
|
|
105
105
|
# A convenince method at the class level for including
|
106
106
|
# ConstructMethods in the given object specifically.
|
@@ -146,20 +146,20 @@ module Attic
|
|
146
146
|
attic_vars = self.attic_variables.clone
|
147
147
|
klass.attic.instance_variable_set("@attic_variables", attic_vars)
|
148
148
|
end
|
149
|
-
if method_defined? :instance_variables
|
150
|
-
instance_variables_orig = instance_method(:instance_variables)
|
151
|
-
define_method :instance_variables do
|
152
|
-
ret =
|
149
|
+
if obj.method_defined? :instance_variables
|
150
|
+
instance_variables_orig = obj.instance_method(:instance_variables)
|
151
|
+
obj.define_method :instance_variables do
|
152
|
+
ret = instance_variables_orig.bind(self).call.clone
|
153
153
|
ret.reject! { |v| v.to_s =~ /^@___?attic/ } # match 2 or 3 underscores
|
154
154
|
ret
|
155
155
|
end
|
156
|
-
define_method :all_instance_variables do
|
157
|
-
|
156
|
+
obj.define_method :all_instance_variables do
|
157
|
+
instance_variables_orig.bind(self).call
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
161
|
rescue TypeError => e
|
162
|
-
raise
|
162
|
+
raise NoSingletonError, obj, caller
|
163
163
|
end
|
164
164
|
|
165
165
|
# A class method for defining variables to store in the attic.
|
@@ -203,6 +203,16 @@ module Attic
|
|
203
203
|
attic_variables # only after defining new attic vars
|
204
204
|
end
|
205
205
|
|
206
|
+
def attic?
|
207
|
+
return false if NoSingletonError.member? self
|
208
|
+
|
209
|
+
singleton_class?
|
210
|
+
|
211
|
+
rescue TypeError
|
212
|
+
NoSingletonError.add_member self
|
213
|
+
false
|
214
|
+
end
|
215
|
+
|
206
216
|
# Returns an Array of attic variables for the current class.
|
207
217
|
# e.g.
|
208
218
|
#
|
data/try/20_accessing_tryouts.rb
CHANGED
@@ -1,29 +1,30 @@
|
|
1
|
-
|
1
|
+
require_relative '../lib/attic'
|
2
|
+
|
2
3
|
class ::Worker
|
3
4
|
extend Attic
|
4
5
|
attic :size
|
5
6
|
end
|
6
7
|
|
7
|
-
|
8
|
+
|
8
9
|
## save an instance variable the long way
|
9
10
|
w = Worker.new
|
10
|
-
w.
|
11
|
-
w.
|
11
|
+
w.attic.instance_variable_set '@mattress', 'S&F'
|
12
|
+
w.attic.instance_variable_get '@mattress'
|
12
13
|
#=> 'S&F'
|
13
|
-
|
14
|
+
|
14
15
|
## save an instance variable the short way
|
15
16
|
w = Worker.new
|
16
17
|
w.size = :california_king
|
17
18
|
w.size
|
18
19
|
#=> :california_king
|
19
|
-
|
20
|
+
|
20
21
|
## new instances don't cross streams
|
21
22
|
w = Worker.new
|
22
23
|
w.size
|
23
24
|
#=> nil
|
24
|
-
|
25
|
+
|
25
26
|
## instance variables are hidden
|
26
27
|
w = Worker.new
|
27
|
-
w.
|
28
|
+
w.attic.instance_variable_set '@mattress', 'S&F'
|
28
29
|
w.instance_variables
|
29
30
|
## []
|
data/try/25_string_tryouts.rb
CHANGED
@@ -4,25 +4,25 @@ require 'attic'
|
|
4
4
|
String.extend Attic
|
5
5
|
String.respond_to? :attic
|
6
6
|
#=> true
|
7
|
-
|
7
|
+
|
8
8
|
## save an instance variable the long way
|
9
9
|
s = ""
|
10
|
-
s.
|
11
|
-
s.
|
10
|
+
s.attic.instance_variable_set '@mattress', 'S&F'
|
11
|
+
s.attic.instance_variable_get '@mattress'
|
12
12
|
#=> 'S&F'
|
13
13
|
|
14
14
|
## can create attributes
|
15
15
|
String.attic :goodies
|
16
16
|
#=> [:goodies]
|
17
|
-
|
17
|
+
|
18
18
|
## save an instance variable the short way
|
19
19
|
s = ""
|
20
20
|
s.goodies = :california_king
|
21
21
|
p s.instance_variables
|
22
|
-
p s.
|
22
|
+
p s.attic_variables
|
23
23
|
s.goodies
|
24
24
|
#=> :california_king
|
25
|
-
|
25
|
+
|
26
26
|
## String instances don't cross streams
|
27
27
|
String.extend Attic
|
28
28
|
String.attic :name
|
@@ -39,6 +39,14 @@ Symbol.extend Attic
|
|
39
39
|
:any.attic?
|
40
40
|
#=> false
|
41
41
|
|
42
|
+
## A String's attic vars appear in `all_instance_variables` do
|
43
|
+
String.extend Attic
|
44
|
+
String.attic :_name
|
45
|
+
a, b = 'String1', 'String2'
|
46
|
+
a._name = :roger
|
47
|
+
a.all_instance_variables
|
48
|
+
#=> [:@___attic_name]
|
49
|
+
|
42
50
|
## A Symbol's attic vars appear in `all_instance_variables` do
|
43
51
|
Symbol.extend Attic
|
44
52
|
Symbol.attic :_name
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.
|
4
|
+
version: 1.0.0.pre.RC3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -69,7 +69,6 @@ files:
|
|
69
69
|
- attic.gemspec
|
70
70
|
- lib/attic.rb
|
71
71
|
- lib/attic/class_methods.rb
|
72
|
-
- lib/attic/core_ext.rb
|
73
72
|
- lib/attic/errors.rb
|
74
73
|
- lib/attic/instance_methods.rb
|
75
74
|
- try/01_mixins_tryouts.rb
|
data/lib/attic/core_ext.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
|
2
|
-
class NoMetaClass < RuntimeError
|
3
|
-
end
|
4
|
-
|
5
|
-
# = Object
|
6
|
-
#
|
7
|
-
# These methods are copied directly from _why's metaid.rb.
|
8
|
-
# See: http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
|
9
|
-
class Object
|
10
|
-
|
11
|
-
unless defined?(::Object::NOMETACLASS)
|
12
|
-
# An Array of classes which do not have metaclasses.
|
13
|
-
NOMETACLASS = [Symbol, Integer].freeze
|
14
|
-
end
|
15
|
-
|
16
|
-
def nometaclass?
|
17
|
-
NOMETACLASS.member?(self)
|
18
|
-
end
|
19
|
-
|
20
|
-
def metaclass?
|
21
|
-
!NOMETACLASS.member?(self.class)
|
22
|
-
end
|
23
|
-
|
24
|
-
# A convenient method for getting the metaclass of the current object.
|
25
|
-
# i.e.
|
26
|
-
#
|
27
|
-
# class << self; self; end;
|
28
|
-
#
|
29
|
-
# NOTE: Some Ruby class do not have meta classes (see: NOMETACLASS).
|
30
|
-
# For these classes, this method returns the class itself. That means
|
31
|
-
# the instance variables will stored in the class itself.
|
32
|
-
def metaclass
|
33
|
-
if !self.metaclass?
|
34
|
-
raise NoMetaClass, self
|
35
|
-
else
|
36
|
-
class << self; self; end;
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# Execute a block +&blk+ within the metaclass of the current object.
|
41
|
-
def meta_eval &blk; metaclass.instance_eval &blk; end
|
42
|
-
|
43
|
-
# Add an instance method called +name+ to metaclass for the current object.
|
44
|
-
# This is useful because it will be available as a singleton method
|
45
|
-
# to all subclasses too.
|
46
|
-
def meta_def name, &blk
|
47
|
-
meta_eval { define_method name, &blk }
|
48
|
-
end
|
49
|
-
|
50
|
-
# Add a class method called +name+ for the current object's class. This
|
51
|
-
# isn't so special but it maintains consistency with meta_def.
|
52
|
-
def class_def name, &blk
|
53
|
-
class_eval { define_method name, &blk }
|
54
|
-
end
|
55
|
-
|
56
|
-
|
57
|
-
# A convenient method for getting the metaclass of the metaclass
|
58
|
-
# i.e.
|
59
|
-
#
|
60
|
-
# self.metaclass.metaclass
|
61
|
-
#
|
62
|
-
def metametaclass; self.metaclass.metaclass; end
|
63
|
-
|
64
|
-
def metameta_eval &blk; metametaclass.instance_eval &blk; end
|
65
|
-
|
66
|
-
def metameta_def name, &blk
|
67
|
-
metameta_eval { define_method name, &blk }
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|