attic 1.0.0.pre.RC2 → 1.0.0.pre.RC3

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
  SHA256:
3
- metadata.gz: 65eaa51d7ee74a1e97bef40a3cdb0c6cb8c78ca29e0cd8f8bb55e0cba641f664
4
- data.tar.gz: fbc75d2a1063522b54edfc6d608a2f4599ac2b34c39a92aa400b138138f19cd8
3
+ metadata.gz: cd963a291df8b9b731adac87c5886f9f25b83606c7a171347d0e6e8396c98533
4
+ data.tar.gz: '0113974e4554b99b6061005f7d0218398592384d7bcd85f2fe4899b0d51232e9'
5
5
  SHA512:
6
- metadata.gz: 2a54f4d47b2aa70d9a8d6ee30578d5c06360e9e5c2ffd3c5dfa196086b40122dfee3d84b079cbabd9a24076262b8d8b4521d50a649fe111c3f8f3b80d20945da
7
- data.tar.gz: b06ab0a4a824c1536046f4d36ee0a42ce0e5315e214ef398955cf45f7046c56937d93333102044a1a4607fbe4780dd176d0377569126320e81f623c220527c16
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-RC2"
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"]
@@ -40,6 +40,8 @@ module Attic
40
40
 
41
41
  safe_name = "@_attic_#{name}"
42
42
  instance_variable_set(safe_name, name)
43
+ rescue TypeError => e
44
+ raise NoSingletonError, name, caller
43
45
  end
44
46
 
45
47
  def attic_variable?(name)
@@ -8,12 +8,39 @@ module Attic
8
8
  module InstanceMethods
9
9
 
10
10
  def attic
11
- raise NoSingleton, self, caller unless attic?
11
+ raise NoSingletonError, self, caller unless attic?
12
12
 
13
13
  singleton_class
14
14
 
15
15
  rescue TypeError
16
- NoSingleton.add_member self
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.9.0-RC1'.freeze unless defined?(VERSION)
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 = _instance_variables_orig.bind(self).call.clone
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
- _instance_variables_orig.bind(self).call
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 NoSingleton, obj, caller
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
  #
@@ -1,29 +1,30 @@
1
- require 'attic'
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.metametaclass.instance_variable_set '@mattress', 'S&F'
11
- w.metametaclass.instance_variable_get '@mattress'
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.metametaclass.instance_variable_set '@mattress', 'S&F'
28
+ w.attic.instance_variable_set '@mattress', 'S&F'
28
29
  w.instance_variables
29
30
  ## []
@@ -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.metametaclass.instance_variable_set '@mattress', 'S&F'
11
- s.metametaclass.instance_variable_get '@mattress'
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.attic_vars
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.RC2
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
@@ -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