variables 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e00350ee1237f9a686c15f1b68ecdf1b4a8b907a
4
+ data.tar.gz: e896b8ae8384d3359f13387825e900dd6cef315c
5
+ SHA512:
6
+ metadata.gz: d33a10bb51f355d331923bd4be509141641dee0edcf5e31b3956a80d51d3ef0e44f7db7b6471c11c4736342eb8e555843bfd732df2f85bd6ae814fa8f98d385e
7
+ data.tar.gz: 801cc456f88824ff7ffdcb463d5c828d4c88c1cb2e1b6e7465ccee54a5c2f73e2dbeeb788546cd7e31652bf29e8ff8756a317c48ee3c7fdd2da45d25de87e49a
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ pkg
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ addons:
2
+ code_climate:
3
+ repo_token: e438cb2f24b677f5638441a8f31d294e34afe3fb5a5b5ec9b2d13d5d1fdf4d12
4
+
5
+ install: bundle install --jobs 3 --retry 3
6
+
7
+ rvm:
8
+ - 1.8.7
9
+ - 1.9.3
10
+ - 2.0.0
11
+ - ruby-head
12
+
13
+ script: bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://www.rubygems.org'
2
+
3
+ gemspec
4
+
5
+ unless RUBY_VERSION =~ /1\.8\./
6
+ gem 'codeclimate-test-reporter'
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ variables (0.0.0)
5
+ abstract_class (>= 1.0.0)
6
+
7
+ GEM
8
+ remote: https://www.rubygems.org/
9
+ specs:
10
+ abstract_class (1.0.1)
11
+ codeclimate-test-reporter (0.4.7)
12
+ simplecov (>= 0.7.1, < 1.0.0)
13
+ diff-lcs (1.2.5)
14
+ docile (1.1.5)
15
+ multi_json (1.10.1)
16
+ rspec (3.2.0)
17
+ rspec-core (~> 3.2.0)
18
+ rspec-expectations (~> 3.2.0)
19
+ rspec-mocks (~> 3.2.0)
20
+ rspec-core (3.2.1)
21
+ rspec-support (~> 3.2.0)
22
+ rspec-expectations (3.2.0)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.2.0)
25
+ rspec-mocks (3.2.1)
26
+ diff-lcs (>= 1.2.0, < 2.0)
27
+ rspec-support (~> 3.2.0)
28
+ rspec-support (3.2.2)
29
+ simplecov (0.9.2)
30
+ docile (~> 1.1.0)
31
+ multi_json (~> 1.0)
32
+ simplecov-html (~> 0.9.0)
33
+ simplecov-html (0.9.0)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ codeclimate-test-reporter
40
+ rspec
41
+ variables!
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2015 Sean Huber - github@shuber.io
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # [![Sean Huber](https://cloud.githubusercontent.com/assets/2419/6550752/832d9a64-c5ea-11e4-9717-6f9aa6e023b5.png)](https://github.com/shuber) variables
2
+
3
+ [![Build Status](https://secure.travis-ci.org/shuber/variables.svg)](http://travis-ci.org/shuber/variables) [![Code Climate](https://codeclimate.com/github/shuber/variables/badges/gpa.svg)](https://codeclimate.com/github/shuber/variables) [![Coverage](https://codeclimate.com/github/shuber/variables/badges/coverage.svg)](https://codeclimate.com/github/shuber/variables)
4
+
5
+ > `Variable` objects for *class* and *instance* variables
6
+
7
+ Ruby already has `Method` objects, why not `Variable` objects as well?
8
+
9
+
10
+ ## Installation
11
+
12
+ ```
13
+ gem install variables
14
+ ```
15
+
16
+
17
+ ## Requirements
18
+
19
+ Ruby 1.8.7+
20
+
21
+
22
+ ## Usage
23
+
24
+ Let's experiment with a simple `User` class.
25
+
26
+ ```ruby
27
+ class User
28
+ def initialize(name)
29
+ @name = name
30
+ end
31
+ end
32
+ ```
33
+
34
+ Objects can have any number of *instance* variables.
35
+
36
+ ```ruby
37
+ user = User.new('Bob') #=> #<User:0x007f8f6a84aa98>
38
+ user.instance_variable_get('@name') #=> "Bob"
39
+ ```
40
+
41
+ Similar to [`Object#method`](http://ruby-doc.org/core-1.8.7/Object.html#method-i-method), a handy `instance_variable` method is available for us to use.
42
+
43
+ ```ruby
44
+ name = user.instance_variable(:name) #=> #<InstanceVariable: #<User>@name>
45
+ ```
46
+
47
+ But unlike `Object#method`, this method does not require a variable to actually be defined.
48
+
49
+ ```ruby
50
+ undefined = user.instance_variable(:undefined) #=> #<InstanceVariable: #<User>@undefined>
51
+ ```
52
+
53
+ We can check if a variable is defined by using the `defined?` method.
54
+
55
+ ```ruby
56
+ name.defined? #=> true
57
+ undefined.defined? #=> false
58
+ ```
59
+
60
+ Once we have a `Variable` object, we can `get` its value.
61
+
62
+ ```ruby
63
+ name.get #=> "Bob"
64
+ undefined.get #=> nil
65
+ ```
66
+
67
+ Similar to [`Hash#fetch`](http://ruby-doc.org/core-1.9.3/Hash.html#method-i-fetch), the `fetch` method raises an exception if the variable is undefined.
68
+
69
+ ```ruby
70
+ name.fetch #=> "Bob"
71
+ undefined.fetch #=> Variables::UndefinedVariable - undefined variable "undefined"
72
+ ```
73
+
74
+ The `fetch` method optionally accepts a default value to return if the variable is undefined.
75
+
76
+ ```ruby
77
+ name.fetch(:default) #=> "Bob"
78
+ undefined.fetch(:default) #=> :default
79
+ ```
80
+
81
+ Default values can also be defined with a `block` which is yielded the `Variable` name.
82
+
83
+ ```ruby
84
+ name.fetch { |name| "#{name}-default" } #=> "Bob"
85
+ undefined.fetch { |name| "#{name}-default" } #=> "@undefined-default"
86
+ ```
87
+
88
+ We can update a `Variable` value by using the `set` method.
89
+
90
+ ```ruby
91
+ name.set('Steve') #=> "Steve"
92
+ user.instance_variable_get('@name') #=> "Steve"
93
+ ```
94
+
95
+ The `replace` method is similar to `set`, but it returns the old value instead of the new value.
96
+
97
+ ```ruby
98
+ name.replace('Bob') #=> "Steve"
99
+ user.instance_variable_get('@name') #=> "Bob"
100
+ ```
101
+
102
+ We can even temporarily `replace` a value for the duration of a `block`.
103
+
104
+ ```ruby
105
+ user.instance_variable_get('@name') #=> "Bob"
106
+
107
+ value = name.replace('Steve') do
108
+ user.instance_variable_get('@name') #=> "Steve"
109
+
110
+ 'we can return a value here'
111
+ end
112
+
113
+ user.instance_variable_get('@name') #=> "Bob"
114
+
115
+ value.inspect #=> "we can return a value here"
116
+ ```
117
+
118
+ Everything that we do with *instance* variables can be done with *class* variables as well!
119
+
120
+ ```ruby
121
+ example = User.class_variable(:example) #=> #<ClassVariable: User@@name>
122
+
123
+ example.defined? #=> false
124
+
125
+ example.set('testing') #=> "testing"
126
+
127
+ User.class_variable_get('@@example') #=> "testing"
128
+ ```
129
+
130
+
131
+ ## Testing
132
+
133
+ ```
134
+ bundle exec rspec
135
+ ```
136
+
137
+
138
+ ## Contributing
139
+
140
+ * Fork the project.
141
+ * Make your feature addition or bug fix.
142
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
143
+ * Commit, do not mess with Rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
144
+ * Send me a pull request. Bonus points for topic branches.
145
+
146
+
147
+ ## License
148
+
149
+ [MIT](https://github.com/shuber/variables/blob/master/LICENSE) - Copyright © 2015 Sean Huber
@@ -0,0 +1,18 @@
1
+ require 'variables/variable'
2
+
3
+ module Variables
4
+ class ClassVariable < Variable
5
+ def get
6
+ super
7
+ rescue NameError
8
+ end
9
+
10
+ def method_prefix
11
+ 'class'
12
+ end
13
+
14
+ def variable_prefix
15
+ '@@'
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ require 'variables/class_variable'
2
+
3
+ module Variables
4
+ module CoreExt
5
+ module Module
6
+ def class_variable(name)
7
+ ClassVariable.new(self, name)
8
+ end
9
+
10
+ def class_variable_fetch(name, *args, &block)
11
+ class_variable(name).fetch(*args, &block)
12
+ end
13
+
14
+ def class_variable_replace(name, *args, &block)
15
+ class_variable(name).replace(*args, &block)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'variables/instance_variable'
2
+
3
+ module Variables
4
+ module CoreExt
5
+ module Object
6
+ def instance_variable(name)
7
+ InstanceVariable.new(self, name)
8
+ end
9
+
10
+ def instance_variable_fetch(name, *args, &block)
11
+ instance_variable(name).fetch(*args, &block)
12
+ end
13
+
14
+ def instance_variable_replace(name, *args, &block)
15
+ instance_variable(name).replace(*args, &block)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ require 'variables/variable'
2
+
3
+ module Variables
4
+ class InstanceVariable < Variable
5
+ def method_prefix
6
+ 'instance'
7
+ end
8
+
9
+ def variable_prefix
10
+ '@'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module Variables
2
+ module Interface
3
+ def method_prefix
4
+ raise NotImplementedError
5
+ end
6
+
7
+ def variable_prefix
8
+ raise NotImplementedError
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ module Variables
2
+ class UndefinedVariable < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1,74 @@
1
+ require 'abstract_class'
2
+ require 'variables/interface'
3
+ require 'variables/undefined_variable'
4
+
5
+ module Variables
6
+ class Variable
7
+ extend AbstractClass
8
+ include Interface
9
+
10
+ attr_reader :owner, :name
11
+
12
+ def initialize(owner, name)
13
+ @owner = owner
14
+ @name = normalize(name)
15
+ end
16
+
17
+ def defined?
18
+ variable(:defined?, name)
19
+ end
20
+
21
+ def fetch(*args)
22
+ # We have to explicitly reference `self` here
23
+ # since `defined?` is a `Kernel` method
24
+ if self.defined?
25
+ get
26
+ elsif args.any?
27
+ args.first
28
+ elsif block_given?
29
+ yield(name)
30
+ else
31
+ raise UndefinedVariable, "undefined variable #{name.inspect}"
32
+ end
33
+ end
34
+
35
+ def get
36
+ variable(:get, name)
37
+ end
38
+
39
+ def replace(value, &block)
40
+ if block_given?
41
+ replace_with_block(value, &block)
42
+ else
43
+ replace_without_block(value)
44
+ end
45
+ end
46
+
47
+ def set(value)
48
+ variable(:set, name, value)
49
+ end
50
+
51
+ private
52
+
53
+ def normalize(name)
54
+ name.to_s.sub(/^([^#{variable_prefix}])/, "#{variable_prefix}\\1")
55
+ end
56
+
57
+ def variable(method, *args)
58
+ owner.send("#{method_prefix}_variable_#{method}", *args)
59
+ end
60
+
61
+ def replace_with_block(value)
62
+ existing = replace_without_block(value)
63
+ yield
64
+ ensure
65
+ replace_without_block(existing)
66
+ end
67
+
68
+ def replace_without_block(value)
69
+ existing = get
70
+ set(value)
71
+ existing
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,3 @@
1
+ module Variables
2
+ VERSION = '0.0.0'
3
+ end
data/lib/variables.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'variables/core_ext/module'
2
+ require 'variables/core_ext/object'
3
+ require 'variables/version'
4
+
5
+ Module.send(:include, Variables::CoreExt::Module)
6
+ Object.send(:include, Variables::CoreExt::Object)
@@ -0,0 +1,15 @@
1
+ begin
2
+ if ENV['CODECLIMATE_REPO_TOKEN']
3
+ require 'codeclimate-test-reporter'
4
+ CodeClimate::TestReporter.start
5
+ else
6
+ require 'simplecov'
7
+ SimpleCov.start { add_filter('/vendor/bundle/') }
8
+ end
9
+ rescue LoadError
10
+ # Ignore when testing with Ruby 1.8.7
11
+ end
12
+
13
+ RSpec.configure do |config|
14
+ config.raise_errors_for_deprecations!
15
+ end
@@ -0,0 +1,101 @@
1
+ require File.expand_path('../../../lib/variables/class_variable', __FILE__)
2
+
3
+ RSpec.describe Variables::ClassVariable do
4
+ subject { described_class.new(owner, name) }
5
+
6
+ let(:owner) { Class.new }
7
+ let(:name) { :undefined }
8
+
9
+ describe '#defined?' do
10
+ it 'should return false if the variable is undefined' do
11
+ expect(subject).not_to be_defined
12
+ end
13
+
14
+ it 'should return true if the variable is defined' do
15
+ owner.send(:class_variable_set, '@@undefined', nil)
16
+ expect(subject).to be_defined
17
+ end
18
+ end
19
+
20
+ describe '#fetch' do
21
+ it 'should raise UndefinedVariable if the variable is undefined' do
22
+ action = proc { subject.fetch }
23
+ expect(action).to raise_error(Variables::UndefinedVariable)
24
+ end
25
+
26
+ it 'should return the value if the variable is defined' do
27
+ owner.send(:class_variable_set, '@@undefined', :value)
28
+ expect(subject.fetch).to eq(:value)
29
+ end
30
+
31
+ it 'should return the default value if the variable is undefined' do
32
+ expect(subject.fetch(:value)).to eq(:value)
33
+ end
34
+
35
+ it 'should return the block result if the variable is undefined' do
36
+ value = subject.fetch { |name| name }
37
+ expect(value).to eq('@@undefined')
38
+
39
+ value = subject.fetch { :value }
40
+ expect(value).to eq(:value)
41
+ end
42
+ end
43
+
44
+ describe '#get' do
45
+ it 'should return nil if the variable is undefined' do
46
+ expect(subject.get).to be_nil
47
+ end
48
+
49
+ it 'should return the value if the variable is defined' do
50
+ owner.send(:class_variable_set, '@@undefined', :value)
51
+ expect(subject.get).to eq(:value)
52
+ end
53
+ end
54
+
55
+ describe '#owner' do
56
+ it 'should return the original owner' do
57
+ expect(subject.owner).to eq(owner)
58
+ end
59
+ end
60
+
61
+ describe '#replace' do
62
+ it 'should replace a variable and return the old value' do
63
+ expect(subject.replace(:value)).to be_nil
64
+ value = owner.send(:class_variable_get, '@@undefined')
65
+ expect(value).to eq(:value)
66
+ end
67
+
68
+ it 'should replace a variable for the duration of a block' do
69
+ action = proc { owner.class_variable_get('@@undefined') }
70
+ expect(action).to raise_error(NameError)
71
+
72
+ subject.replace(:value) do
73
+ value = owner.send(:class_variable_get, '@@undefined')
74
+ expect(value).to eq(:value)
75
+ end
76
+
77
+ value = owner.send(:class_variable_get, '@@undefined')
78
+ expect(value).to be_nil
79
+ end
80
+
81
+ it 'should return the last expression of a block' do
82
+ value = subject.replace(:value) { :test }
83
+ expect(value).to eq(:test)
84
+ end
85
+ end
86
+
87
+ describe '#set' do
88
+ it 'should set the new value if the variable is undefined' do
89
+ subject.set(:value)
90
+ value = owner.send(:class_variable_get, '@@undefined')
91
+ expect(value).to eq(:value)
92
+ end
93
+
94
+ it 'should overwrite a value if the variable is defined' do
95
+ owner.send(:class_variable_set, '@@undefined', nil)
96
+ subject.set(:value)
97
+ value = owner.send(:class_variable_get, '@@undefined')
98
+ expect(value).to eq(:value)
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,37 @@
1
+ require File.expand_path('../../../../lib/variables/core_ext/module', __FILE__)
2
+
3
+ RSpec.describe Variables::CoreExt::Module do
4
+ subject { Class.new.extend(described_class) }
5
+
6
+ describe '#instance_variable' do
7
+ it 'should initialize a new ClassVariable' do
8
+ variable = Variables::ClassVariable
9
+ expect(variable).to receive(:new).with(subject, :test).and_return(true)
10
+
11
+ value = subject.class_variable(:test)
12
+ expect(value).to eq(true)
13
+ end
14
+ end
15
+
16
+ describe '#class_variable_fetch' do
17
+ it 'should delegate #fetch to the named class variable' do
18
+ var = double('class variable')
19
+ block = proc { }
20
+ expect(subject).to receive(:class_variable).with(:test).and_return(var)
21
+ expect(var).to receive(:fetch).with(:a, :b, &block).and_return(:example)
22
+ value = subject.class_variable_fetch(:test, :a, :b, &block)
23
+ expect(value).to eq(:example)
24
+ end
25
+ end
26
+
27
+ describe '#class_variable_replace' do
28
+ it 'should delegate #replace to the named class variable' do
29
+ var = double('class variable')
30
+ block = proc { }
31
+ expect(subject).to receive(:class_variable).with(:test).and_return(var)
32
+ expect(var).to receive(:replace).with(:a, :b, &block).and_return(:example)
33
+ value = subject.class_variable_replace(:test, :a, :b, &block)
34
+ expect(value).to eq(:example)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ require File.expand_path('../../../../lib/variables/core_ext/object', __FILE__)
2
+
3
+ RSpec.describe Variables::CoreExt::Object do
4
+ subject { Object.new.extend(described_class) }
5
+
6
+ describe '#instance_variable' do
7
+ it 'should initialize a new InstanceVariable' do
8
+ variable = Variables::InstanceVariable
9
+ expect(variable).to receive(:new).with(subject, :test).and_return(true)
10
+
11
+ value = subject.instance_variable(:test)
12
+ expect(value).to eq(true)
13
+ end
14
+ end
15
+
16
+ describe '#instance_variable_fetch' do
17
+ it 'should delegate #fetch to the named instance variable' do
18
+ var = double('instance variable')
19
+ block = proc { }
20
+ expect(subject).to receive(:instance_variable).with(:test).and_return(var)
21
+ expect(var).to receive(:fetch).with(:a, :b, &block).and_return(:example)
22
+ value = subject.instance_variable_fetch(:test, :a, :b, &block)
23
+ expect(value).to eq(:example)
24
+ end
25
+ end
26
+
27
+ describe '#instance_variable_replace' do
28
+ it 'should delegate #replace to the named instance variable' do
29
+ var = double('instance variable')
30
+ block = proc { }
31
+ expect(subject).to receive(:instance_variable).with(:test).and_return(var)
32
+ expect(var).to receive(:replace).with(:a, :b, &block).and_return(:example)
33
+ value = subject.instance_variable_replace(:test, :a, :b, &block)
34
+ expect(value).to eq(:example)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,97 @@
1
+ require File.expand_path('../../../lib/variables/instance_variable', __FILE__)
2
+
3
+ RSpec.describe Variables::InstanceVariable do
4
+ subject { described_class.new(owner, name) }
5
+
6
+ let(:owner) { Object.new }
7
+ let(:name) { :undefined }
8
+
9
+ describe '#defined?' do
10
+ it 'should return false if the variable is undefined' do
11
+ expect(subject).not_to be_defined
12
+ end
13
+
14
+ it 'should return true if the variable is defined' do
15
+ owner.instance_variable_set('@undefined', nil)
16
+ expect(subject).to be_defined
17
+ end
18
+ end
19
+
20
+ describe '#fetch' do
21
+ it 'should raise UndefinedVariable if the variable is undefined' do
22
+ action = proc { subject.fetch }
23
+ expect(action).to raise_error(Variables::UndefinedVariable)
24
+ end
25
+
26
+ it 'should return the value if the variable is defined' do
27
+ owner.instance_variable_set('@undefined', :value)
28
+ expect(subject.fetch).to eq(:value)
29
+ end
30
+
31
+ it 'should return the default value if the variable is undefined' do
32
+ expect(subject.fetch(:value)).to eq(:value)
33
+ end
34
+
35
+ it 'should return the block result if the variable is undefined' do
36
+ value = subject.fetch { |name| name }
37
+ expect(value).to eq('@undefined')
38
+
39
+ value = subject.fetch { :value }
40
+ expect(value).to eq(:value)
41
+ end
42
+ end
43
+
44
+ describe '#get' do
45
+ it 'should return nil if the variable is undefined' do
46
+ expect(subject.get).to be_nil
47
+ end
48
+
49
+ it 'should return the value if the variable is defined' do
50
+ owner.instance_variable_set('@undefined', :value)
51
+ expect(subject.get).to eq(:value)
52
+ end
53
+ end
54
+
55
+ describe '#owner' do
56
+ it 'should return the original owner' do
57
+ expect(subject.owner).to eq(owner)
58
+ end
59
+ end
60
+
61
+ describe '#replace' do
62
+ it 'should replace a variable and return the old value' do
63
+ expect(subject.replace(:value)).to be_nil
64
+ expect(owner.instance_variable_get('@undefined')).to eq(:value)
65
+ end
66
+
67
+ it 'should replace a variable for the duration of a block' do
68
+ expect(owner.instance_variable_get('@undefined')).to be_nil
69
+
70
+ subject.replace(:value) do
71
+ expect(owner.instance_variable_get('@undefined')).to eq(:value)
72
+ end
73
+
74
+ expect(owner.instance_variable_get('@undefined')).to be_nil
75
+ end
76
+
77
+ it 'should return the last expression of a block' do
78
+ value = subject.replace(:value) { :test }
79
+ expect(value).to eq(:test)
80
+ end
81
+ end
82
+
83
+ describe '#set' do
84
+ it 'should set the new value if the variable is undefined' do
85
+ subject.set(:value)
86
+ value = owner.instance_variable_get('@undefined')
87
+ expect(value).to eq(:value)
88
+ end
89
+
90
+ it 'should overwrite a value if the variable is defined' do
91
+ owner.instance_variable_set('@undefined', nil)
92
+ subject.set(:value)
93
+ value = owner.instance_variable_get('@undefined')
94
+ expect(value).to eq(:value)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../../../lib/variables/interface', __FILE__)
2
+
3
+ RSpec.describe Variables::Interface do
4
+ subject { Class.new.send(:include, described_class).new }
5
+
6
+ it 'should raise NotImplementedError for all methods' do
7
+ described_class.instance_methods(false).each do |method|
8
+ action = subject.method(method).to_proc
9
+ expect(action).to raise_error(NotImplementedError)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path('../../../lib/variables/variable', __FILE__)
2
+
3
+ RSpec.describe Variables::Variable do
4
+ subject { described_class }
5
+
6
+ it { is_expected.to be_an(AbstractClass) }
7
+ end
data/variables.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ require File.expand_path('../lib/variables/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.author = 'Sean Huber'
5
+ s.description = 'Ruby already has `Method` objects, why not `Variable` objects as well?'
6
+ s.email = 'github@shuber.io'
7
+ s.extra_rdoc_files = %w(LICENSE)
8
+ s.files = `git ls-files`.split("\n")
9
+ s.homepage = 'https://github.com/shuber/variables'
10
+ s.license = 'MIT'
11
+ s.name = 'variables'
12
+ s.rdoc_options = %w(--charset=UTF-8 --inline-source --line-numbers --main README.md)
13
+ s.require_paths = %w(lib)
14
+ s.summary = '`Variable` objects for class and instance variables'
15
+ s.test_files = `git ls-files -- spec/*`.split("\n")
16
+ s.version = Variables::VERSION
17
+
18
+ s.add_dependency 'abstract_class', '>= 1.0.0'
19
+ s.add_development_dependency 'rspec'
20
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: variables
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Sean Huber
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: abstract_class
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Ruby already has `Method` objects, why not `Variable` objects as well?
42
+ email: github@shuber.io
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files:
46
+ - LICENSE
47
+ files:
48
+ - ".gitignore"
49
+ - ".rspec"
50
+ - ".travis.yml"
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - LICENSE
54
+ - README.md
55
+ - lib/variables.rb
56
+ - lib/variables/class_variable.rb
57
+ - lib/variables/core_ext/module.rb
58
+ - lib/variables/core_ext/object.rb
59
+ - lib/variables/instance_variable.rb
60
+ - lib/variables/interface.rb
61
+ - lib/variables/undefined_variable.rb
62
+ - lib/variables/variable.rb
63
+ - lib/variables/version.rb
64
+ - spec/spec_helper.rb
65
+ - spec/variables/class_variable_spec.rb
66
+ - spec/variables/core_ext/module_spec.rb
67
+ - spec/variables/core_ext/object_spec.rb
68
+ - spec/variables/instance_variable_spec.rb
69
+ - spec/variables/interface_spec.rb
70
+ - spec/variables/variable_spec.rb
71
+ - variables.gemspec
72
+ homepage: https://github.com/shuber/variables
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options:
78
+ - "--charset=UTF-8"
79
+ - "--inline-source"
80
+ - "--line-numbers"
81
+ - "--main"
82
+ - README.md
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.4.5
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: "`Variable` objects for class and instance variables"
101
+ test_files:
102
+ - spec/spec_helper.rb
103
+ - spec/variables/class_variable_spec.rb
104
+ - spec/variables/core_ext/module_spec.rb
105
+ - spec/variables/core_ext/object_spec.rb
106
+ - spec/variables/instance_variable_spec.rb
107
+ - spec/variables/interface_spec.rb
108
+ - spec/variables/variable_spec.rb