variables 0.0.0 → 0.0.1
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/Gemfile.lock +1 -1
- data/README.md +77 -7
- data/lib/variables.rb +0 -4
- data/lib/variables/core_ext/module.rb +5 -2
- data/lib/variables/core_ext/object.rb +28 -2
- data/lib/variables/version.rb +1 -1
- data/spec/variables/core_ext/module_spec.rb +16 -1
- data/spec/variables/core_ext/object_spec.rb +16 -1
- data/variables.gemspec +1 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5afb3ae44f42e6645bbedd2ba24dfe62fc514226
|
4
|
+
data.tar.gz: 56dd7414254fcc2272a1bbf71378da9193f23b0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 434db9ac4298434b821ededa65f017cfdbbdfd5973ff4ae2f6b1cd8abd01cc30a36c84ed3bee930d5a876247a73f10e1c836998ba9069afd6869d1a2c075520e
|
7
|
+
data.tar.gz: 89ec48f72918ab8ad18d5711c785269b829855b2fd3314ec66153c18e3902926ea6686f83852f483e217700db077f6681d5977b822b8f65e1bc02c9db820bb49
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,26 @@
|
|
1
1
|
# [](https://github.com/shuber) variables
|
2
2
|
|
3
|
-
[](http://travis-ci.org/shuber/variables) [](https://codeclimate.com/github/shuber/variables) [](https://codeclimate.com/github/shuber/variables)
|
3
|
+
[](http://travis-ci.org/shuber/variables) [](https://codeclimate.com/github/shuber/variables) [](https://codeclimate.com/github/shuber/variables) [](http://badge.fury.io/rb/variables)
|
4
4
|
|
5
5
|
> `Variable` objects for *class* and *instance* variables
|
6
6
|
|
7
7
|
Ruby already has `Method` objects, why not `Variable` objects as well?
|
8
8
|
|
9
|
+
## Why?
|
10
|
+
|
11
|
+
Some methods already exist for interacting with *class* and *instance* variables:
|
12
|
+
|
13
|
+
* `Module#class_variable_defined?`
|
14
|
+
* `Module#class_variable_get`
|
15
|
+
* `Module#class_variable_set`
|
16
|
+
* `Object#instance_variable_defined?`
|
17
|
+
* `Object#instance_variable_get`
|
18
|
+
* `Object#instance_variable_set`
|
19
|
+
|
20
|
+
But notice that these all share a common prefix - `instance_variable_` or `class_variable_`.
|
21
|
+
|
22
|
+
This feels a little [smelly](http://en.wikipedia.org/wiki/Code_smell), let's try to [DRY](http://en.wikipedia.org/wiki/Don%27t_repeat_yourself) it up with some `Variable` objects!
|
23
|
+
|
9
24
|
|
10
25
|
## Installation
|
11
26
|
|
@@ -38,7 +53,7 @@ user = User.new('Bob') #=> #<User:0x007f8f6a84aa98>
|
|
38
53
|
user.instance_variable_get('@name') #=> "Bob"
|
39
54
|
```
|
40
55
|
|
41
|
-
Similar to [`Object#method`](http://ruby-doc.org/core-1.8.7/Object.html#method-i-method),
|
56
|
+
Similar to [`Object#method`](http://ruby-doc.org/core-1.8.7/Object.html#method-i-method), the `instance_variable` method returns a `Variable` object.
|
42
57
|
|
43
58
|
```ruby
|
44
59
|
name = user.instance_variable(:name) #=> #<InstanceVariable: #<User>@name>
|
@@ -78,13 +93,20 @@ name.fetch(:default) #=> "Bob"
|
|
78
93
|
undefined.fetch(:default) #=> :default
|
79
94
|
```
|
80
95
|
|
81
|
-
Default values can also be defined with a `block` which is yielded the `Variable` name.
|
96
|
+
Default values can also be defined with a `block` which is yielded with the `Variable` name.
|
82
97
|
|
83
98
|
```ruby
|
84
99
|
name.fetch { |name| "#{name}-default" } #=> "Bob"
|
85
100
|
undefined.fetch { |name| "#{name}-default" } #=> "@undefined-default"
|
86
101
|
```
|
87
102
|
|
103
|
+
The `Object#instance_variable_fetch` method allows us to `fetch` a variable's value by name.
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
name.fetch #=> "Bob"
|
107
|
+
user.instance_variable_fetch(:name) #=> "Bob"
|
108
|
+
```
|
109
|
+
|
88
110
|
We can update a `Variable` value by using the `set` method.
|
89
111
|
|
90
112
|
```ruby
|
@@ -104,18 +126,47 @@ We can even temporarily `replace` a value for the duration of a `block`.
|
|
104
126
|
```ruby
|
105
127
|
user.instance_variable_get('@name') #=> "Bob"
|
106
128
|
|
107
|
-
|
129
|
+
name.replace('Steve') do
|
108
130
|
user.instance_variable_get('@name') #=> "Steve"
|
131
|
+
end
|
132
|
+
|
133
|
+
user.instance_variable_get('@name') #=> "Bob"
|
134
|
+
```
|
135
|
+
|
136
|
+
Note that when using the `block` form of `replace`, the last expression of the block is returned.
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
name.replace('Steve') { 1 + 1 } #=> 2
|
140
|
+
```
|
141
|
+
|
142
|
+
The `Object#instance_variable_replace` method allows us to `replace` a variable's value by name.
|
109
143
|
|
110
|
-
|
144
|
+
```ruby
|
145
|
+
user.instance_variable_get('@name') #=> "Bob"
|
146
|
+
|
147
|
+
user.instance_variable_replace(:name, 'Steve') do
|
148
|
+
user.instance_variable_get('@name') #=> "Steve"
|
111
149
|
end
|
112
150
|
|
113
151
|
user.instance_variable_get('@name') #=> "Bob"
|
152
|
+
```
|
153
|
+
|
154
|
+
The `instance_variable_replace` method also accepts a hash of variables to `replace`.
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
user.instance_variable_get('@name') #=> "Bob"
|
158
|
+
user.instance_variable_get('@test') #=> nil
|
114
159
|
|
115
|
-
|
160
|
+
user.instance_variable_replace(name: 'Steve', test: 'example') do
|
161
|
+
user.instance_variable_get('@name') #=> "Steve"
|
162
|
+
user.instance_variable_get('@test') #=> "example"
|
163
|
+
end
|
164
|
+
|
165
|
+
user.instance_variable_get('@name') #=> "Bob"
|
166
|
+
user.instance_variable_get('@test') #=> nil
|
116
167
|
```
|
117
168
|
|
118
|
-
Everything that we do with *instance* variables can be done with *class* variables as well
|
169
|
+
**Everything that we can do with *instance* variables can be done with *class* variables as well!**
|
119
170
|
|
120
171
|
```ruby
|
121
172
|
example = User.class_variable(:example) #=> #<ClassVariable: User@@name>
|
@@ -128,6 +179,25 @@ User.class_variable_get('@@example') #=> "testing"
|
|
128
179
|
```
|
129
180
|
|
130
181
|
|
182
|
+
## API
|
183
|
+
|
184
|
+
[YARD Documentation](http://www.rubydoc.info/github/shuber/variables)
|
185
|
+
|
186
|
+
* `Module#class_variable`
|
187
|
+
* `Module#class_variable_fetch`
|
188
|
+
* `Module#class_variable_replace`
|
189
|
+
* `Object#instance_variable`
|
190
|
+
* `Object#instance_variable_fetch`
|
191
|
+
* `Object#instance_variable_replace`
|
192
|
+
* `Variable#defined?`
|
193
|
+
* `Variable#fetch`
|
194
|
+
* `Variable#get`
|
195
|
+
* `Variable#name`
|
196
|
+
* `Variable#owner`
|
197
|
+
* `Variable#replace`
|
198
|
+
* `Variable#set`
|
199
|
+
|
200
|
+
|
131
201
|
## Testing
|
132
202
|
|
133
203
|
```
|
data/lib/variables.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'variables/class_variable'
|
2
|
+
require 'variables/core_ext/object'
|
2
3
|
|
3
4
|
module Variables
|
4
5
|
module CoreExt
|
@@ -8,12 +9,14 @@ module Variables
|
|
8
9
|
end
|
9
10
|
|
10
11
|
def class_variable_fetch(name, *args, &block)
|
11
|
-
class_variable
|
12
|
+
fetch_variable(:class_variable, name, *args, &block)
|
12
13
|
end
|
13
14
|
|
14
15
|
def class_variable_replace(name, *args, &block)
|
15
|
-
class_variable
|
16
|
+
replace_variable(:class_variable, name, *args, &block)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
21
|
+
|
22
|
+
Module.send(:include, Variables::CoreExt::Module)
|
@@ -8,12 +8,38 @@ module Variables
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def instance_variable_fetch(name, *args, &block)
|
11
|
-
instance_variable
|
11
|
+
fetch_variable(:instance_variable, name, *args, &block)
|
12
12
|
end
|
13
13
|
|
14
14
|
def instance_variable_replace(name, *args, &block)
|
15
|
-
instance_variable
|
15
|
+
replace_variable(:instance_variable, name, *args, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def fetch_variable(variable, name, *args, &block)
|
21
|
+
send(variable, name).fetch(*args, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def replace_variable(variable, name, *args, &block)
|
25
|
+
if name.is_a?(Hash) && args.empty? && block_given?
|
26
|
+
replace_variable_proc(variable, name, &block).call
|
27
|
+
else
|
28
|
+
send(variable, name).replace(*args, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def replace_variable_proc(variable, hash, &block)
|
33
|
+
hash.reduce(block) do |original, (name, value)|
|
34
|
+
proc do
|
35
|
+
send(variable, name).replace(value) do
|
36
|
+
original.call
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
16
40
|
end
|
17
41
|
end
|
18
42
|
end
|
19
43
|
end
|
44
|
+
|
45
|
+
Object.send(:include, Variables::CoreExt::Object)
|
data/lib/variables/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path('../../../../lib/variables/core_ext/module', __FILE__)
|
2
2
|
|
3
3
|
RSpec.describe Variables::CoreExt::Module do
|
4
|
-
subject { Class.new
|
4
|
+
subject { Class.new }
|
5
5
|
|
6
6
|
describe '#instance_variable' do
|
7
7
|
it 'should initialize a new ClassVariable' do
|
@@ -33,5 +33,20 @@ RSpec.describe Variables::CoreExt::Module do
|
|
33
33
|
value = subject.class_variable_replace(:test, :a, :b, &block)
|
34
34
|
expect(value).to eq(:example)
|
35
35
|
end
|
36
|
+
|
37
|
+
it 'should support a hash of variables to replace' do
|
38
|
+
subject.class_variable_replace(:one => 1, :two => 2) do
|
39
|
+
expect(subject.send(:class_variable_get, '@@one')).to eq(1)
|
40
|
+
expect(subject.send(:class_variable_get, '@@two')).to eq(2)
|
41
|
+
end
|
42
|
+
|
43
|
+
expect(subject.send(:class_variable_get, '@@one')).to be_nil
|
44
|
+
expect(subject.send(:class_variable_get, '@@two')).to be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should only support a hash of variables if a block is given' do
|
48
|
+
action = proc { subject.class_variable_replace(:one => 1, :two => 2) }
|
49
|
+
expect(action).to raise_error(ArgumentError)
|
50
|
+
end
|
36
51
|
end
|
37
52
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path('../../../../lib/variables/core_ext/object', __FILE__)
|
2
2
|
|
3
3
|
RSpec.describe Variables::CoreExt::Object do
|
4
|
-
subject { Object.new
|
4
|
+
subject { Object.new }
|
5
5
|
|
6
6
|
describe '#instance_variable' do
|
7
7
|
it 'should initialize a new InstanceVariable' do
|
@@ -33,5 +33,20 @@ RSpec.describe Variables::CoreExt::Object do
|
|
33
33
|
value = subject.instance_variable_replace(:test, :a, :b, &block)
|
34
34
|
expect(value).to eq(:example)
|
35
35
|
end
|
36
|
+
|
37
|
+
it 'should support a hash of variables to replace' do
|
38
|
+
subject.instance_variable_replace(:one => 1, :two => 2) do
|
39
|
+
expect(subject.instance_variable_get('@one')).to eq(1)
|
40
|
+
expect(subject.instance_variable_get('@two')).to eq(2)
|
41
|
+
end
|
42
|
+
|
43
|
+
expect(subject.instance_variable_get('@one')).to be_nil
|
44
|
+
expect(subject.instance_variable_get('@two')).to be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should only support a hash of variables if a block is given' do
|
48
|
+
action = proc { subject.instance_variable_replace(:one => 1, :two => 2) }
|
49
|
+
expect(action).to raise_error(ArgumentError)
|
50
|
+
end
|
36
51
|
end
|
37
52
|
end
|
data/variables.gemspec
CHANGED
@@ -2,7 +2,6 @@ require File.expand_path('../lib/variables/version', __FILE__)
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.author = 'Sean Huber'
|
5
|
-
s.description = 'Ruby already has `Method` objects, why not `Variable` objects as well?'
|
6
5
|
s.email = 'github@shuber.io'
|
7
6
|
s.extra_rdoc_files = %w(LICENSE)
|
8
7
|
s.files = `git ls-files`.split("\n")
|
@@ -11,7 +10,7 @@ Gem::Specification.new do |s|
|
|
11
10
|
s.name = 'variables'
|
12
11
|
s.rdoc_options = %w(--charset=UTF-8 --inline-source --line-numbers --main README.md)
|
13
12
|
s.require_paths = %w(lib)
|
14
|
-
s.summary = '`
|
13
|
+
s.summary = 'Ruby already has `Method` objects, why not `Variable` objects as well?'
|
15
14
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
16
15
|
s.version = Variables::VERSION
|
17
16
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: variables
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Huber
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: abstract_class
|
@@ -38,7 +38,7 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
description:
|
41
|
+
description:
|
42
42
|
email: github@shuber.io
|
43
43
|
executables: []
|
44
44
|
extensions: []
|
@@ -97,7 +97,7 @@ rubyforge_project:
|
|
97
97
|
rubygems_version: 2.4.5
|
98
98
|
signing_key:
|
99
99
|
specification_version: 4
|
100
|
-
summary:
|
100
|
+
summary: Ruby already has `Method` objects, why not `Variable` objects as well?
|
101
101
|
test_files:
|
102
102
|
- spec/spec_helper.rb
|
103
103
|
- spec/variables/class_variable_spec.rb
|