renewable 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 648680f8f5c0283aa11938e169a4ab509991221e
4
+ data.tar.gz: bbc9186b86c072cf0ece86692883486088325c62
5
+ SHA512:
6
+ metadata.gz: 0cdab0882b58b0680062093a69723fcea91a86803a4ce7936bc0eeb42f37d51c97f8930e9a5fcc90ff3578500c351e33007e8c67cf9b0e438070482445736012
7
+ data.tar.gz: 9b64237e91316164f7dabc144e40f14f7e1e2b764d654ba22b4f16394f7170b1a37ed922da186fca65cebdf89e5964583183bac13162ce639161acd15d37a087
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --require spec_helper
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ renewable
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.1.5
data/.simplecov ADDED
@@ -0,0 +1,4 @@
1
+ SimpleCov.root(File.dirname(__FILE__))
2
+ SimpleCov.start do
3
+ add_filter '/spec/'
4
+ end
data/.travis.yml ADDED
@@ -0,0 +1,75 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - 2.1.1
7
+ - 2.1.2
8
+ - 2.1.3
9
+ - 2.1.4
10
+ - 2.1.5
11
+ - jruby
12
+ - jruby-head
13
+ jdk:
14
+ - openjdk6
15
+ - openjdk7
16
+ - oraclejdk7
17
+ - oraclejdk8
18
+ branches:
19
+ only:
20
+ - master
21
+ matrix:
22
+ exclude:
23
+ - rvm: 1.9.3
24
+ jdk: openjdk6
25
+ - rvm: 1.9.3
26
+ jdk: oraclejdk7
27
+ - rvm: 1.9.3
28
+ jdk: oraclejdk8
29
+ - rvm: 2.0.0
30
+ jdk: openjdk6
31
+ - rvm: 2.0.0
32
+ jdk: oraclejdk7
33
+ - rvm: 2.0.0
34
+ jdk: oraclejdk8
35
+ - rvm: 2.1.0
36
+ jdk: openjdk6
37
+ - rvm: 2.1.0
38
+ jdk: oraclejdk7
39
+ - rvm: 2.1.0
40
+ jdk: oraclejdk8
41
+ - rvm: 2.1.1
42
+ jdk: openjdk6
43
+ - rvm: 2.1.1
44
+ jdk: oraclejdk7
45
+ - rvm: 2.1.1
46
+ jdk: oraclejdk8
47
+ - rvm: 2.1.2
48
+ jdk: openjdk6
49
+ - rvm: 2.1.2
50
+ jdk: oraclejdk7
51
+ - rvm: 2.1.2
52
+ jdk: oraclejdk8
53
+ - rvm: 2.1.3
54
+ jdk: openjdk6
55
+ - rvm: 2.1.3
56
+ jdk: oraclejdk7
57
+ - rvm: 2.1.3
58
+ jdk: oraclejdk8
59
+ - rvm: 2.1.4
60
+ jdk: openjdk6
61
+ - rvm: 2.1.4
62
+ jdk: oraclejdk7
63
+ - rvm: 2.1.4
64
+ jdk: oraclejdk8
65
+ - rvm: 2.1.5
66
+ jdk: openjdk6
67
+ - rvm: 2.1.5
68
+ jdk: oraclejdk7
69
+ - rvm: 2.1.5
70
+ jdk: oraclejdk8
71
+ allow_failures:
72
+ - rvm: jruby-head
73
+ addons:
74
+ code_climate:
75
+ repo_token: 9e50ded77de130a89a7a427514be291a89485d1fb09e805aa384da81bc54a88d
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in renewable.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 James Thompson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # Renewable
2
+
3
+ [![Code Climate](https://codeclimate.com/github/plainprogrammer/renewable/badges/gpa.svg)](https://codeclimate.com/github/plainprogrammer/renewable)
4
+ [![Build Status](https://travis-ci.org/plainprogrammer/renewable.svg)](https://travis-ci.org/plainprogrammer/renewable)
5
+ [![Test Coverage](https://codeclimate.com/github/plainprogrammer/renewable/badges/coverage.svg)](https://codeclimate.com/github/plainprogrammer/renewable)
6
+
7
+ Renewable provides means to have objects that are frozen by default. The benefit
8
+ of this is that it pushes the developer in the direction of a more Functional
9
+ style of programming that is safer in multi-threaded situations, but maintains
10
+ many of the benefits of Object-Oriented Programming's binding of data and
11
+ behavior by simply doing away with in-place mutation.
12
+
13
+ ## STATUS
14
+
15
+ This code is still considered experimental in nature. It is not advised to use
16
+ this library in production environments without having read and fully
17
+ comprehended how the code works.
18
+
19
+ *YOU HAVE BEEN WARNED!*
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ ```ruby
26
+ gem 'renewable'
27
+ ```
28
+
29
+ And then execute:
30
+
31
+ $ bundle
32
+
33
+ Or install it yourself as:
34
+
35
+ $ gem install renewable
36
+
37
+ ## Usage
38
+
39
+ Renewable exposes two usage approached: Mixin and Inheritance.
40
+
41
+ ```ruby
42
+ class Person
43
+ include Renewable
44
+
45
+ attr_reader :name, :birth_date
46
+
47
+ def age
48
+ Date.today.year - birth_date.year
49
+ end
50
+ end
51
+ ```
52
+
53
+ ```ruby
54
+ class Person < Renewable::Object
55
+ attr_reader :name, :birth_date
56
+
57
+ def age
58
+ Date.today.year - birth_date.year
59
+ end
60
+ end
61
+ ```
62
+
63
+ Regardless of which you choose, the behavior is the same. Because of how
64
+ Renewable is intended to function there are some important rules to follow when
65
+ building your classes with Renewable.
66
+
67
+ ### Initializers
68
+
69
+ *Don't write them!* Renewable implements an initializer that you can hook into
70
+ via callbacks. Because of the steps that the initializer takes need to be
71
+ preserved for everything to work properly you should simply avoid writing your
72
+ own. All of the callbacks described below will receive an `attributes` and an
73
+ `options` Hash, which are the two arguments the Renewable-supplied initializer
74
+ expects. Callbacks should simply be defined as `protected` or `private` methods
75
+ based on your inheritance needs.
76
+
77
+ ```ruby
78
+ class Person < Renewable::Object
79
+ attr_reader :name, :birth_date
80
+
81
+ private
82
+
83
+ def process_arguments(attributes, options)
84
+ # This callback is invoked before Renewable does anything itself. So, do any
85
+ # custom manipulation or processing of the attributes and options hashes you
86
+ # need. This method should return an like so:
87
+ return attributes, options
88
+ end
89
+
90
+ def before_freeze(attributes, options)
91
+ # This callback is invoked immediately before Renewable freezes the object's
92
+ # state. Prior to this step Renewable places each item in `attributes` into
93
+ # its respective instance variable and stores `options` as well. This is
94
+ # your last chance to modify the object's internal state. This method should
95
+ # return like so:
96
+ return attributes, options
97
+ end
98
+
99
+ def after_freeze(attributes, options)
100
+ # This callback is invoked immediately after Renewable freezes the object's
101
+ # state. At this point you can no longer mutate the object, but this
102
+ # callback is provided just in case you find a use case. It is also the last
103
+ # thing invoked by Renewable's initialize implementation and thus requires
104
+ # no return value.
105
+ end
106
+ end
107
+ ```
108
+
109
+ ### Mutators (Methods that change stuff)
110
+
111
+ TODO: Write this section.
112
+
113
+ ### #renew
114
+
115
+ TODO: Write this section.
116
+
117
+ ## Contributing
118
+
119
+ 1. Fork it ( https://github.com/[my-github-username]/renewable/fork )
120
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
121
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
122
+ 4. Push to the branch (`git push origin my-new-feature`)
123
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/lib/renewable.rb ADDED
@@ -0,0 +1,52 @@
1
+ require 'renewable/version'
2
+
3
+ module Renewable
4
+ def initialize(attributes = {}, options = {})
5
+ attributes, options = process_arguments(attributes.dup, options.dup)
6
+ renewable_process_attributes(attributes)
7
+ renewable_process_options(options)
8
+ attributes, options = before_freeze(attributes, options)
9
+ self.freeze
10
+ after_freeze(attributes, options)
11
+ end
12
+
13
+ protected
14
+
15
+ # def renewable_attributes
16
+ # @renwable_attributes
17
+ # end
18
+
19
+ # def renewable_options
20
+ # @renwable_options
21
+ # end
22
+
23
+ private
24
+
25
+ def process_arguments(attributes, options)
26
+ return attributes, options
27
+ end
28
+
29
+ def renewable_process_attributes(attributes)
30
+ attributes.each do |name, value|
31
+ self.instance_variable_set(:"@#{name}", value)
32
+ end
33
+
34
+ #@renwable_attributes = attributes
35
+ end
36
+
37
+ def renewable_process_options(options)
38
+ #@renwable_options = options
39
+ end
40
+
41
+ def before_freeze(attributes, options)
42
+ return attributes, options
43
+ end
44
+
45
+ def after_freeze(attributes, options)
46
+ return attributes, options
47
+ end
48
+ end
49
+
50
+ class Renewable::Object
51
+ include ::Renewable
52
+ end
@@ -0,0 +1,3 @@
1
+ module Renewable
2
+ VERSION = '0.0.1'
3
+ end
data/renewable.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'renewable/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'renewable'
8
+ spec.version = Renewable::VERSION
9
+ spec.authors = ['James Thompson']
10
+ spec.email = %w{james@buypd.com}
11
+ spec.summary = %q{Provides frozen by default objects}
12
+ spec.description = %q{Provides frozen by default objects for more Functional style.}
13
+ spec.homepage = 'https://github.com/plainprogrammer/renewable'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.6'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'rspec', '~> 3.0'
24
+ spec.add_development_dependency 'simplecov', '~> 0.9'
25
+ spec.add_development_dependency 'codeclimate-test-reporter'
26
+ end
@@ -0,0 +1,37 @@
1
+ require 'samples/inheritance_sample'
2
+
3
+ RSpec.describe Renewable do
4
+ context 'used via inheritance' do
5
+ it 'initializes to a frozen object' do
6
+ expect(PersonA.new(birth_date: '1972-06-13').frozen?).to eq(true)
7
+ end
8
+
9
+ it 'assigns all attributes' do
10
+ person = PersonA.new(name: 'John',
11
+ birth_date: '1972-06-13',
12
+ hair_color: 'Brown')
13
+
14
+ expect(person.instance_variable_get(:@name)).to eq('John')
15
+ expect(person.instance_variable_get(:@birth_date)).to eq('1972-06-13')
16
+ expect(person.instance_variable_get(:@hair_color)).to eq('Brown')
17
+ end
18
+
19
+ it 'runs process_arguments callback' do
20
+ expect {
21
+ PersonA.new({}, {raise_process_arguments: true})
22
+ }.to raise_error(ArgumentError, 'entered process_arguments with raise option')
23
+ end
24
+
25
+ it 'runs before_freeze callback' do
26
+ expect {
27
+ PersonA.new({}, {raise_before_freeze: true})
28
+ }.to raise_error(ArgumentError, 'entered before_freeze with raise option')
29
+ end
30
+
31
+ it 'runs after_freeze callback' do
32
+ expect {
33
+ PersonA.new({}, {raise_after_freeze: true})
34
+ }.to raise_error(ArgumentError, 'entered after_freeze with raise option')
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ require 'samples/mixin_sample'
2
+
3
+ RSpec.describe Renewable do
4
+ context 'used as a mixin' do
5
+ it 'initializes to a frozen object' do
6
+ expect(PersonB.new(birth_date: '1972-06-13').frozen?).to eq(true)
7
+ end
8
+
9
+ it 'assigns all attributes' do
10
+ person = PersonB.new(name: 'John',
11
+ birth_date: '1972-06-13',
12
+ hair_color: 'Brown')
13
+
14
+ expect(person.instance_variable_get(:@name)).to eq('John')
15
+ expect(person.instance_variable_get(:@birth_date)).to eq('1972-06-13')
16
+ expect(person.instance_variable_get(:@hair_color)).to eq('Brown')
17
+ end
18
+
19
+ it 'runs process_arguments callback' do
20
+ expect {
21
+ PersonB.new({}, {raise_process_arguments: true})
22
+ }.to raise_error(ArgumentError, 'entered process_arguments with raise option')
23
+ end
24
+
25
+ it 'runs before_freeze callback' do
26
+ expect {
27
+ PersonB.new({}, {raise_before_freeze: true})
28
+ }.to raise_error(ArgumentError, 'entered before_freeze with raise option')
29
+ end
30
+
31
+ it 'runs after_freeze callback' do
32
+ expect {
33
+ PersonB.new({}, {raise_after_freeze: true})
34
+ }.to raise_error(ArgumentError, 'entered after_freeze with raise option')
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ require 'date'
2
+ require 'renewable'
3
+
4
+ class PersonA < Renewable::Object
5
+ attr_accessor :name, :birth_date
6
+
7
+ def age
8
+ Date.today.year - Date.parse(birth_date.to_s).year
9
+ end
10
+
11
+ private
12
+
13
+ def process_arguments(attributes, options)
14
+ if options[:raise_process_arguments]
15
+ raise ArgumentError, 'entered process_arguments with raise option'
16
+ end
17
+
18
+ return attributes, options
19
+ end
20
+
21
+ def before_freeze(attributes, options)
22
+ if options[:raise_before_freeze]
23
+ raise ArgumentError, 'entered before_freeze with raise option'
24
+ end
25
+
26
+ return attributes, options
27
+ end
28
+
29
+ def after_freeze(attributes, options)
30
+ if options[:raise_after_freeze]
31
+ raise ArgumentError, 'entered after_freeze with raise option'
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ require 'date'
2
+ require 'renewable'
3
+
4
+ class PersonB
5
+ include ::Renewable
6
+
7
+ attr_accessor :name, :birth_date
8
+
9
+ def age
10
+ Date.today.year - Date.parse(birth_date.to_s).year
11
+ end
12
+
13
+ private
14
+
15
+ def process_arguments(attributes, options)
16
+ if options[:raise_process_arguments]
17
+ raise ArgumentError, 'entered process_arguments with raise option'
18
+ end
19
+
20
+ return attributes, options
21
+ end
22
+
23
+ def before_freeze(attributes, options)
24
+ if options[:raise_before_freeze]
25
+ raise ArgumentError, 'entered before_freeze with raise option'
26
+ end
27
+
28
+ return attributes, options
29
+ end
30
+
31
+ def after_freeze(attributes, options)
32
+ if options[:raise_after_freeze]
33
+ raise ArgumentError, 'entered after_freeze with raise option'
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ if ENV['CI']
2
+ require 'codeclimate-test-reporter'
3
+ CodeClimate::TestReporter.start
4
+ else
5
+ require 'simplecov'
6
+ SimpleCov.start
7
+ end
8
+
9
+ RSpec.configure do |config|
10
+ config.expect_with :rspec do |expectations|
11
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
12
+ end
13
+
14
+ config.mock_with :rspec do |mocks|
15
+ mocks.verify_partial_doubles = true
16
+ end
17
+
18
+ config.disable_monkey_patching!
19
+ config.warnings = true
20
+ config.profile_examples = 5
21
+ config.order = :random
22
+
23
+ Kernel.srand config.seed
24
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: renewable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - James Thompson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: codeclimate-test-reporter
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Provides frozen by default objects for more Functional style.
84
+ email:
85
+ - james@buypd.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".ruby-gemset"
93
+ - ".ruby-version"
94
+ - ".simplecov"
95
+ - ".travis.yml"
96
+ - Gemfile
97
+ - LICENSE.txt
98
+ - README.md
99
+ - Rakefile
100
+ - lib/renewable.rb
101
+ - lib/renewable/version.rb
102
+ - renewable.gemspec
103
+ - spec/inhertitance_spec.rb
104
+ - spec/mixin_spec.rb
105
+ - spec/samples/inheritance_sample.rb
106
+ - spec/samples/mixin_sample.rb
107
+ - spec/spec_helper.rb
108
+ homepage: https://github.com/plainprogrammer/renewable
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.4.3
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Provides frozen by default objects
132
+ test_files:
133
+ - spec/inhertitance_spec.rb
134
+ - spec/mixin_spec.rb
135
+ - spec/samples/inheritance_sample.rb
136
+ - spec/samples/mixin_sample.rb
137
+ - spec/spec_helper.rb