delegate_when_nil 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- TODO: Write a gem description
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
- First of all require the gem
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
- class Widget < PopularFramework::Base
38
- attr_accessor :parent
39
- attr_accessor :description, :colour, :height
40
- delegate_when_nil :description, :colour, :height, to: :parent
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
- p = Parent.new :description => "Woggle"
46
- w = Widget.new :parent => p, :colour => :blue
57
+ p = Parent.new :description => "Woggle"
58
+ w = Widget.new :parent => p, :colour => :blue
47
59
 
48
- w.description #=> "Woggle"
49
- w.colour #=> :blue
60
+ w.get_description #=> "Woggle"
61
+ w.get_colour #=> :blue
50
62
 
51
63
  ## Contributing
52
64
 
@@ -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', '~> 2.9'
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) }
@@ -1,28 +1,41 @@
1
1
  require "delegate_when_nil/version"
2
2
 
3
3
  module DelegateWhenNil
4
- def define_conditional_delegation name, target
5
- old_name = "delegate_when_nil_#{name}".to_sym
6
- return if method_defined? old_name
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
- class_eval <<DELEGATION
9
- alias #{old_name} #{name} # alias delegate_when_nil_description description
10
- def #{name} *args # def description *args
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
- def delegate_when_nil *names
22
- target = names.pop[:to]
23
- raise "missing :to option to #delegate_when_nil for #{name}" if target.to_s == ""
24
- names.each do |name|
25
- define_conditional_delegation name, target
26
- end
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
@@ -1,3 +1,3 @@
1
1
  module DelegateWhenNil
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  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, :to => :parent
12
- delegate_when_nil :size, :to => :"parent.last_name"
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 "should not intervene when the property is present" do
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 "should not get upset when everything is nil" do
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 "should not intervene when the property is present and the delegate target is also present" do
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 "should not intervene when the property is present and the delegate target is also present" do
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 eq "Wonka"
38
+ expect(child.last_name).to be_nil
39
+ expect(child.get_last_name).to eq "Wonka"
38
40
  end
39
41
 
40
- it "should raise an error if a complex delegation target fails" do
42
+ it "raises an error if a complex delegation target fails" do
41
43
  child = Child.new
42
- expect { child.size }.to raise_error
44
+ expect { child.measure_size }.to raise_error NoMethodError
43
45
  end
44
46
 
45
- it "should execute a complex delegation target as expected" do
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 eq 7
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 "should ignore a complex delegation target as expected when the local property is not nil" do
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
@@ -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.1
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: 2013-12-13 00:00:00.000000000 Z
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: ! 'Like #delegate, but assumes the target method already exists, and
47
- delegates only when the local method returns nil'
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: 1.8.24
66
+ rubygems_version: 2.5.2.3
87
67
  signing_key:
88
- specification_version: 3
89
- summary: ! 'Like #delegate, but assumes the target method already exists, and delegates
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