instance 0.1.0 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cee2d02baf52220acdc856e29882e4f010ba2738
4
- data.tar.gz: 431b52894e0f05ed07f01a659a32dfee9afd46d5
3
+ metadata.gz: 50ea7131aae9fc777b3fbb1627ad12921c8f030a
4
+ data.tar.gz: 333c9c0a0c3b5621826573b6cbd8f79a1f12c93c
5
5
  SHA512:
6
- metadata.gz: 6db8dc0db1016e250ef002411b651027c934e627baf1feb292e1846c412897b35b975cad3de8a993a7f7c8b746dfa132d45d5e409c1e267e525851f02c86c35e
7
- data.tar.gz: 36957724377899c20c5e5e604444b8e3da459522fea4c9154ec1781c89174354912e653a9a8848d3e464431c899e841b6b8ba188c284796cbae199ca3f379a49
6
+ metadata.gz: 1656a2cacca66158e402d560a522e0e1ecf39cc37f749955637584eb9dd10b4a398755219535551732dcc77c358534cd023ec843eccf5f121030c73b27c0938c
7
+ data.tar.gz: 1aa585e6ae04ea595d0525a7750b6765e9b792a081c26811ffe65cf3dc54a5cd3f24e09d79210e0808e9592b315b68c7f6b8f9e77ecf281225d2a41fc34266b3
data/.index CHANGED
@@ -58,5 +58,5 @@ created: '2014-01-31'
58
58
  description: |-
59
59
  Instance is a spin-off of Ruby Facets. It provides a simple convenient API
60
60
  for accessing an object's state.
61
- version: 0.1.0
62
- date: '2014-02-01'
61
+ version: 0.2.0
62
+ date: '2014-02-02'
data/HISTORY.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # RELEASE HISTORY
2
2
 
3
+ ## 0.2.0 | 2014-02-02
4
+
5
+ This release adds an extra set of methods for modules and classes.
6
+
7
+ Changes:
8
+
9
+ * Add `method_definition` if object is a module or class.
10
+ * Add `method_definitions` if object is a module or class.
11
+
12
+
3
13
  ## 0.1.0 | 2014-02-01
4
14
 
5
15
  This is the initial release of Instance, a class spun-off from
data/README.md CHANGED
@@ -24,28 +24,33 @@ Let's use a very simple example class with which to demonstrate usage.
24
24
  ```ruby
25
25
  class Song
26
26
  attr_accessor :title
27
- attr_accessor :author
27
+ attr_accessor :artist
28
28
  attr_accessor :length
29
29
 
30
- def initialize(title, author, length)
30
+ def initialize(title, artist, length)
31
31
  @title = title
32
- @author = author
33
- @length = length
32
+ @artist = artist
33
+ @year = year
34
34
  end
35
35
  end
36
36
  ```
37
37
 
38
+ Now we can create an instance of Song and work with it's state.
39
+
38
40
  ```ruby
39
41
  song = Song.new("Paranoid", "Black Sabbath", 1970)
40
42
 
41
- song.instance.variables #=> [:@author, :@title, :@length]
43
+ song.instance.variables #=> [:@title, :@artist, :@year]
44
+
45
+ song.instance.get(:title) #=> "Parinoid"
42
46
 
43
- song.instance.get(:name) #=> "Black Sabbath"
47
+ song.instance[:artist] #=> "Black Sabbath"
44
48
 
45
- song.instance[:name] #=> "Black Sabbath"
49
+ song.instance.to_h
50
+ #=> {:name => "Paranoid", :author => "Black Sabbath", :year => 1970)
46
51
  ```
47
52
 
48
- For more a more complete set of usage examples see the QED documentation.
53
+ For a more complete set of usage examples see the QED documentation.
49
54
 
50
55
 
51
56
  ## Copyrights
@@ -18,23 +18,32 @@ And now demonstrate the available API.
18
18
 
19
19
  ## Instance#variables
20
20
 
21
- f1 = Friend.new("John", 30, "555-1212")
22
- f1.instance.variables.assert == [:@name, :@age, :@phone]
21
+ A list of instance variables can be had via the `#variables` method.
22
+
23
+ f = Friend.new("John", 30, "555-1212")
24
+ f.instance.variables.assert == [:@name, :@age, :@phone]
23
25
 
24
26
  ## Instance#names
25
27
 
26
- f1 = Friend.new("John", 30, "555-1212")
27
- f1.instance.names.assert == ["name", "age", "phone"]
28
+ To get a list of variables names as strings and without the `@` prefix,
29
+ use the `#names` method.
30
+
31
+ f = Friend.new("John", 30, "555-1212")
32
+ f.instance.names.assert == ["name", "age", "phone"]
28
33
 
29
34
  ## Instance#keys
30
35
 
31
- f1 = Friend.new("John", 30, "555-1212")
32
- f1.instance.keys.assert == [:name, :age, :phone]
36
+ Likewise, to get symbols instead of strings, use the `#keys` method.
37
+
38
+ f = Friend.new("John", 30, "555-1212")
39
+ f.instance.keys.assert == [:name, :age, :phone]
33
40
 
34
41
  ## Instance#values
35
42
 
36
- f1 = Friend.new("John", 30, "555-1212")
37
- f1.instance.values.assert == ["John", 30, "555-1212"]
43
+ The values of the instance variables alone can be had via the `#values` method.
44
+
45
+ f = Friend.new("John", 30, "555-1212")
46
+ f.instance.values.assert == ["John", 30, "555-1212"]
38
47
 
39
48
  ## Instance#size
40
49
 
@@ -53,14 +62,21 @@ This method is primarily of use to the Enumerable mixin.
53
62
 
54
63
  ## Instance#update and #assign
55
64
 
56
- f1 = Friend.new("John", 30, "555-1212")
57
- f1.name.assert == 'John'
65
+ The `#update` method can be used to change instance variables in mass via
66
+ method options.
58
67
 
59
- f1.instance.update(:name=>'Jerry')
60
- f1.name.assert == 'Jerry'
68
+ f = Friend.new("John", 30, "555-1212")
69
+ f.name.assert == 'John'
70
+ f.instance.update(:name=>'Jerry')
71
+ f.name.assert == 'Jerry'
61
72
 
62
- f1.instance.assign(:name=>'John')
63
- f1.name.assert == 'John'
73
+ ## Instance#assign
74
+
75
+ The `#assign` method is simply an alias for `#update`.
76
+
77
+ f = Friend.new("John", 30, "555-1212")
78
+ f.instance.assign(:name=>'Joe')
79
+ f.name.assert == 'Joe'
64
80
 
65
81
  ## Instance#to_h
66
82
 
@@ -78,11 +94,17 @@ want the `@` to stay simply pass `true` to the `#to_h` method.
78
94
 
79
95
  ## Instance#class
80
96
 
97
+ To know the class of an object use the `#class` method.
98
+
81
99
  f = Friend.new("John", 30, "555-1212")
82
100
  f.instance.class.assert == ::Friend
83
101
 
102
+ Note that to get the class of Instance itself, you must use `#object_class`.
103
+
84
104
  ## Instance#id
85
105
 
106
+ To know the id of an object use the `#id` method.
107
+
86
108
  f = Friend.new("John", 30, "555-1212")
87
109
  f.instance.id == f.object_id
88
110
 
@@ -91,15 +113,32 @@ want the `@` to stay simply pass `true` to the `#to_h` method.
91
113
  f = Friend.new("John", 30, "555-1212")
92
114
  f.instance.assert.of?(::Friend)
93
115
 
94
- ## Instance#get and #set
116
+ ## Instance#get
117
+
118
+ To get the value of a specific instance variable use the `#get` or `#[]`
119
+ methods.
95
120
 
96
121
  f = Friend.new("John", 30, "555-1212")
97
122
  f.instance.get(:name).assert == "John"
123
+ f.instance[:name].assert == "John"
124
+
125
+ ## Instance#set
126
+
127
+ To set the value of a specific instance variable use the `#set` or `#[]=`
128
+ methods.
129
+
130
+ f = Friend.new("John", 30, "555-1212")
131
+
98
132
  f.instance.set(:name, "Bill")
99
133
  f.name.assert == "Bill"
100
134
 
135
+ f.instance[:name] = "Billy"
136
+ f.name.assert == "Billy"
137
+
101
138
  ## Instance#remove
102
139
 
140
+ To remove an instance variable from an object use the `#remove` method.
141
+
103
142
  f = Friend.new("John", 30, "555-1212")
104
143
  f.instance.remove(:name)
105
144
  f.instance.refute.variable_defined?(:@name)
@@ -120,6 +159,8 @@ The actual *instance method* is the object's method.
120
159
 
121
160
  ## Instance#methods
122
161
 
162
+ We can also get a whole list of an object's methods via the `#methods` method.
163
+
123
164
  f = Friend.new("John", 30, "555-1212")
124
165
  f.instance.methods
125
166
  f.instance.methods(:private)
@@ -127,10 +168,18 @@ The actual *instance method* is the object's method.
127
168
  f.instance.methods(:public)
128
169
  f.instance.methods(:public, :private)
129
170
 
130
- ## Instance#eval and #exec
171
+ ## Instance#eval
172
+
173
+ To evaluate code in the context to the object's instance use the `#eval` method.
131
174
 
132
175
  f = Friend.new("John", 30, "555-1212")
133
176
  f.instance.eval("@name").assert == "John"
177
+
178
+ ## Instance#exec
179
+
180
+ Likewise the `#exec` method can also be used.
181
+
182
+ f = Friend.new("John", 30, "555-1212")
134
183
  f.instance.exec{ @name }.assert == "John"
135
184
 
136
185
  ## Instance#send
@@ -144,6 +193,9 @@ Hence it makes sense for it to be done via the `instance` interface.
144
193
 
145
194
  ## Instance#delegate
146
195
 
196
+ To get at the delegated object of an Instance, use the `#delegate` method.
197
+
147
198
  f = Friend.new("John", 30, "555-1212")
148
199
  f.instance.delegate.assert == f
149
200
 
201
+
@@ -0,0 +1,34 @@
1
+ # Instance for Modules/Classes
2
+
3
+ Modules and Classes have additional features not shared by other
4
+ types of objects.
5
+
6
+ ## Instance#method_definition
7
+
8
+ um = String.instance.method_definition(:to_s)
9
+ um.class.assert == UnboundMethod
10
+
11
+ ## Instance#definition
12
+
13
+ The `#definition` method is just an alias for `#method_definition`.
14
+
15
+ um = String.instance.definition(:to_s)
16
+ um.class.assert == UnboundMethod
17
+
18
+ ## Instance#method_definitions
19
+
20
+ list = String.instance.method_definitions
21
+
22
+ Method definitions can be selected use support symbol selectors.
23
+
24
+ list = String.instance.method_definitions(:public)
25
+ list = String.instance.method_definitions(:protected)
26
+ list = String.instance.method_definitions(:private)
27
+ list = String.instance.method_definitions(:private, :protected)
28
+
29
+ ## Instance#definitions
30
+
31
+ The `#definitions` method is likewise an alias for `#method_definitions`.
32
+
33
+ list = String.instance.definitions
34
+
@@ -64,9 +64,13 @@ class Instance
64
64
  @cache[delegate] ||= Instance.new(delegate)
65
65
  end
66
66
 
67
- # Initialize new Instance instance.
67
+ # Initialize new Instance instance. If the delegate is a type of
68
+ # Module or Class then the instance will be extended with the
69
+ # {ModuleExtensions} mixin.
70
+ #
68
71
  def initialize(delegate)
69
72
  @delegate = delegate
73
+ extend ModuleExtensions if Module === delegate
70
74
  end
71
75
 
72
76
  # The delegated object.
@@ -236,11 +240,11 @@ class Instance
236
240
 
237
241
  selection.each do |s|
238
242
  case s
239
- when :public
243
+ when :public, :all
240
244
  list.concat METHODS[:public_methods].bind(@delegate).call
241
- when :protected
245
+ when :protected, :all
242
246
  list.concat METHODS[:protected_methods].bind(@delegate).call
243
- when :private
247
+ when :private, :all
244
248
  list.concat METHODS[:private_methods].bind(@delegate).call
245
249
  end
246
250
  end
@@ -271,6 +275,9 @@ class Instance
271
275
  METHODS[:object_id].bind(@delegate).call
272
276
  end
273
277
 
278
+ # Fallback to get the real class of the Instance delegate itself.
279
+ alias :object_class :class
280
+
274
281
  # Get object's instance id.
275
282
  #
276
283
  # Returns [Class]
@@ -290,6 +297,71 @@ private
290
297
  name.to_s !~ /^@/ ? "@#{name}" : name
291
298
  end
292
299
 
300
+ ##
301
+ # ModuleExtensions provides some additional methods for Module and Class
302
+ # objects.
303
+ #
304
+ # TODO: Are there any other module/class methods that need to be provided?
305
+ #
306
+ module ModuleExtensions
307
+ # Store Object methods so they cannot be overriden by the delegate class.
308
+ METHODS = {}
309
+
310
+ def self.freeze_method(name)
311
+ METHODS[name.to_sym] = Module.instance_method(name)
312
+ end
313
+
314
+ freeze_method :instance_method
315
+ freeze_method :instance_methods
316
+ freeze_method :public_instance_methods
317
+ freeze_method :protected_instance_methods
318
+ freeze_method :private_instance_methods
319
+
320
+ # List of method definitions in a module or class.
321
+ #
322
+ # selection - Any of `:public`, `:protected` or `:private` which
323
+ # is used to select specific subsets of methods.
324
+ #
325
+ # Returns [Array<Symbol>]
326
+ def method_definitions(*selection)
327
+ list = []
328
+
329
+ if selection.empty?
330
+ list.concat METHODS[:instance_methods].bind(@delegate).call
331
+ end
332
+
333
+ selection.each do |s|
334
+ case s
335
+ when :public, :all
336
+ list.concat METHODS[:public_instance_methods].bind(@delegate).call
337
+ when :protected, :all
338
+ list.concat METHODS[:protected_instance_methods].bind(@delegate).call
339
+ when :private, :all
340
+ list.concat METHODS[:private_instance_methods].bind(@delegate).call
341
+ end
342
+ end
343
+
344
+ return list
345
+ end
346
+
347
+ # Shorter alias for #method_definitions.
348
+ alias :definitions :method_definitions
349
+
350
+ # Get a first-class method definition object.
351
+ #
352
+ # Returns an unbound method object. [UnboundMethod]
353
+ def method_definition(name)
354
+ METHODS[:instance_method].bind(@delegate).call(name)
355
+ end
356
+
357
+ alias :definition :method_definition
358
+ end
359
+
360
+ #
361
+ #module ClassExtensions
362
+ #
363
+ #end
364
+
293
365
  end
294
366
 
295
367
 
@@ -58,5 +58,5 @@ created: '2014-01-31'
58
58
  description: |-
59
59
  Instance is a spin-off of Ruby Facets. It provides a simple convenient API
60
60
  for accessing an object's state.
61
- version: 0.1.0
62
- date: '2014-02-01'
61
+ version: 0.2.0
62
+ date: '2014-02-02'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: instance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Sawyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-01 00:00:00.000000000 Z
11
+ date: 2014-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: qed
@@ -70,6 +70,7 @@ files:
70
70
  - lib/instance.yml
71
71
  - demo/applique/env.rb
72
72
  - demo/instance.md
73
+ - demo/module.md
73
74
  - README.md
74
75
  - HISTORY.md
75
76
  - LICENSE.txt