instance 0.1.0 → 0.2.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: 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