diff options
Diffstat (limited to 'activesupport/lib/active_support/core_ext/module')
7 files changed, 37 insertions, 46 deletions
diff --git a/activesupport/lib/active_support/core_ext/module/aliasing.rb b/activesupport/lib/active_support/core_ext/module/aliasing.rb index 580cb80413..0a6fadf928 100644 --- a/activesupport/lib/active_support/core_ext/module/aliasing.rb +++ b/activesupport/lib/active_support/core_ext/module/aliasing.rb @@ -19,9 +19,9 @@ class Module # alias_method :foo_without_feature?, :foo? # alias_method :foo?, :foo_with_feature? # - # so you can safely chain foo, foo?, and foo! with the same feature. + # so you can safely chain foo, foo?, foo! and/or foo= with the same feature. def alias_method_chain(target, feature) - # Strip out punctuation on predicates or bang methods since + # Strip out punctuation on predicates, bang or writer methods since # e.g. target?_without_feature is not a valid method name. aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1 yield(aliased_target, punctuation) if block_given? diff --git a/activesupport/lib/active_support/core_ext/module/attr_internal.rb b/activesupport/lib/active_support/core_ext/module/attr_internal.rb index db07d549b0..93fb598650 100644 --- a/activesupport/lib/active_support/core_ext/module/attr_internal.rb +++ b/activesupport/lib/active_support/core_ext/module/attr_internal.rb @@ -27,10 +27,8 @@ class Module def attr_internal_define(attr_name, type) internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, '') - class_eval do # class_eval is necessary on 1.9 or else the methods a made private - # use native attr_* methods as they are faster on some Ruby implementations - send("attr_#{type}", internal_name) - end + # use native attr_* methods as they are faster on some Ruby implementations + send("attr_#{type}", internal_name) attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer alias_method attr_name, internal_name remove_method internal_name diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb index d317df5079..d4e6b5a1ac 100644 --- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb +++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb @@ -203,7 +203,7 @@ class Module # include HairColors # end # - # Person.class_variable_get("@@hair_colors") #=> [:brown, :black, :blonde, :red] + # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red] def mattr_accessor(*syms, &blk) mattr_reader(*syms, &blk) mattr_writer(*syms, &blk) diff --git a/activesupport/lib/active_support/core_ext/module/concerning.rb b/activesupport/lib/active_support/core_ext/module/concerning.rb index b22dc5ff1e..07a392404e 100644 --- a/activesupport/lib/active_support/core_ext/module/concerning.rb +++ b/activesupport/lib/active_support/core_ext/module/concerning.rb @@ -63,7 +63,7 @@ class Module # # == Mix-in noise exiled to its own file: # - # Once our chunk of behavior starts pushing the scroll-to-understand it + # Once our chunk of behavior starts pushing the scroll-to-understand it's # boundary, we give in and move it to a separate file. At this size, the # overhead feels in good proportion to the size of our extraction, despite # diluting our at-a-glance sense of how things really work. diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index 58146cdf7a..24df83800b 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -1,15 +1,23 @@ +require 'set' + class Module # Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+ # option is not used. class DelegationError < NoMethodError; end + RUBY_RESERVED_WORDS = Set.new( + %w(alias and BEGIN begin break case class def defined? do else elsif END + end ensure false for if in module next nil not or redo rescue retry + return self super then true undef unless until when while yield) + ).freeze + # Provides a +delegate+ class method to easily expose contained objects' # public methods as your own. # # ==== Options # * <tt>:to</tt> - Specifies the target object # * <tt>:prefix</tt> - Prefixes the new method with the target name or a custom prefix - # * <tt>:allow_nil</tt> - if set to true, prevents a +NoMethodError+ to be raised + # * <tt>:allow_nil</tt> - if set to true, prevents a +NoMethodError+ from being raised # # The macro receives one or more method names (specified as symbols or # strings) and the name of the target object via the <tt>:to</tt> option @@ -163,45 +171,35 @@ class Module line = line.to_i to = to.to_s - to = 'self.class' if to == 'class' + to = "self.#{to}" if RUBY_RESERVED_WORDS.include?(to) methods.each do |method| # Attribute writer methods only accept one argument. Makes sure []= # methods still accept two arguments. definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block' - # The following generated methods call the target exactly once, storing + # The following generated method calls the target exactly once, storing # the returned value in a dummy variable. # # Reason is twofold: On one hand doing less calls is in general better. # On the other hand it could be that the target has side-effects, # whereas conceptually, from the user point of view, the delegator should # be doing one call. - if allow_nil - module_eval(<<-EOS, file, line - 3) - def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block) - _ = #{to} # _ = client - if !_.nil? || nil.respond_to?(:#{method}) # if !_.nil? || nil.respond_to?(:name) - _.#{method}(#{definition}) # _.name(*args, &block) - end # end - end # end - EOS - else - exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") - module_eval(<<-EOS, file, line - 2) - def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block) - _ = #{to} # _ = client - _.#{method}(#{definition}) # _.name(*args, &block) - rescue NoMethodError => e # rescue NoMethodError => e - if _.nil? && e.name == :#{method} # if _.nil? && e.name == :name - #{exception} # # add helpful message to the exception - else # else - raise # raise - end # end - end # end - EOS - end + exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") + + method_def = [ + "def #{method_prefix}#{method}(#{definition})", + " _ = #{to}", + " if !_.nil? || nil.respond_to?(:#{method})", + " _.#{method}(#{definition})", + " else", + " #{exception unless allow_nil}", + " end", + "end" + ].join ';' + + module_eval(method_def, file, line) end end end diff --git a/activesupport/lib/active_support/core_ext/module/method_transplanting.rb b/activesupport/lib/active_support/core_ext/module/method_transplanting.rb index b1097cc83b..1fde3db070 100644 --- a/activesupport/lib/active_support/core_ext/module/method_transplanting.rb +++ b/activesupport/lib/active_support/core_ext/module/method_transplanting.rb @@ -1,11 +1,3 @@ -class Module - ### - # TODO: remove this after 1.9 support is dropped - def methods_transplantable? # :nodoc: - x = Module.new { def foo; end } - Module.new { define_method :bar, x.instance_method(:foo) } - true - rescue TypeError - false - end -end +require 'active_support/deprecation' + +ActiveSupport::Deprecation.warn("This file is deprecated and will be removed in Rails 5.1 with no replacement.") diff --git a/activesupport/lib/active_support/core_ext/module/remove_method.rb b/activesupport/lib/active_support/core_ext/module/remove_method.rb index 719071d1c2..8a2569a7d0 100644 --- a/activesupport/lib/active_support/core_ext/module/remove_method.rb +++ b/activesupport/lib/active_support/core_ext/module/remove_method.rb @@ -1,10 +1,13 @@ class Module + # Remove the named method, if it exists. def remove_possible_method(method) if method_defined?(method) || private_method_defined?(method) undef_method(method) end end + # Replace the existing method definition, if there is one, with the contents + # of the block. def redefine_method(method, &block) remove_possible_method(method) define_method(method, &block) |