Add :allow_nil option to delegate [#1127 state:resolved]
Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
This commit is contained in:
parent
f7bd0beb67
commit
e8de7a67a5
@ -1,5 +1,7 @@
|
||||
*2.3.0 [Edge]*
|
||||
|
||||
* Add :allow_nil option to delegate. #1127 [Sergio Gil]
|
||||
|
||||
* Add Benchmark.ms convenience method to benchmark realtime in milliseconds. [Jeremy Kemper]
|
||||
|
||||
* Updated included memcache-client to the 1.5.0.5 version which includes fixes from fiveruns and 37signals to deal with failover and timeouts #1535 [Joshua Sierles]
|
||||
|
@ -72,6 +72,30 @@ class Module
|
||||
# invoice.customer_name # => "John Doe"
|
||||
# invoice.customer_address # => "Vimmersvej 13"
|
||||
#
|
||||
# If the object to which you delegate can be nil, you may want to use the
|
||||
# :allow_nil option. In that case, it returns nil instead of raising a
|
||||
# NoMethodError exception:
|
||||
#
|
||||
# class Foo
|
||||
# attr_accessor :bar
|
||||
# def initialize(bar = nil)
|
||||
# @bar = bar
|
||||
# end
|
||||
# delegate :zoo, :to => :bar
|
||||
# end
|
||||
#
|
||||
# Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
|
||||
#
|
||||
# class Foo
|
||||
# attr_accessor :bar
|
||||
# def initialize(bar = nil)
|
||||
# @bar = bar
|
||||
# end
|
||||
# delegate :zoo, :to => :bar, :allow_nil => true
|
||||
# end
|
||||
#
|
||||
# Foo.new.zoo # returns nil
|
||||
#
|
||||
def delegate(*methods)
|
||||
options = methods.pop
|
||||
unless options.is_a?(Hash) && to = options[:to]
|
||||
@ -84,10 +108,12 @@ def delegate(*methods)
|
||||
|
||||
prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_"
|
||||
|
||||
allow_nil = options[:allow_nil] && "#{to} && "
|
||||
|
||||
methods.each do |method|
|
||||
module_eval(<<-EOS, "(__DELEGATION__)", 1)
|
||||
def #{prefix}#{method}(*args, &block)
|
||||
#{to}.__send__(#{method.inspect}, *args, &block)
|
||||
#{allow_nil}#{to}.__send__(#{method.inspect}, *args, &block)
|
||||
end
|
||||
EOS
|
||||
end
|
||||
|
@ -41,6 +41,10 @@ class De
|
||||
delegate :street, :city, :name, :to => :client, :prefix => :customer
|
||||
end
|
||||
|
||||
Project = Struct.new(:description, :person) do
|
||||
delegate :name, :to => :person, :allow_nil => true
|
||||
end
|
||||
|
||||
class Name
|
||||
delegate :upcase, :to => :@full_name
|
||||
|
||||
@ -117,6 +121,29 @@ def initialize(client)
|
||||
end
|
||||
end
|
||||
|
||||
def test_delegation_with_allow_nil
|
||||
rails = Project.new("Rails", Someone.new("David"))
|
||||
assert_equal rails.name, "David"
|
||||
end
|
||||
|
||||
def test_delegation_with_allow_nil_and_nil_value
|
||||
rails = Project.new("Rails")
|
||||
assert_nil rails.name
|
||||
end
|
||||
|
||||
def test_delegation_with_allow_nil_and_nil_value_and_prefix
|
||||
Project.class_eval do
|
||||
delegate :name, :to => :person, :allow_nil => true, :prefix => true
|
||||
end
|
||||
rails = Project.new("Rails")
|
||||
assert_nil rails.person_name
|
||||
end
|
||||
|
||||
def test_delegation_without_allow_nil_and_nil_value
|
||||
david = Someone.new("David")
|
||||
assert_raises(NoMethodError) { david.street }
|
||||
end
|
||||
|
||||
def test_parent
|
||||
assert_equal Yz::Zy, Yz::Zy::Cd.parent
|
||||
assert_equal Yz, Yz::Zy.parent
|
||||
|
Loading…
Reference in New Issue
Block a user