significance 0.1.1 → 0.2.0
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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/CHANGELOG.rdoc +15 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +31 -0
- data/{MIT-LICENSE → LICENSE.txt} +1 -1
- data/README.rdoc +21 -16
- data/Rakefile +50 -27
- data/VERSION +1 -0
- data/lib/significance/core_ext.rb +2 -0
- data/lib/significance/core_ext/hash.rb +4 -2
- data/lib/significance/core_ext/object.rb +5 -5
- data/lib/significance/core_ext/set.rb +5 -0
- data/lib/significance/core_ext/string.rb +2 -2
- data/spec/significance_spec.rb +220 -0
- data/spec/spec_helper.rb +12 -0
- metadata +80 -98
- data/lib/significance/version.rb +0 -3
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/assets/javascripts/application.js +0 -9
- data/test/dummy/app/assets/stylesheets/application.css +0 -7
- data/test/dummy/app/controllers/application_controller.rb +0 -3
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -45
- data/test/dummy/config/boot.rb +0 -10
- data/test/dummy/config/database.yml +0 -25
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -30
- data/test/dummy/config/environments/production.rb +0 -60
- data/test/dummy/config/environments/test.rb +0 -39
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/inflections.rb +0 -10
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/secret_token.rb +0 -7
- data/test/dummy/config/initializers/session_store.rb +0 -8
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -5
- data/test/dummy/config/routes.rb +0 -58
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +0 -16
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +0 -13
- data/test/dummy/log/test.log +0 -0
- data/test/dummy/public/404.html +0 -26
- data/test/dummy/public/422.html +0 -26
- data/test/dummy/public/500.html +0 -26
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +0 -6
- data/test/significance_test.rb +0 -7
- data/test/test_helper.rb +0 -10
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/CHANGELOG.rdoc
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", "~> 2.11.0"
|
10
|
+
gem "rdoc", "~> 3.12"
|
11
|
+
gem "bundler", ">= 1.0.0"
|
12
|
+
gem "jeweler", "~> 1.8.4"
|
13
|
+
# gem "rcov", ">= 0"
|
14
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.3)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.8.4)
|
7
|
+
bundler (~> 1.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
rdoc
|
11
|
+
json (1.7.5)
|
12
|
+
rake (0.9.2.2)
|
13
|
+
rdoc (3.12)
|
14
|
+
json (~> 1.4)
|
15
|
+
rspec (2.11.0)
|
16
|
+
rspec-core (~> 2.11.0)
|
17
|
+
rspec-expectations (~> 2.11.0)
|
18
|
+
rspec-mocks (~> 2.11.0)
|
19
|
+
rspec-core (2.11.1)
|
20
|
+
rspec-expectations (2.11.3)
|
21
|
+
diff-lcs (~> 1.1.3)
|
22
|
+
rspec-mocks (2.11.3)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
bundler (>= 1.0.0)
|
29
|
+
jeweler (~> 1.8.4)
|
30
|
+
rdoc (~> 3.12)
|
31
|
+
rspec (~> 2.11.0)
|
data/{MIT-LICENSE → LICENSE.txt}
RENAMED
data/README.rdoc
CHANGED
@@ -4,27 +4,32 @@ Similar in behavior to Object#presence defined in ActiveSupport, Significance is
|
|
4
4
|
|
5
5
|
The utility of this gem can best be demonstrated when considering the merging of two hashes. Under normal circumstances the mere existence of an equivalent key in the second hash results in its overriding the corresponding value in the original hash. Using Hash#significant_merge, however, the second hash will retain only key-value pairs whose values are "significant," even applying the significance filter recursively into child hashes or arrays.
|
6
6
|
|
7
|
+
== Usage:
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
ruby-1.9.2-head :025 > [h1, h2, h3, h4, h5].each_with_index{|hsh, i| puts("# #{hsh}.significant") || puts("# => #{hsh.significant}"); nil}
|
11
|
-
{:a=>1, :b=>2, :c=>3, :d=>4}.significant
|
12
|
-
=> {:a=>1, :b=>2, :c=>3, :d=>4}
|
13
|
-
|
14
|
-
{:a=>1, :b=>nil, :c=>[], :d=>{}, :e=>" ", :f=>"798", :g=>""}.significant
|
15
|
-
=> {:a=>1, :f=>"798"}
|
9
|
+
gem 'significance', :git => "git://github.com/caleon/significance.git"
|
16
10
|
|
17
|
-
{:a=>1, :b=>nil, :c=>[nil], :d=>{:thing=>nil}, :e=>" [] ", :f=>" 789"}.significant
|
18
|
-
=> {:a=>1, :e=>"[]", :f=>"789"}
|
19
11
|
|
20
|
-
|
21
|
-
=> {:a=>1}
|
12
|
+
== Examples:
|
22
13
|
|
23
|
-
|
24
|
-
|
14
|
+
ruby-1.9.2-head :025 > [h1, h2, h3, h4, h5].each_with_index{|hsh, i| puts("# #{hsh}.significant") || puts("# => #{hsh.significant}"); nil}
|
15
|
+
{:a=>1, :b=>2, :c=>3, :d=>4}.significant
|
16
|
+
=> {:a=>1, :b=>2, :c=>3, :d=>4}
|
17
|
+
|
18
|
+
{:a=>1, :b=>nil, :c=>[], :d=>{}, :e=>" ", :f=>"798", :g=>""}.significant
|
19
|
+
=> {:a=>1, :f=>"798"}
|
20
|
+
|
21
|
+
{:a=>1, :b=>nil, :c=>[nil], :d=>{:thing=>nil}, :e=>" [] ", :f=>" 789"}.significant
|
22
|
+
=> {:a=>1, :e=>"[]", :f=>"789"}
|
23
|
+
|
24
|
+
{:a=>1, :b=>nil, :c=>[nil, nil], :d=>{:thing=>nil, :thing2=>[]}, :e=>{:thing3=>{:thing4=>{}}}, :f=>[{}], :g=>[{}, {}]}.significant
|
25
|
+
=> {:a=>1}
|
26
|
+
|
27
|
+
{:a=>1, :b=>nil, :c=>[nil, {nil=>1, 27=>""}, " "], :d=>{:thing=>{:z=>{:y=>{:x=>{:w=>{:v=>{:u=>[:t, ":s", {:r=>:q}]}}}}}}}, :f=>[{}, [""]]}.significant
|
28
|
+
=> {:a=>1, :c=>[{nil=>1}], :d=>{:thing=>{:z=>{:y=>{:x=>{:w=>{:v=>{:u=>[:t, ":s", {:r=>:q}]}}}}}}}}
|
25
29
|
|
26
|
-
|
27
|
-
|
30
|
+
[nil, 1, 3, '', [], [nil, [{}, 2]], ['']].significant
|
31
|
+
=> [1, 3, [[2]]]
|
32
|
+
|
28
33
|
|
29
34
|
=== TODO: utilize the following:
|
30
35
|
|
data/Rakefile
CHANGED
@@ -1,37 +1,60 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
2
5
|
begin
|
3
|
-
|
4
|
-
rescue
|
5
|
-
puts
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
6
11
|
end
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "significance"
|
18
|
+
gem.homepage = "http://github.com/caleon/significance"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Similar in behavior to Object#presence defined in ActiveSupport, Significance is a state which determines not just the blank-ness of an object but whether or not the non-blank object has any real-world value.}
|
21
|
+
gem.description = <<-DESC
|
22
|
+
Similar in behavior to Object#presence defined in ActiveSupport,
|
23
|
+
Significance is a state which determines not just the blank-ness of an
|
24
|
+
object but whether or not the non-blank object has any real-world value.
|
25
|
+
The utility of this gem can best be demonstrated when considering the
|
26
|
+
merging of two hashes. Under normal circumstances the mere existence of an
|
27
|
+
equivalent key in the second hash results in its overriding the
|
28
|
+
corresponding value in the original hash. Using Hash#significant_merge,
|
29
|
+
however, the second hash will retain only key-value pairs whose values are
|
30
|
+
"significant," even applying the significance filter recursively into child
|
31
|
+
hashes or arrays.
|
32
|
+
DESC
|
33
|
+
gem.email = "caleon@gmail.com"
|
34
|
+
gem.authors = ["caleon"]
|
35
|
+
# dependencies defined in Gemfile
|
13
36
|
end
|
37
|
+
Jeweler::RubygemsDotOrgTasks.new
|
14
38
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
rdoc.rdoc_files.include('README.rdoc')
|
20
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
39
|
+
require 'rspec/core'
|
40
|
+
require 'rspec/core/rake_task'
|
41
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
42
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
21
43
|
end
|
22
44
|
|
45
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
46
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
47
|
+
spec.rcov = true
|
48
|
+
end
|
23
49
|
|
50
|
+
task :default => :spec
|
24
51
|
|
25
|
-
|
26
|
-
|
27
|
-
|
52
|
+
require 'rdoc/task'
|
53
|
+
Rake::RDocTask.new do |rdoc|
|
54
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
28
55
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
t.verbose = false
|
56
|
+
rdoc.rdoc_dir = 'rdoc'
|
57
|
+
rdoc.title = "Significance #{version}"
|
58
|
+
rdoc.rdoc_files.include('README*')
|
59
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
34
60
|
end
|
35
|
-
|
36
|
-
|
37
|
-
task :default => :test
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
@@ -1,5 +1,7 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
1
2
|
require 'significance/core_ext/object'
|
2
3
|
require 'significance/core_ext/false_class'
|
3
4
|
require 'significance/core_ext/string'
|
4
5
|
require 'significance/core_ext/array'
|
6
|
+
require 'significance/core_ext/set'
|
5
7
|
require 'significance/core_ext/hash'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/hash/reverse_merge'
|
2
|
+
|
1
3
|
class Hash # also deep now.
|
2
4
|
def significant
|
3
5
|
Hash.new.tap { |hsh| each(&significance_each_block(hsh)) }
|
@@ -5,12 +7,12 @@ class Hash # also deep now.
|
|
5
7
|
|
6
8
|
# also allows nil so we don't need Something.new(params.merge(params[:etc] || {}))
|
7
9
|
def significant_merge(other_hash={})
|
8
|
-
return self unless (other_hash ||= {}).significant?
|
10
|
+
return self unless (other_hash ||= {}).significant.present?
|
9
11
|
merge(other_hash.significant)
|
10
12
|
end
|
11
13
|
# destructive
|
12
14
|
def significant_merge!(other_hash={})
|
13
|
-
return self unless (other_hash ||= {}).significant?
|
15
|
+
return self unless (other_hash ||= {}).significant.present?
|
14
16
|
merge!(other_hash.significant)
|
15
17
|
end
|
16
18
|
# need to call significant on self now.
|
@@ -1,8 +1,8 @@
|
|
1
1
|
class Object # `significant == self` is the way to end the recursion.
|
2
|
-
def blank?
|
3
|
-
|
4
|
-
end
|
5
|
-
|
2
|
+
# def blank?
|
3
|
+
# respond_to?(:empty?) ? empty? : !self
|
4
|
+
# end
|
5
|
+
|
6
6
|
def significant?
|
7
7
|
!blank? and significant == self
|
8
8
|
end
|
@@ -10,7 +10,7 @@ class Object # `significant == self` is the way to end the recursion.
|
|
10
10
|
def significant
|
11
11
|
self
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def keep_significant
|
15
15
|
respond_to?(:replace) ? replace(significant) : significant
|
16
16
|
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'Significance' do
|
4
|
+
|
5
|
+
describe Object do
|
6
|
+
|
7
|
+
describe 'Basic check for methods being available' do
|
8
|
+
|
9
|
+
it { should respond_to :significant? }
|
10
|
+
it { should respond_to :significant }
|
11
|
+
it { should respond_to :keep_significant }
|
12
|
+
it { should respond_to :significant! }
|
13
|
+
it { should respond_to :significance }
|
14
|
+
it { should respond_to :significant_significance }
|
15
|
+
it { should respond_to :significant_significance? }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#significant?' do
|
19
|
+
it { should be_significant }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#significant' do
|
23
|
+
it 'returns self' do
|
24
|
+
subject.significant.should be subject
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#keep_significant' do
|
29
|
+
it 'returns self' do
|
30
|
+
subject.should_not respond_to :replace
|
31
|
+
subject.keep_significant.should be subject
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#significant!' do
|
36
|
+
it 'is an alias for #keep_significant' do
|
37
|
+
subject.should_receive(:keep_significant)
|
38
|
+
subject.significant!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#significant_significance' do
|
43
|
+
before(:each) do
|
44
|
+
significant = mock('significant')
|
45
|
+
subject.should_receive(:significant).and_return(significant)
|
46
|
+
significant.should_receive(:significance)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'chain-calls #significant and #significance' do
|
50
|
+
subject.significant_significance
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'is aliased to #sigsig' do
|
54
|
+
subject.sigsig
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#significant_significance?' do
|
59
|
+
before(:each) do
|
60
|
+
sigsig = mock('sigsig')
|
61
|
+
subject.should_receive(:significant_significance).and_return(sigsig)
|
62
|
+
sigsig.should_receive(:significant?)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'chain-calls #significant_significance and #significant?' do
|
66
|
+
subject.significant_significance?
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'is aliased as #sigsig?' do
|
70
|
+
subject.sigsig?
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe false do
|
76
|
+
it { should be_significant }
|
77
|
+
end
|
78
|
+
|
79
|
+
describe String do
|
80
|
+
|
81
|
+
describe '#significant' do
|
82
|
+
it 'strips whitespaces on either end' do
|
83
|
+
subject.should_receive(:strip)
|
84
|
+
subject.significant
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#strictly_significant' do
|
89
|
+
it 'removes all whitespaces within' do
|
90
|
+
subject.should_receive(:gsub).with(/\s+/, '')
|
91
|
+
subject.strictly_significant
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe Array do
|
97
|
+
let(:element) { mock('el', :significant_significance? => true) }
|
98
|
+
subject { [element, element] }
|
99
|
+
describe '#significant' do
|
100
|
+
|
101
|
+
it 'calls #significant_significance? on each element' do
|
102
|
+
element.should_receive(:significant_significance?).twice
|
103
|
+
subject.significant
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'calls #significant on the filtered elements' do
|
107
|
+
element.should_receive(:significant).twice.and_return(element)
|
108
|
+
subject.significant.should =~ [element, element]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe Set do
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
describe Hash do
|
118
|
+
|
119
|
+
describe '#significant' do
|
120
|
+
|
121
|
+
it 'returns a new Hash' do
|
122
|
+
subject.significant.should_not be subject
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'calls #significance_each_block on each' do
|
126
|
+
# hsh.stub(:significance_each_block).and_return(Proc.new { |x| x.to_s })
|
127
|
+
subject.should_receive(:each)#.with(kind_of(Proc))
|
128
|
+
subject.significant
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
let(:other_hash) { mock('other_hash') }
|
133
|
+
|
134
|
+
describe '#significant_merge' do
|
135
|
+
|
136
|
+
context 'when other hash is empty' do
|
137
|
+
before { other_hash.stub(:significant => {}) }
|
138
|
+
|
139
|
+
it 'returns self' do
|
140
|
+
subject.significant_merge(other_hash).should be subject
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'when other hash is significant' do
|
145
|
+
before { other_hash.stub(:significant => other_hash,
|
146
|
+
:present? => true) }
|
147
|
+
|
148
|
+
it 'calls merge with #significant on other hash' do
|
149
|
+
other_hash.should_receive(:significant).twice
|
150
|
+
subject.should_receive(:merge).with(other_hash)
|
151
|
+
subject.significant_merge(other_hash)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe '#significant_merge!' do
|
157
|
+
|
158
|
+
context 'when other hash is empty' do
|
159
|
+
before { other_hash.stub(:significant => {}) }
|
160
|
+
|
161
|
+
it 'returns self' do
|
162
|
+
subject.significant_merge!(other_hash).should be subject
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'when other hash is significant' do
|
167
|
+
before { other_hash.stub(:significant => other_hash,
|
168
|
+
:present? => true) }
|
169
|
+
|
170
|
+
it 'calls merge! with #significant on other hash' do
|
171
|
+
other_hash.should_receive(:significant).twice
|
172
|
+
subject.should_receive(:merge!).with(other_hash)
|
173
|
+
subject.significant_merge!(other_hash)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe '#reverse_significant_merge' do
|
179
|
+
|
180
|
+
context 'when other hash is empty' do
|
181
|
+
it 'returns self' do
|
182
|
+
other_hash.stub(:merge => :merged_hash)
|
183
|
+
subject.reverse_significant_merge(other_hash).should be :merged_hash
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context 'when other hash is significant' do
|
188
|
+
before { other_hash.stub(:significant => other_hash,
|
189
|
+
:present? => true) }
|
190
|
+
|
191
|
+
it 'calls merge with #significant on other hash' do
|
192
|
+
subject.should_receive(:significant).and_return(subject)
|
193
|
+
subject.should_receive(:reverse_merge).with(other_hash)
|
194
|
+
subject.reverse_significant_merge(other_hash)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe '#reverse_significant_merge!' do
|
200
|
+
|
201
|
+
context 'when other hash is empty' do
|
202
|
+
it 'returns self' do
|
203
|
+
subject.stub(:merge! => :merged_hash)
|
204
|
+
subject.reverse_significant_merge!(other_hash).should be :merged_hash
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context 'when other hash is significant' do
|
209
|
+
before { other_hash.stub(:significant => other_hash,
|
210
|
+
:present? => true) }
|
211
|
+
|
212
|
+
it 'calls merge with #significant on other hash' do
|
213
|
+
subject.should_receive(:significant).and_return(subject)
|
214
|
+
subject.should_receive(:reverse_merge!).with(other_hash)
|
215
|
+
subject.reverse_significant_merge!(other_hash)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|