diff options
author | Sergio Gil <sgilperez@gmail.com> | 2008-12-08 00:53:38 +0100 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2008-12-21 23:24:06 +0000 |
commit | e8de7a67a5ef063164da022845a7cae1753da80e (patch) | |
tree | 6b9f49120dd9f95b4b5800454520bf1cc4dcf793 /activesupport | |
parent | f7bd0beb67c5d9d50e37aa596605b91e61197fbe (diff) | |
download | rails-e8de7a67a5ef063164da022845a7cae1753da80e.tar.gz rails-e8de7a67a5ef063164da022845a7cae1753da80e.tar.bz2 rails-e8de7a67a5ef063164da022845a7cae1753da80e.zip |
Add :allow_nil option to delegate [#1127 state:resolved]
Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/CHANGELOG | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/module/delegation.rb | 28 | ||||
-rw-r--r-- | activesupport/test/core_ext/module_test.rb | 27 |
3 files changed, 56 insertions, 1 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index bc29c41d7c..cf41a20a5c 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -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] diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index 2905eebc85..5c75bd4938 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -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 @@ class Module 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 diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb index 886f692499..a5d98507ba 100644 --- a/activesupport/test/core_ext/module_test.rb +++ b/activesupport/test/core_ext/module_test.rb @@ -41,6 +41,10 @@ Invoice = Struct.new(:client) do 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 @@ class ModuleTest < Test::Unit::TestCase 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 |