octothorpe 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,13 @@
1
+ syntax: glob
2
+ .bundle
3
+ Gemfile.lock
4
+ doc/
5
+ pkg/
6
+ spec/reports/
7
+ tmp/
8
+ *.bundle
9
+ *.so
10
+ *.o
11
+ *.a
12
+ mkmf.log
13
+ .rbenv-gemsets
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --color
2
+ --require spec_helper
3
+ --require doc_no_pending
4
+ -I .
5
+ --format progress
@@ -0,0 +1 @@
1
+ 1.9.3-p551
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in octothorpe.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Andy Jones
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.
@@ -0,0 +1,78 @@
1
+ # Octothorpe
2
+
3
+ A very simple hash-like class that borrows a little from OpenStruct, etc.
4
+
5
+ * Treats string and symbol keys as equal
6
+ * Access member objects with ot.>>.keyname
7
+ * Guard conditions allow you to control what returns if key is not present
8
+ * Pretty much read-only, for better or worse
9
+
10
+ Meant to facilitate message-passing between classes.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'octothorpe'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install octothorpe
27
+
28
+ ## Usage
29
+
30
+ Simple example:
31
+
32
+ ot = Octotghorpe.new(one: 1, "two" => 2, "weird key" => 3)
33
+ ot.>>.one # -> 1
34
+ ot.>>.two # -> 2
35
+ ot.get("weird key") # -> 3
36
+
37
+ With guard conditions:
38
+
39
+ ot = Octotghorpe.new(one: 1, "two" => 2)
40
+ ot.guard(Array, :three)
41
+ ot.freeze # optional step - makes OT truly read-only
42
+ ot.>>.three # -> []
43
+ ot.>>.three[9] # valid (of course; returns nil)
44
+
45
+ Octothorpe responds to a good subset of the methods that hash does
46
+ (although, not the write methods).
47
+
48
+ ## FAQ
49
+
50
+ ### Octo-what?
51
+
52
+ An antiquated term for the pound, or, _hash_ key on a phone keyboard. It's a
53
+ sort of a joke, you see. Or, very nearly.
54
+
55
+ ### This is a very small library. Was it really worth it?
56
+
57
+ Maybe not. Feel free to be your own judge.
58
+
59
+ ### What possible use is it?
60
+
61
+ If you are fed up with errors caused because Gem A gives you a hash with string
62
+ keys and Gem B expects symbol keys; or you are tired of putting:
63
+
64
+ hash && (hash[:key] || {})[4]
65
+
66
+ ...then this might just possibly be of use.
67
+
68
+ Alternatively you might try an OpenStruct, Rails' HashWithIndifferentAccess,
69
+ the Hashie gem or the AndAnd gem.
70
+
71
+ ### Why Read-Only?
72
+
73
+ Functional programming.
74
+
75
+ I find it very hard to fully realise the ideals of functional programming in
76
+ Ruby; but as I get closer to those ideals, my code becomes clearer to read and
77
+ my tests become much, much simpler.
78
+
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
@@ -0,0 +1,195 @@
1
+ # Coding: UTF-8
2
+
3
+ require 'forwardable'
4
+
5
+
6
+ ##
7
+ # A very simple hash-like class that borrows a little from OpenStruct, etc.
8
+ #
9
+ # * Treats string and symbol keys as equal
10
+ # * Access member objects with ot.>>.keyname
11
+ # * Guard conditions allow you to control what returns if key is not present
12
+ # * Pretty much read-only, for better or worse
13
+ #
14
+ # Meant to facilitate message-passing between classes.
15
+ #
16
+ # Simple example:
17
+ # ot = Octotghorpe.new(one: 1, "two" => 2, "weird key" => 3)
18
+ # ot.>>.one # -> 1
19
+ # ot.>>.two # -> 2
20
+ # ot.get("weird key") # -> 3
21
+ #
22
+ # With guard conditions:
23
+ # ot = Octotghorpe.new(one: 1, "two" => 2)
24
+ # ot.guard(Array, :three)
25
+ # ot.freeze # optional step - makes OT truly read-only
26
+ # ot.>>.three # -> []
27
+ # ot.>>.three[9] # valid (of course; returns nil)
28
+ #
29
+ # Octothorpe additionally responds to the following methods exactly as a Hash
30
+ # would:
31
+ #
32
+ # empty?, has_key?, has_value?, include?
33
+ # each, each_key, each_value, keys, values
34
+ # select, map, reject, inject
35
+ #
36
+ class Octothorpe
37
+ extend Forwardable
38
+
39
+ def_delegators :@inner_hash, :empty?, :has_key?, :has_value?, :include?
40
+ def_delegators :@inner_hash, :each, :each_key, :each_value, :keys, :values
41
+ def_delegators :@inner_hash, :select, :map, :reject, :inject
42
+
43
+ # Gem version number
44
+ VERSION = '0.1.0'
45
+
46
+
47
+ # Generic Octothorpe error class
48
+ class OctoError < StandardError; end
49
+
50
+ # Raised when Octothorpe needs a hash but didn't get one
51
+ class BadHash < OctoError; end
52
+
53
+ # Raised when caller tries to modify a frozen Octothorpe
54
+ class Frozen < OctoError; end
55
+
56
+
57
+ ##
58
+ # Inner class for storage. This is to minimise namespace collision with key
59
+ # names. Not exposed to Octothorpe's caller.
60
+ #
61
+ class Storage
62
+ attr_reader :store
63
+
64
+ def initialize(hash)
65
+ @store = hash
66
+ end
67
+
68
+ def method_missing(method, *attrs)
69
+ super if (block_given? || !attrs.empty?)
70
+ @store[method.to_sym]
71
+ end
72
+
73
+ end
74
+ ##
75
+
76
+
77
+ ##
78
+ # :call-seq:
79
+ # ot = Octothrpe.new(hash)
80
+ #
81
+ # Initialise an Octothorpe object by passing it a hash.
82
+ #
83
+ # You can create an empty OT by calling Octothorpe.new, but there's probably
84
+ # little utility in that, given that it is read-only.
85
+ #
86
+ # If you pass anything other than nil or something OT can treat as a Hash,
87
+ # you will cause an Octothorpe::BadHash exception.
88
+ #
89
+ def initialize(hash=nil)
90
+ @store = Storage.new( symbol_hash(hash || {}) )
91
+ @inner_hash = @store.store
92
+ end
93
+
94
+
95
+ ##
96
+ # :call-seq:
97
+ # ot.>>.keyname
98
+ #
99
+ # You can use >> to access member objects in somewhat the same way as an
100
+ # OpenStruct.
101
+ #
102
+ # ot = Octotghorpe.new(one: 1, "two" => 2)
103
+ # ot.>>.one # -> 1
104
+ #
105
+ # This will not work for members that have keys with spaces in, or keys which
106
+ # have the same name as methods on Object. Use _get_ for those.
107
+ #
108
+ def >>; @store; end
109
+
110
+
111
+ ##
112
+ # :call-seq:
113
+ # ot.get(key)
114
+ # ot.send(key)
115
+ #
116
+ # You can use get to access member object values instead of the >> syntax.
117
+ #
118
+ # Unlike >>, this works for keys with spaces, or keys that have the same name
119
+ # as methods on Object.
120
+ #
121
+ def get(key); @store.store[key.to_sym]; end
122
+
123
+ alias send get
124
+
125
+
126
+ ##
127
+ # Returns a hash of the object.
128
+ #
129
+ def to_h; @store.store; end
130
+
131
+
132
+ ##
133
+ # :call-seq:
134
+ # ot.guard( class, key [, key, ...] )
135
+ #
136
+ # Guarantees the initial state of a memnber. Each key that is not already
137
+ # present will be set to <class>.new. Has no effect if key is already
138
+ # present.
139
+ #
140
+ # Class must be some class Thing that can respond to a vanilla Thing.new.
141
+ #
142
+ # Note that this is the only time that you can modify an Octothorpe object
143
+ # once it is created. If you call _freeze_ on an it, it will become genuinely
144
+ # read-only, and any call to guard from then on will raise Octothorpe::Frozen.
145
+ #
146
+ def guard(klass, *keys)
147
+ raise Frozen if self.frozen?
148
+ keys.map(&:to_sym).each{|k| @store.store[k] ||= klass.new }
149
+ self
150
+ end
151
+
152
+
153
+ ##
154
+ # :call-seq:
155
+ # ot.merge(other) -> new_ot
156
+ # ot.merge(other){|key, oldval, newval| block} -> new_ot
157
+ #
158
+ # Exactly has _Hash.merge_, but returns a new Octothorpe object.
159
+ #
160
+ # You may pass a hash or an octothorpe. Raises Octothorpe::BadHash
161
+ # if it is anything else.
162
+ #
163
+ def merge(other)
164
+ otherHash = symbol_hash(other)
165
+
166
+ merged =
167
+ if block_given?
168
+ @store.store.merge(otherHash) {|key,old,new| yield key, old, new }
169
+ else
170
+ @store.store.merge(otherHash)
171
+ end
172
+
173
+ return Octothorpe.new(merged)
174
+ end
175
+
176
+
177
+ private
178
+
179
+
180
+ ##
181
+ # Try to return thing as a hash with symbols for keys
182
+ #
183
+ def symbol_hash(thing)
184
+ if thing.kind_of?(Octothorpe)
185
+ thing.to_h
186
+ else
187
+ thing.each_with_object({}) {|(k,v),m| m[k.to_sym] = v }
188
+ end
189
+ rescue
190
+ raise BadHash
191
+ end
192
+
193
+
194
+ end
195
+
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'octothorpe'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "octothorpe"
8
+ spec.version = Octothorpe::VERSION
9
+ spec.authors = ["Andy Jones"]
10
+ spec.email = ["andy@twosticksconsulting.co.uk"]
11
+ spec.summary = %q{Like a Hash. Better for message passing between classes, I hope.}
12
+
13
+ spec.description = <<-DESCRIPTION.gsub(/^\s+/, '')
14
+ A very simple hash-like class that borrows a little from OpenStruct, etc.
15
+
16
+ * Treats string and symbol keys as equal
17
+ * Access member objects with ot.>>.keyname
18
+ * Guard conditions allow you to control what returns if key is not present
19
+ * Pretty much read-only, for better or worse
20
+
21
+ Meant to facilitate message-passing between classes.
22
+ DESCRIPTION
23
+
24
+ spec.homepage = ""
25
+ spec.license = "MIT"
26
+
27
+ spec.files = `hg status -macn0`.split("\x0")
28
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
29
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.7"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+ spec.add_development_dependency "rspec"
35
+ spec.add_development_dependency "pry"
36
+ spec.add_development_dependency "pry-doc"
37
+ end
@@ -0,0 +1,5 @@
1
+ class DocNoPending < RSpec::Core::Formatters::DocumentationFormatter
2
+ RSpec::Core::Formatters.register self, :example_pending
3
+
4
+ def example_pending(notification); end
5
+ end
@@ -0,0 +1,205 @@
1
+ require 'octothorpe'
2
+
3
+ describe Octothorpe do
4
+
5
+
6
+ before do
7
+ @hash = {one: 'a', 'two' => 2, dup: 3, "weird key" => 4}
8
+ @hash2 = @hash.each_with_object({}) {|(k,v),m| m[k.to_sym] = v }
9
+ @ot = Octothorpe.new(@hash)
10
+ end
11
+
12
+
13
+ describe "#new" do
14
+
15
+ it "takes a hash" do
16
+ expect{ Octothorpe.new(one: 2, three: 4) }.not_to raise_exception
17
+ end
18
+
19
+ it "accepts no arguments" do
20
+ expect{ Octothorpe.new }.not_to raise_exception
21
+ end
22
+
23
+ it "raises Octothorpe::BadHash if passed non-hash, non-nil" do
24
+ expect{ Octothorpe.new("hello") }.to raise_exception Octothorpe::BadHash
25
+ expect{ Octothorpe.new(:boo) }.to raise_exception Octothorpe::BadHash
26
+ expect{ Octothorpe.new(14) }.to raise_exception Octothorpe::BadHash
27
+ end
28
+
29
+ end
30
+
31
+
32
+ describe "#>>" do
33
+
34
+ it "returns the value with the given key" do
35
+ expect(@ot.>>.one).to eq @hash2[:one]
36
+ expect(@ot.>>.two).to eq @hash2[:two]
37
+ end
38
+
39
+ it "returns nil when given a non-key value" do
40
+ expect(@ot.>>.three).to be_nil
41
+ end
42
+
43
+ it "throws an exception if passed a parameter or block" do
44
+ expect{ @ot.>>.three(1) }.to raise_exception
45
+ expect{ @ot.>>.three{|x| puts x} }.to raise_exception
46
+ end
47
+
48
+ end
49
+
50
+
51
+ describe "#get" do
52
+
53
+ it "returns the value with the given key" do
54
+ expect( @ot.get(:one) ).to eq @hash2[:one]
55
+ expect( @ot.get(:two) ).to eq @hash2[:two]
56
+ end
57
+
58
+ it "returns nil when given a non-key value" do
59
+ expect( @ot.get(:three) ).to be_nil
60
+ end
61
+
62
+ it "will return odd keys" do
63
+ expect( @ot.get(:dup) ).to eq @hash2[:dup]
64
+ expect( @ot.get('weird key') ).to eq @hash2[:'weird key']
65
+ end
66
+
67
+ end
68
+
69
+
70
+ describe "#to_h" do
71
+
72
+ it "dumps the OT as a hash" do
73
+ expect( @ot.to_h ).to eq @hash2
74
+ end
75
+
76
+ end
77
+
78
+
79
+ describe "#guard" do
80
+
81
+ it "sets the given fields with a default value for the class" do
82
+ @ot.guard(Array, :alpha)
83
+ @ot.guard(Hash, :beta)
84
+
85
+ expect( @ot.>>.alpha ).to eq([])
86
+ expect( @ot.>>.beta ).to eq({})
87
+ end
88
+
89
+ it "returns self" do
90
+ expect( @ot.guard(Array, :foo) ).to eq @ot
91
+ end
92
+
93
+ it "only sets the field if it does not already exist" do
94
+ @ot.guard(Array, :one)
95
+ expect( @ot.>>.one ).to eq @hash2[:one]
96
+ end
97
+
98
+ it "accepts a list of keys" do
99
+ @ot.guard(Array, :fred, :daphne, "velma")
100
+ otHash = @ot.to_h
101
+ expect( otHash[:fred] ).to eq([])
102
+ expect( otHash[:daphne] ).to eq([])
103
+ expect( otHash[:velma] ).to eq([])
104
+ end
105
+
106
+ it "raises Octothorpe::Frozen if the OT is frozen" do
107
+ @ot.freeze
108
+ expect{ @ot.guard(Hash, :foo) }.to raise_exception Octothorpe::Frozen
109
+ end
110
+
111
+ end
112
+
113
+
114
+ describe "#merge" do
115
+ before do
116
+ @other = {fred: 1, "velma" => 2}
117
+ end
118
+
119
+ it "accepts a hash" do
120
+ expect{ @ot.merge(@other) }.not_to raise_exception
121
+ end
122
+
123
+ it "accepts another OT" do
124
+ ot2 = Octothorpe.new(@other)
125
+ expect{ @ot.merge(ot2) }.not_to raise_exception
126
+ end
127
+
128
+ it "raises Octothorpe::BadHash if the parameter cannot be turned into a hash" do
129
+ expect{ @ot.merge(12) }.to raise_exception Octothorpe::BadHash
130
+ expect{ @ot.merge(nil) }.to raise_exception Octothorpe::BadHash
131
+ end
132
+
133
+ it "returns a new OT that combines the self OT with another" do
134
+ ot2 = @ot.merge(@other)
135
+ other2 = @other.each_with_object({}) {|(k,v),m| m[k.to_sym] = v }
136
+
137
+ expect( ot2 ).to be_a( Octothorpe )
138
+ expect( ot2.to_h ).to eq( @hash2.merge(other2) )
139
+ end
140
+
141
+ it "honours the Hash.merge block format" do
142
+ h1 = {one: 1, two: 2}
143
+ h2 = {one: 3, two: 4}
144
+
145
+ ot = Octothorpe.new(h1)
146
+ ans = ot.merge(h2){|k,o,n| o.to_s + '.' + n.to_s }
147
+
148
+ expect( ans.to_h ).to eq( {one: '1.3', two: '2.4'} )
149
+ end
150
+
151
+ end
152
+
153
+
154
+ describe "(miscelaneous other stuff)" do
155
+ # I "imagine" that the actual class uses Forwardable, but the test code
156
+ # shouldn't know or care about that. In any case, just testing with
157
+ # responds_to always feels like cheating.
158
+
159
+ it "behaves like a Hash for a bunch of query methods" do
160
+ expect( @ot.empty? ).not_to eq true
161
+ expect( Octothorpe.new().empty? ).to eq true
162
+
163
+ expect( @ot.has_key?(:two) ).to eq true
164
+ expect( @ot.has_key?(:four) ).not_to eq true
165
+
166
+ expect( @ot.has_value?(3) ).to eq true
167
+ expect( @ot.has_value?(14) ).not_to eq true
168
+
169
+ expect( @ot.include?(:two) ).to eq true
170
+ expect( @ot.include?(:foo) ).not_to eq true
171
+ end
172
+
173
+ it "behaves like a hash for a bunch of methods that return an array" do
174
+ expect( @ot.keys ).to eq(@hash2.keys)
175
+ expect( @ot.values ).to eq(@hash2.values)
176
+
177
+ expect( @ot.map{|k,v| k} ).to eq( @hash2.map{|k,v| k} )
178
+
179
+ ans = @hash2.select{|k,_| k == :two }
180
+ expect( @ot.select{|k,v| k == :two } ).to eq( {two: 2} )
181
+
182
+ ans = @hash2.reject{|k,_| k == :two }
183
+ expect( @ot.reject{|k,_| k == :two } ).to eq( ans )
184
+ end
185
+
186
+ it "behaves like a hash for a bunch of iterators" do
187
+
188
+ expect( @ot.inject(0){|m,(k,v)| m += v.to_i } ).to eq 9
189
+
190
+ expect{ @ot.each{|k,v| } }.not_to raise_exception
191
+ ans = []; @ot.each{|k,_| ans << k}
192
+ expect( ans ).to eq( @hash2.keys )
193
+
194
+ ans = []; @ot.each_key{|k| ans << k}
195
+ expect(ans).to eq( @hash2.keys )
196
+
197
+ ans = []; @ot.each_value{|v| ans << v}
198
+ expect(ans).to eq( @hash2.values )
199
+ end
200
+
201
+ end
202
+
203
+
204
+ end
205
+
@@ -0,0 +1,96 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
4
+ # file to always be loaded, without a need to explicitly require it in any files.
5
+ #
6
+ # Given that it is always loaded, you are encouraged to keep this file as
7
+ # light-weight as possible. Requiring heavyweight dependencies from this file
8
+ # will add to the boot time of your test suite on EVERY test run, even for an
9
+ # individual file that may not need all of that loaded. Instead, consider making
10
+ # a separate helper file that requires the additional dependencies and performs
11
+ # the additional setup, and require it from the spec files that actually need it.
12
+ #
13
+ # The `.rspec` file also contains a few flags that are not defaults but that
14
+ # users commonly want.
15
+ #
16
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
17
+ RSpec.configure do |config|
18
+ # rspec-expectations config goes here. You can use an alternate
19
+ # assertion/expectation library such as wrong or the stdlib/minitest
20
+ # assertions if you prefer.
21
+ config.expect_with :rspec do |expectations|
22
+ # This option will default to `true` in RSpec 4. It makes the `description`
23
+ # and `failure_message` of custom matchers include text for helper methods
24
+ # defined using `chain`, e.g.:
25
+ # be_bigger_than(2).and_smaller_than(4).description
26
+ # # => "be bigger than 2 and smaller than 4"
27
+ # ...rather than:
28
+ # # => "be bigger than 2"
29
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
30
+ end
31
+
32
+ # rspec-mocks config goes here. You can use an alternate test double
33
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
34
+ config.mock_with :rspec do |mocks|
35
+ # Prevents you from mocking or stubbing a method that does not exist on
36
+ # a real object. This is generally recommended, and will default to
37
+ # `true` in RSpec 4.
38
+ mocks.verify_partial_doubles = true
39
+ end
40
+
41
+ if config.files_to_run.one?
42
+ # Use the documentation formatter for detailed output,
43
+ # unless a formatter has already been configured
44
+ # (e.g. via a command-line flag).
45
+ config.default_formatter = 'doc'
46
+ end
47
+
48
+ # The settings below are suggested to provide a good initial experience
49
+ # with RSpec, but feel free to customize to your heart's content.
50
+ =begin
51
+ # These two settings work together to allow you to limit a spec run
52
+ # to individual examples or groups you care about by tagging them with
53
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
54
+ # get run.
55
+ config.filter_run :focus
56
+ config.run_all_when_everything_filtered = true
57
+
58
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
59
+ # For more details, see:
60
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
61
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
62
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
63
+ config.disable_monkey_patching!
64
+
65
+ # This setting enables warnings. It's recommended, but in some cases may
66
+ # be too noisy due to issues in dependencies.
67
+ config.warnings = true
68
+
69
+ # Many RSpec users commonly either run the entire suite or an individual
70
+ # file, and it's useful to allow more verbose output when running an
71
+ # individual spec file.
72
+ if config.files_to_run.one?
73
+ # Use the documentation formatter for detailed output,
74
+ # unless a formatter has already been configured
75
+ # (e.g. via a command-line flag).
76
+ config.default_formatter = 'doc'
77
+ end
78
+
79
+ # Print the 10 slowest examples and example groups at the
80
+ # end of the spec run, to help surface which specs are running
81
+ # particularly slow.
82
+ config.profile_examples = 10
83
+
84
+ # Run specs in random order to surface order dependencies. If you find an
85
+ # order dependency and want to debug it, you can fix the order by providing
86
+ # the seed, which is printed after each run.
87
+ # --seed 1234
88
+ config.order = :random
89
+
90
+ # Seed global randomization in this process using the `--seed` CLI option.
91
+ # Setting this allows you to use `--seed` to deterministically reproduce
92
+ # test failures related to randomization by passing the same `--seed` value
93
+ # as the one that triggered the failure.
94
+ Kernel.srand config.seed
95
+ =end
96
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: octothorpe
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andy Jones
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-09-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.7'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.7'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '10.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '10.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: pry
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: pry-doc
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: ! 'A very simple hash-like class that borrows a little from OpenStruct,
95
+ etc.
96
+
97
+ * Treats string and symbol keys as equal
98
+
99
+ * Access member objects with ot.>>.keyname
100
+
101
+ * Guard conditions allow you to control what returns if key is not present
102
+
103
+ * Pretty much read-only, for better or worse
104
+
105
+ Meant to facilitate message-passing between classes.
106
+
107
+ '
108
+ email:
109
+ - andy@twosticksconsulting.co.uk
110
+ executables: []
111
+ extensions: []
112
+ extra_rdoc_files: []
113
+ files:
114
+ - .hgignore
115
+ - .rspec
116
+ - .ruby-version
117
+ - Gemfile
118
+ - LICENSE.txt
119
+ - README.md
120
+ - Rakefile
121
+ - lib/octothorpe.rb
122
+ - octothorpe.gemspec
123
+ - spec/doc_no_pending.rb
124
+ - spec/octothorpe_spec.rb
125
+ - spec/spec_helper.rb
126
+ homepage: ''
127
+ licenses:
128
+ - MIT
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ! '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 1.8.23.2
148
+ signing_key:
149
+ specification_version: 3
150
+ summary: Like a Hash. Better for message passing between classes, I hope.
151
+ test_files:
152
+ - spec/doc_no_pending.rb
153
+ - spec/octothorpe_spec.rb
154
+ - spec/spec_helper.rb
155
+ has_rdoc: