File: active_support/core_ext/object/extending.rb

Overview
Module Structure
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: <Built-in Module>
  class: Object
module: InstanceExecMethods    #55

Code

   1  class Object
   2    def remove_subclasses_of(*superclasses) #:nodoc:
   3      Class.remove_class(*subclasses_of(*superclasses))
   4    end
   5 
   6    begin
   7      ObjectSpace.each_object(Class.new) {}
   8 
   9      # Exclude this class unless it's a subclass of our supers and is defined.
  10      # We check defined? in case we find a removed class that has yet to be
  11      # garbage collected. This also fails for anonymous classes -- please
  12      # submit a patch if you have a workaround.
  13      def subclasses_of(*superclasses) #:nodoc:
  14        subclasses = []
  15 
  16        superclasses.each do |sup|
  17          ObjectSpace.each_object(class << sup; self; end) do |k|
  18            if k != sup && (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
  19              subclasses << k
  20            end
  21          end
  22        end
  23 
  24        subclasses
  25      end
  26    rescue RuntimeError
  27      # JRuby and any implementations which cannot handle the objectspace traversal
  28      # above fall back to this implementation
  29      def subclasses_of(*superclasses) #:nodoc:
  30        subclasses = []
  31 
  32        superclasses.each do |sup|
  33          ObjectSpace.each_object(Class) do |k|
  34            if superclasses.any? { |superclass| k < superclass } &&
  35              (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
  36              subclasses << k
  37            end
  38          end
  39          subclasses.uniq!
  40        end
  41        subclasses
  42      end
  43    end
  44 
  45    def extended_by #:nodoc:
  46      ancestors = class << self; ancestors end
  47      ancestors.select { |mod| mod.class == Module } - [ Object, Kernel ]
  48    end
  49 
  50    def extend_with_included_modules_from(object) #:nodoc:
  51      object.extended_by.each { |mod| extend mod }
  52    end
  53 
  54    unless defined? instance_exec # 1.9
  55      module InstanceExecMethods #:nodoc:
  56      end
  57      include InstanceExecMethods
  58 
  59      # Evaluate the block with the given arguments within the context of
  60      # this object, so self is set to the method receiver.
  61      #
  62      # From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
  63      def instance_exec(*args, &block)
  64        begin
  65          old_critical, Thread.critical = Thread.critical, true
  66          n = 0
  67          n += 1 while respond_to?(method_name = "__instance_exec#{n}")
  68          InstanceExecMethods.module_eval { define_method(method_name, &block) }
  69        ensure
  70          Thread.critical = old_critical
  71        end
  72 
  73        begin
  74          send(method_name, *args)
  75        ensure
  76          InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
  77        end
  78      end
  79    end
  80  end