delegate_when_nil 0.0.1 → 0.0.2
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 +7 -0
- data/README.md +37 -25
- data/delegate_when_nil.gemspec +1 -2
- data/lib/delegate_when_nil.rb +34 -21
- data/lib/delegate_when_nil/version.rb +1 -1
- data/spec/delegate_when_nil_spec.rb +16 -12
- data/spec/spec_helper.rb +1 -1
- metadata +14 -34
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9792d84c37ea5e3c15dc4b6d490fdb537c978e9c
|
4
|
+
data.tar.gz: 7a9ef09e419e7a8a142e392799bb1a57e8faafee
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7a7b282e90b32c49e250af8536c118bd2e820139cde0b41b17ea1b55c31c9de2648f3100b46d87f97869774aadbeae8526187fb9663330d8085ee4346779ea91
|
7
|
+
data.tar.gz: c17356ebf0873edb2d54ae7b7779f510e6687fcf4c962a3773c3654c13233943b089dc8a85c16eb7f8008ab9aef8edcd9b2b19a4414b3b1d67a84fd127664d99
|
data/README.md
CHANGED
@@ -1,6 +1,32 @@
|
|
1
1
|
# DelegateWhenNil
|
2
2
|
|
3
|
-
|
3
|
+
This gem provides a macro-method, #delegate_when_nil, which works kind of like #delegate, except it evaluates
|
4
|
+
the expression locally first, and delegates to the target only if the local result is nil.
|
5
|
+
|
6
|
+
|
7
|
+
class Parent
|
8
|
+
attr_accessor :name, :address
|
9
|
+
...
|
10
|
+
end
|
11
|
+
|
12
|
+
class Child
|
13
|
+
attr_accessor :name, :address
|
14
|
+
delegate_when_nil :name, :address, to: :parent, prefix: :get
|
15
|
+
|
16
|
+
# equivalent to
|
17
|
+
# def get_name
|
18
|
+
# self.name || (parent && parent.get_name) # #get_name on Parent might delegate further...
|
19
|
+
# end
|
20
|
+
|
21
|
+
# use #stop option to avoid the prefix on the parent attribute (delegation "stops" at parent)
|
22
|
+
|
23
|
+
class Child
|
24
|
+
delegate_when_nil :name, :address, to: :parent, prefix: :get, stop: true
|
25
|
+
|
26
|
+
# equivalent to
|
27
|
+
# def get_name
|
28
|
+
# self.name || (parent && parent.name) # #name directly on parent instead of #get_name
|
29
|
+
# end
|
4
30
|
|
5
31
|
## Installation
|
6
32
|
|
@@ -18,35 +44,21 @@ Or install it yourself as:
|
|
18
44
|
|
19
45
|
## Usage
|
20
46
|
|
21
|
-
|
22
|
-
|
23
|
-
require 'delegate_when_nil'
|
24
|
-
|
25
|
-
Mix in the DelegateWhenNil module
|
26
|
-
|
27
|
-
class Widget
|
28
|
-
extend DelegateWhenNil
|
29
|
-
...
|
30
|
-
|
31
|
-
To use with ActiveRecord, put this in an initializer instead
|
32
|
-
|
33
|
-
ActiveRecord::Base.send :extend, DelegateNil
|
34
|
-
|
35
|
-
Then #delegate_when_nil is available as a class method on your model,
|
47
|
+
DelegateWhenNil installs itself in Module so is available everywhere in your code.
|
36
48
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
49
|
+
class Widget < PopularFramework::Base
|
50
|
+
attr_accessor :parent
|
51
|
+
attr_accessor :description, :colour, :height
|
52
|
+
delegate_when_nil :description, :colour, :height, to: :parent, prefix: :get
|
53
|
+
...
|
42
54
|
|
43
55
|
In this example, if the #description, #colour, or #height properties are accessed and are nil, DelegateWhenNil will ask the #parent property instead.
|
44
56
|
|
45
|
-
|
46
|
-
|
57
|
+
p = Parent.new :description => "Woggle"
|
58
|
+
w = Widget.new :parent => p, :colour => :blue
|
47
59
|
|
48
|
-
|
49
|
-
|
60
|
+
w.get_description #=> "Woggle"
|
61
|
+
w.get_colour #=> :blue
|
50
62
|
|
51
63
|
## Contributing
|
52
64
|
|
data/delegate_when_nil.gemspec
CHANGED
@@ -15,8 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.summary = %q{Like #delegate, but assumes the target method already exists, and delegates only when the local method returns nil}
|
16
16
|
gem.homepage = "https://github.com/conanite/delegate_when_nil"
|
17
17
|
|
18
|
-
gem.add_development_dependency 'rspec'
|
19
|
-
gem.add_development_dependency 'rspec_numbering_formatter'
|
18
|
+
gem.add_development_dependency 'rspec'
|
20
19
|
|
21
20
|
gem.files = `git ls-files`.split($/)
|
22
21
|
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
data/lib/delegate_when_nil.rb
CHANGED
@@ -1,28 +1,41 @@
|
|
1
1
|
require "delegate_when_nil/version"
|
2
2
|
|
3
3
|
module DelegateWhenNil
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
# Child defines accessor :name
|
5
|
+
# Parent defines accessor :name
|
6
|
+
#
|
7
|
+
# class Child
|
8
|
+
# delegate_when_nil :name, :address, to: :parent, prefix: :get
|
9
|
+
#
|
10
|
+
# # equivalent to
|
11
|
+
# def get_name
|
12
|
+
# self.name || (parent && parent.get_name)
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# use #stop option to avoid prefix on parent (delegation "stops" at parent)
|
16
|
+
#
|
17
|
+
# class Child
|
18
|
+
# delegate_when_nil :name, :address, to: :parent, prefix: :get, stop: true
|
19
|
+
#
|
20
|
+
# # equivalent to
|
21
|
+
# def get_name
|
22
|
+
# self.name || (parent && parent.name) # #name directly on parent instead of #get_name
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
def delegate_when_nil *names
|
26
|
+
opts = names.pop
|
27
|
+
raise "please provide a hash with keys :to and :prefix as last argument" unless opts.is_a?(Hash) && opts.key?(:to) && opts.key?(:prefix)
|
7
28
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
result = #{old_name}(*args) # result = delegate_when_nil_description(*args)
|
12
|
-
if result == nil # if result == nil
|
13
|
-
delegate = #{target} # delegate = parent
|
14
|
-
result = delegate.#{name}(*args) if delegate # result = delegate.description(*args) if delegate
|
15
|
-
end # end
|
16
|
-
result # result
|
17
|
-
end # end
|
18
|
-
DELEGATION
|
19
|
-
end
|
29
|
+
fallback = opts[:to]
|
30
|
+
prefix = opts[:prefix]
|
31
|
+
stop = opts[:stop]
|
20
32
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
33
|
+
raise "prefix required to avoid infinite recursion in #attr_fallback #{names.inspect}" unless prefix
|
34
|
+
|
35
|
+
names.each { |name|
|
36
|
+
myname = [prefix, name].compact.join('_')
|
37
|
+
fbname = stop ? name : myname
|
38
|
+
class_eval "def #{myname}(*args) ; self.#{name}(*args) || (#{fallback} && #{fallback}.#{fbname}(*args)) ; end"
|
39
|
+
}
|
27
40
|
end
|
28
41
|
end
|
@@ -3,53 +3,57 @@ require 'spec_helper'
|
|
3
3
|
describe DelegateWhenNil do
|
4
4
|
class Parent
|
5
5
|
attr_accessor :last_name
|
6
|
+
alias get_last_name last_name
|
6
7
|
end
|
7
8
|
|
8
9
|
class Child
|
9
10
|
extend DelegateWhenNil
|
10
11
|
attr_accessor :last_name, :parent, :size
|
11
|
-
delegate_when_nil :last_name, :
|
12
|
-
delegate_when_nil :size, :
|
12
|
+
delegate_when_nil :last_name, to: :parent, prefix: :get
|
13
|
+
delegate_when_nil :size, to: "parent.last_name", prefix: :measure, stop: true
|
13
14
|
end
|
14
15
|
|
15
|
-
it "
|
16
|
+
it "does not delegate when the local property is present" do
|
16
17
|
child = Child.new
|
17
18
|
child.last_name = "Wong"
|
18
19
|
expect(child.last_name).to eq "Wong"
|
19
20
|
end
|
20
21
|
|
21
|
-
it "
|
22
|
+
it "does not get upset when everything is nil" do
|
22
23
|
child = Child.new
|
23
24
|
expect(child.last_name).to eq nil
|
24
25
|
end
|
25
26
|
|
26
|
-
it "
|
27
|
+
it "does not delegate when the property is present and the delegate target is also present" do
|
27
28
|
child = Child.new
|
28
29
|
child.last_name = "Shaw"
|
29
30
|
child.parent = Parent.new
|
30
31
|
expect(child.last_name).to eq "Shaw"
|
31
32
|
end
|
32
33
|
|
33
|
-
it "
|
34
|
+
it "does not delegate when the property is present and the delegate target is also present" do
|
34
35
|
child = Child.new
|
35
36
|
child.parent = Parent.new
|
36
37
|
child.parent.last_name = "Wonka"
|
37
|
-
expect(child.last_name).to
|
38
|
+
expect(child.last_name).to be_nil
|
39
|
+
expect(child.get_last_name).to eq "Wonka"
|
38
40
|
end
|
39
41
|
|
40
|
-
it "
|
42
|
+
it "raises an error if a complex delegation target fails" do
|
41
43
|
child = Child.new
|
42
|
-
expect { child.
|
44
|
+
expect { child.measure_size }.to raise_error NoMethodError
|
43
45
|
end
|
44
46
|
|
45
|
-
it "
|
47
|
+
it "delegates to a complex delegation target as expected" do
|
46
48
|
child = Child.new
|
47
49
|
child.parent = Parent.new
|
48
50
|
child.parent.last_name = "1234567"
|
49
|
-
expect(child.size).to
|
51
|
+
expect(child.size).to be_nil
|
52
|
+
expect(child.parent.last_name.size).to eq 7
|
53
|
+
expect(child.measure_size).to eq 7
|
50
54
|
end
|
51
55
|
|
52
|
-
it "
|
56
|
+
it "ignores a complex delegation target as expected when the local property is not nil" do
|
53
57
|
child = Child.new
|
54
58
|
child.size = 21
|
55
59
|
child.parent = Parent.new
|
data/spec/spec_helper.rb
CHANGED
@@ -7,7 +7,7 @@ require 'delegate_when_nil'
|
|
7
7
|
#
|
8
8
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
9
9
|
RSpec.configure do |config|
|
10
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
10
|
+
# config.treat_symbols_as_metadata_keys_with_true_values = true
|
11
11
|
config.run_all_when_everything_filtered = true
|
12
12
|
config.filter_run :focus
|
13
13
|
|
metadata
CHANGED
@@ -1,58 +1,39 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: delegate_when_nil
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Conan Dalton
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2020-01-31 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rspec
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '2.9'
|
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: '2.9'
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: rspec_numbering_formatter
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
|
-
requirements:
|
35
|
-
- - ! '>='
|
17
|
+
- - ">="
|
36
18
|
- !ruby/object:Gem::Version
|
37
19
|
version: '0'
|
38
20
|
type: :development
|
39
21
|
prerelease: false
|
40
22
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
23
|
requirements:
|
43
|
-
- -
|
24
|
+
- - ">="
|
44
25
|
- !ruby/object:Gem::Version
|
45
26
|
version: '0'
|
46
|
-
description:
|
47
|
-
|
27
|
+
description: 'Like #delegate, but assumes the target method already exists, and delegates
|
28
|
+
only when the local method returns nil'
|
48
29
|
email:
|
49
30
|
- conan@conandalton.net
|
50
31
|
executables: []
|
51
32
|
extensions: []
|
52
33
|
extra_rdoc_files: []
|
53
34
|
files:
|
54
|
-
- .gitignore
|
55
|
-
- .rspec
|
35
|
+
- ".gitignore"
|
36
|
+
- ".rspec"
|
56
37
|
- Gemfile
|
57
38
|
- LICENSE.txt
|
58
39
|
- README.md
|
@@ -65,28 +46,27 @@ files:
|
|
65
46
|
homepage: https://github.com/conanite/delegate_when_nil
|
66
47
|
licenses:
|
67
48
|
- MIT
|
49
|
+
metadata: {}
|
68
50
|
post_install_message:
|
69
51
|
rdoc_options: []
|
70
52
|
require_paths:
|
71
53
|
- lib
|
72
54
|
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
55
|
requirements:
|
75
|
-
- -
|
56
|
+
- - ">="
|
76
57
|
- !ruby/object:Gem::Version
|
77
58
|
version: '0'
|
78
59
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
-
none: false
|
80
60
|
requirements:
|
81
|
-
- -
|
61
|
+
- - ">="
|
82
62
|
- !ruby/object:Gem::Version
|
83
63
|
version: '0'
|
84
64
|
requirements: []
|
85
65
|
rubyforge_project:
|
86
|
-
rubygems_version:
|
66
|
+
rubygems_version: 2.5.2.3
|
87
67
|
signing_key:
|
88
|
-
specification_version:
|
89
|
-
summary:
|
68
|
+
specification_version: 4
|
69
|
+
summary: 'Like #delegate, but assumes the target method already exists, and delegates
|
90
70
|
only when the local method returns nil'
|
91
71
|
test_files:
|
92
72
|
- spec/delegate_when_nil_spec.rb
|