diff --git a/.gitignore b/.gitignore index 2dfdf96..79d884c 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ railties/test/initializer/root/log railties/doc railties/guides/output railties/tmp +.DS_Store +nbproject diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index 3a7652f..9ccb2b6 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -109,11 +109,12 @@ class Module raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)." end - if options[:prefix] == true && options[:to].to_s =~ /^[^a-z_]/ - raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method." + if (options[:prefix] == true || options[:writer]) && options[:to].to_s =~ /^[^a-z_]/ + raise ArgumentError, "Can only automatically set the delegation prefix or make a writer method when delegating to a method." end prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_" || '' + writer = !!options[:writer] file, line = caller.first.split(':', 2) line = line.to_i @@ -141,6 +142,24 @@ class Module end # end end # end EOS + + if writer + module_eval(<<-EOS, file, line - 5) + if instance_methods(false).map(&:to_s).include?("#{prefix}#{method}=") + remove_possible_method("#{prefix}#{method}=") + end + + def #{prefix}#{method}=(*args, &block) # def customer_name=(*args, &block) + #{to}.__send__(#{method.inspect}=, *args, &block) # client.__send__(:name=, *args, &block) + rescue NoMethodError # rescue NoMethodError + if #{to}.nil? # if client.nil? + #{on_nil} # return # depends on :allow_nil + else # else + raise # raise + end # end + end # end + EOS + end end end end diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb index 75404ec..0841711 100644 --- a/activesupport/test/core_ext/module_test.rb +++ b/activesupport/test/core_ext/module_test.rb @@ -42,6 +42,10 @@ Invoice = Struct.new(:client) do delegate :street, :city, :name, :to => :client, :prefix => :customer end +Bill = Struct.new(:client) do + delegate :name, :to => :client, :prefix => true, :writer => true +end + Project = Struct.new(:description, :person) do delegate :name, :to => :person, :allow_nil => true delegate :to_f, :to => :description, :allow_nil => true @@ -82,6 +86,12 @@ class ModuleTest < Test::Unit::TestCase assert_equal "DAVID HANSSON", david.upcase end + def test_delegation_to_methods_with_writer + bill = Bill.new(@david) + bill.client_name = "Nathan" + assert_equal "Nathan", bill.client_name + end + def test_missing_delegation_target assert_raise(ArgumentError) do Name.send :delegate, :nowhere