diff options
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/CHANGELOG.md | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/hash/keys.rb | 14 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/integer/time.rb | 6 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/module/delegation.rb | 24 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/numeric/time.rb | 6 | ||||
-rw-r--r-- | activesupport/lib/active_support/inflector/methods.rb | 2 | ||||
-rw-r--r-- | activesupport/test/core_ext/module_test.rb | 19 | ||||
-rw-r--r-- | activesupport/test/inflector_test_cases.rb | 28 |
8 files changed, 69 insertions, 32 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 8165b89cde..b6c3e91db8 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,5 +1,7 @@ ## Rails 4.0.0 (unreleased) ## +* Make Module#delegate stop using `send` - can no longer delegate to private methods. *dasch* + * AS::Callbacks: deprecate `:rescuable` option. *Bogdan Gusiev* * Adds Integer#ordinal to get the ordinal suffix string of an integer. *Tim Gildea* diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb index d8748b1138..65c3736593 100644 --- a/activesupport/lib/active_support/core_ext/hash/keys.rb +++ b/activesupport/lib/active_support/core_ext/hash/keys.rb @@ -1,7 +1,11 @@ class Hash # Return a new hash with all keys converted to strings. def stringify_keys - dup.stringify_keys! + result = {} + keys.each do |key| + result[key.to_s] = self[key] + end + result end # Destructively convert all keys to strings. @@ -15,14 +19,18 @@ class Hash # Return a new hash with all keys converted to symbols, as long as # they respond to +to_sym+. def symbolize_keys - dup.symbolize_keys! + result = {} + keys.each do |key| + result[(key.to_sym rescue key)] = self[key] + end + result end # Destructively convert all keys to symbols, as long as they respond # to +to_sym+. def symbolize_keys! keys.each do |key| - self[(key.to_sym rescue key) || key] = delete(key) + self[(key.to_sym rescue key)] = delete(key) end self end diff --git a/activesupport/lib/active_support/core_ext/integer/time.rb b/activesupport/lib/active_support/core_ext/integer/time.rb index c677400396..894b5d0696 100644 --- a/activesupport/lib/active_support/core_ext/integer/time.rb +++ b/activesupport/lib/active_support/core_ext/integer/time.rb @@ -24,9 +24,9 @@ class Integer # 1.year.to_f.from_now # # In such cases, Ruby's core - # Date[http://stdlib.rubyonrails.org/libdoc/date/rdoc/index.html] and - # Time[http://stdlib.rubyonrails.org/libdoc/time/rdoc/index.html] should be used for precision - # date and time arithmetic + # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and + # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision + # date and time arithmetic. def months ActiveSupport::Duration.new(self * 30.days, [[:months, self]]) end diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index af92b869fd..ee8adae1cb 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -1,5 +1,5 @@ class Module - # Provides a delegate class method to easily expose contained objects' methods + # Provides a delegate class method to easily expose contained objects' public methods # as your own. Pass one or more methods (specified as symbols or strings) # and the name of the target object via the <tt>:to</tt> option (also a symbol # or string). At least one method and the <tt>:to</tt> option are required. @@ -124,23 +124,27 @@ class Module file, line = caller.first.split(':', 2) line = line.to_i - if allow_nil - methods.each do |method| + methods.each do |method| + method = method.to_s + + # Attribute writer methods only accept one argument. Makes sure []= + # methods still accept two arguments. + definition = (method =~ /[^\]]=$/) ? "arg" : "*args, &block" + + if allow_nil module_eval(<<-EOS, file, line - 2) - def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block) + def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block) if #{to} || #{to}.respond_to?(:#{method}) # if client || client.respond_to?(:name) - #{to}.__send__(:#{method}, *args, &block) # client.__send__(:name, *args, &block) + #{to}.#{method}(#{definition}) # client.name(*args, &block) end # end end # end EOS - end - else - methods.each do |method| + else exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") module_eval(<<-EOS, file, line - 1) - def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block) - #{to}.__send__(:#{method}, *args, &block) # client.__send__(:name, *args, &block) + def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block) + #{to}.#{method}(#{definition}) # client.name(*args, &block) rescue NoMethodError # rescue NoMethodError if #{to}.nil? # if client.nil? #{exception} # # add helpful message to the exception diff --git a/activesupport/lib/active_support/core_ext/numeric/time.rb b/activesupport/lib/active_support/core_ext/numeric/time.rb index 58a03d508e..822f766af7 100644 --- a/activesupport/lib/active_support/core_ext/numeric/time.rb +++ b/activesupport/lib/active_support/core_ext/numeric/time.rb @@ -28,9 +28,9 @@ class Numeric # 1.year.to_f.from_now # # In such cases, Ruby's core - # Date[http://stdlib.rubyonrails.org/libdoc/date/rdoc/index.html] and - # Time[http://stdlib.rubyonrails.org/libdoc/time/rdoc/index.html] should be used for precision - # date and time arithmetic + # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and + # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision + # date and time arithmetic. def seconds ActiveSupport::Duration.new(self, [[:seconds, self]]) end diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index 54d3b4f5ca..61876d89a9 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -114,7 +114,7 @@ module ActiveSupport # "TheManWithoutAPast".titleize # => "The Man Without A Past" # "raiders_of_the_lost_ark".titleize # => "Raiders Of The Lost Ark" def titleize(word) - humanize(underscore(word)).gsub(/\b(['’`]?[a-z])/) { $1.capitalize } + humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { $&.capitalize } end # Create the name of a table like Rails does for models to table names. This method diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb index 09ca4e7296..6e1b3ca010 100644 --- a/activesupport/test/core_ext/module_test.rb +++ b/activesupport/test/core_ext/module_test.rb @@ -60,6 +60,14 @@ Tester = Struct.new(:client) do delegate :name, :to => :client, :prefix => false end +class ParameterSet + delegate :[], :[]=, :to => :@params + + def initialize + @params = {:foo => "bar"} + end +end + class Name delegate :upcase, :to => :@full_name @@ -83,6 +91,17 @@ class ModuleTest < ActiveSupport::TestCase assert_equal "Fred", @david.place.name end + def test_delegation_to_index_get_method + @params = ParameterSet.new + assert_equal "bar", @params[:foo] + end + + def test_delegation_to_index_set_method + @params = ParameterSet.new + @params[:foo] = "baz" + assert_equal "baz", @params[:foo] + end + def test_delegation_down_hierarchy assert_equal "CHICAGO", @david.upcase end diff --git a/activesupport/test/inflector_test_cases.rb b/activesupport/test/inflector_test_cases.rb index 879c3c1125..86c5e1f135 100644 --- a/activesupport/test/inflector_test_cases.rb +++ b/activesupport/test/inflector_test_cases.rb @@ -211,18 +211,22 @@ module InflectorTestCases } MixtureToTitleCase = { - 'active_record' => 'Active Record', - 'ActiveRecord' => 'Active Record', - 'action web service' => 'Action Web Service', - 'Action Web Service' => 'Action Web Service', - 'Action web service' => 'Action Web Service', - 'actionwebservice' => 'Actionwebservice', - 'Actionwebservice' => 'Actionwebservice', - "david's code" => "David's Code", - "David's code" => "David's Code", - "david's Code" => "David's Code", - "Fred’s" => "Fred’s", - "Fred`s" => "Fred`s" + 'active_record' => 'Active Record', + 'ActiveRecord' => 'Active Record', + 'action web service' => 'Action Web Service', + 'Action Web Service' => 'Action Web Service', + 'Action web service' => 'Action Web Service', + 'actionwebservice' => 'Actionwebservice', + 'Actionwebservice' => 'Actionwebservice', + "david's code" => "David's Code", + "David's code" => "David's Code", + "david's Code" => "David's Code", + "sgt. pepper's" => "Sgt. Pepper's", + "i've just seen a face" => "I've Just Seen A Face", + "maybe you'll be there" => "Maybe You'll Be There", + "¿por qué?" => '¿Por Qué?', + "Fred’s" => "Fred’s", + "Fred`s" => "Fred`s" } OrdinalNumbers = { |