Class Module
In: lib/facets/core-uncommon/facets/module/class_inheritor.rb
lib/facets/core-uncommon/facets/module/method_clash.rb
lib/facets/core-uncommon/facets/module/class_accessor.rb
lib/facets/core-uncommon/facets/module/attr_tester.rb
lib/facets/core-uncommon/facets/module/memoize.rb
lib/facets/core-uncommon/facets/module/let.rb
lib/facets/core-uncommon/facets/module/enclosure.rb
lib/facets/core-uncommon/facets/module/preextend.rb
lib/facets/core-uncommon/facets/module/prepend.rb
lib/facets/core-uncommon/facets/module/method_space.rb
lib/facets/core-uncommon/facets/module/instance_function.rb
lib/facets/core-uncommon/facets/module/module_load.rb
lib/facets/core-uncommon/facets/module/copy_inheritor.rb
lib/facets/core-uncommon/facets/module/class_extend.rb
lib/facets/core-uncommon/facets/module/attr_class_accessor.rb
lib/facets/core-uncommon/facets/module/cattr.rb
lib/facets/core-uncommon/facets/module/attr_validator.rb
lib/facets/core-uncommon/facets/module/attr_inheritor.rb
Parent: Object

Methods

Included Modules

Memoizable Prependable

Classes and Modules

Module Module::InstanceFunction

Public Instance methods

Create aliases for flag reader.

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: Trans

[Source]

# File lib/facets/core-uncommon/facets/module/attr_tester.rb, line 40
  def alias_tester(*args)
    orig = args.last
    args = args - [orig]
    args.each do |name|
      alias_method("#{name}?", "#{orig}?")
    end
  end

Create aliases for validators.

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/attr_validator.rb, line 30
  def alias_validator(*args)
    orig = args.last
    args = args - [orig]
    args.each do |name|
      #alias_method(name, orig)
      alias_method("#{name}=", "#{orig}=")
    end
  end

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/attr_class_accessor.rb, line 6
  def attr_class_accessor(name)
    attr_class_reader(name)
    attr_class_writer(name)
  end

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/attr_class_accessor.rb, line 14
  def attr_class_reader(name)
    module_eval("def self.\#{name}\n@\#{name}\nend\ndef \#{name}\nself.class.\#{name}\nend\n", __FILE__, __LINE__)
  end

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/attr_class_accessor.rb, line 29
  def attr_class_writer(name)
    module_eval("def self.\#{name}=(x)\n@\#{name} = x\nend\ndef \#{name}=(x)\nself.class.\#{name} = x\nend\n", __FILE__, __LINE__)
  end

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/attr_inheritor.rb, line 6
  def attr_inheritable_reader(name, default)
    copy_inheritor(name, default)
    module_eval("def \#{name}\nself.class.\#{name}\nend\n", __FILE__, __LINE__)
  end

Create an tester attribute. This creates a single method used to test the attribute for truth.

  attr_tester :a

is equivalent to

  def a?
    @a ? true : @a
  end

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: Trans

[Source]

# File lib/facets/core-uncommon/facets/module/attr_tester.rb, line 19
  def attr_tester(*args)
    code, made = '', []
    args.each do |a|
      code << %{
        def #{a}?(truth=nil)
          @#{a} ? truth || @#{a} : @#{a}
        end
      }
      made << "#{a}?".to_sym
    end
    module_eval code
    made
  end

Like attr_writer, but the writer method validates the setting against the given block.

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: ?

[Source]

# File lib/facets/core-uncommon/facets/module/attr_validator.rb, line 11
  def attr_validator(*symbols, &validator)
    made = []
    symbols.each do |symbol|
      define_method "#{symbol}=" do |val|
        unless validator.call(val)
          raise ArgumentError, "Invalid value provided for #{symbol}"
        end
        instance_variable_set("@#{symbol}", val)
      end
      made << "#{symbol}=".to_sym
    end
    made
  end

Creates a class-variable attribute that can be accessed both on an instance and class level.

  class CARExample
    @@a = 10
    cattr :a
  end

  CARExample.a           #=> 10
  CARExample.new.a       #=> 10

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: David Heinemeier Hansson

[Source]

# File lib/facets/core-uncommon/facets/module/cattr.rb, line 18
  def cattr(*syms)
    writers, readers = syms.flatten.partition{ |a| a.to_s =~ /=$/ }
    writers = writers.map{ |e| e.to_s.chomp('=').to_sym }
    ##readers.concat( writers ) # writers also get readers

    cattr_reader(*readers)
    cattr_writer(*writers)

    return readers + writers
  end

Creates a class-variable attr_accessor that can be accessed both on an instance and class level.

  class CAAExample
    cattr_accessor :a
  end

  CAAExample.a = 10
  CAAExample.a           #=> 10
  mc = CAAExample.new
  mc.a                   #=> 10

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: David Heinemeier Hansson

[Source]

# File lib/facets/core-uncommon/facets/module/cattr.rb, line 119
  def cattr_accessor(*syms)
    cattr_reader(*syms) + cattr_writer(*syms)
  end

Creates a class-variable attr_reader that can be accessed both on an instance and class level.

  class CARExample
    @@a = 10
    cattr_reader :a
  end

  CARExample.a           #=> 10
  CARExample.new.a       #=> 10

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: David Heinemeier Hansson

[Source]

# File lib/facets/core-uncommon/facets/module/cattr.rb, line 44
  def cattr_reader(*syms)
    syms.flatten.each do |sym|
      module_eval("unless defined? @@\#{sym}\n@@\#{sym} = nil\nend\n\ndef self.\#{sym}\n@@\#{sym}\nend\n\ndef \#{sym}\n@@\#{sym}\nend\n", __FILE__, __LINE__)
    end
    return syms
  end

Creates a class-variable attr_writer that can be accessed both on an instance and class level.

  class CAWExample
    cattr_writer :a
    def self.a
      @@a
    end
  end

  CAWExample.a = 10
  CAWExample.a            #=> 10
  CAWExample.new.a = 29
  CAWExample.a            #=> 29

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: David Heinemeier Hansson

[Source]

# File lib/facets/core-uncommon/facets/module/cattr.rb, line 83
  def cattr_writer(*syms)
    syms.flatten.each do |sym|
      module_eval("unless defined? @@\#{sym}\n@@\#{sym} = nil\nend\n\ndef self.\#{sym}=(obj)\n@@\#{sym} = obj\nend\n\ndef \#{sym}=(obj)\n@@\#{sym}=(obj)\nend\n", __FILE__, __LINE__)
    end
    return syms
  end

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/class_accessor.rb, line 6
  def class_accessor(name)
    class_reader(name)
    class_writer(name)
  end

Normally when including modules, class/module methods are not extended. To achieve this behavior requires some clever Ruby Karate. Instead class_extend provides an easy to use and clean solution. Simply place the extending class methods in a block of the special module method class_extend.

  module Mix
    def inst_meth
      puts 'inst_meth'
    end

    class_extend do
      def class_meth
        "Class Method!"
      end
    end
  end

  class X
    include Mix
  end

  X.class_meth  #=> "Class Method!"

NOTE: This old class_extension version of this method did not extend the containing class automatically —it had to be done by hand. With class_extend, that is no longer the case.

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: Daniel Schierbeck, Thomas Sawyer

THANKS: Nobu Nakada, Ulysses

[Source]

# File lib/facets/core-uncommon/facets/module/class_extend.rb, line 39
  def class_extend(*mods, &block)
    class_extension = Module.new

    class_extension.__send__(:include, *mods)
    class_extension.module_eval(&block) if block_given?

    extend(class_extension)  # extend this module too

    append_method = method(:append_features)

    (class << self; self; end).class_eval do
      define_method(:append_features) do |mod|
        append_method.call(mod)
        mod.extend(class_extension)
        if mod.instance_of?(Module)
          mod.__send__(:class_extend, class_extension)
        end
      end
    end

    class_extensions << class_extension
  end

[Source]

# File lib/facets/core-uncommon/facets/module/class_extend.rb, line 65
  def class_extensions
    @class_extensions ||= []
  end

Class Inheritor

Create an dynamic class inheritable attribute.

Inheritor providse a means to store and inherit data via the class heirarchy. An inheritor creates two methods one named after the key that provides a reader. And one named after key! which provides the writer. (Because of the unique nature of inheritor the reader and writer can‘t be the same method.)

The first argument is the inheritor‘s name. The second argument is the archtype object. This object must be duplicable (via dup). The last argument is either the symbolic operator/method or a block that specifies how one hierarchical level "integrates" with the next.

  class X
    class_inheritor :x, [], :+
  end

  class Y < X
  end

  X.x! << :a
  X.x  #=> [:a]
  Y.x  #=> [:a]

  Y.x! << :b
  X.x  #=> [:a]
  Y.x  #=> [:a, :b]

NOTE: Adding an inheritor directly to Module or Class will probably not do what is expected. Thankfully that usecase is likely a YAGNI, but in anycase it is even more likely that it is not possible with this code.

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: Thomas Sawyer

[Source]

# File lib/facets/core-uncommon/facets/module/class_inheritor.rb, line 45
  def class_inheritor(key, obj, op=nil, &fop)
    raise ArgumentError if op && fop

    if !fop
      op  = op ? op.to_sym : :+
      fop = lambda{ |o, x| o.__send__(op, x) }
    end

    #(class << self; self; end).module_eval do
    class_extend do

      define_method(key) do
        ancestors.reverse.inject(obj.dup) do |o, a|
          if a.respond_to?("#{key}!")
            fop.call(o, a.__send__("#{key}!"))
          else
            o
          end
        end
      end

      define_method("#{key}!") do
        if instance_variable_defined?("@#{key}")
          instance_variable_get("@#{key}")
        else
          instance_variable_set("@#{key}", obj.dup)
        end
      end

    end
  end
class_load( path )

Alias for module_load

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/class_accessor.rb, line 14
  def class_reader(name)
    module_eval("def self.\#{name}\n@\#{name}\nend\n", __FILE__, __LINE__)
  end
class_require( path )

Alias for module_require

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/class_accessor.rb, line 26
  def class_writer(name)
    module_eval("def self.\#{name}=(x)\n@\#{name} = x\nend\n", __FILE__, __LINE__)
  end

Like class_inheritor but non-dynamic. The value of the inheritor is copied from the ancestor on first read.

  c = Class.new do
    def self.x; ['x']; end
  end

  d = Class.new(c) do
    copy_inheritor :x
  end

  d.x  #=> ['x']

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: Thomas Sawyer

[Source]

# File lib/facets/core-uncommon/facets/module/copy_inheritor.rb, line 23
  def copy_inheritor(name, default={})
    class_extend do
      define_method(name) do
        if instance_variable_defined?("@#{name}")
          instance_variable_get("@#{name}")
        else
          if anc = ancestors[1..-1].find{ |a| a.respond_to?(name) }
            value = anc.__send__(name)
            value = value.dup rescue value
            instance_variable_set("@#{name}", value)
          else
            instance_variable_set("@#{name}", default)
          end
        end
      end
    end
  end

Returns the module which contains this one according to its name.

  module ::EncExample
    module M
      module N
      end
    end
  end

  EncExample::M::N.enclosure  #=> EncExample::M

The enclosure of top-level and anonymous modules is Object.

  EncExample.enclosure   #=> Object
  Module.new.enclosure   #=> Object

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/enclosure.rb, line 21
  def enclosure
    name = /::[^:]+\Z/ =~ self.name ? $` : nil
    if name
      #base = name.sub!(/^::/, '') ? Object : self
      name.split(/::/).inject(self) do |mod, cref|
        if /\:(0x.*?)\>$/ =~ cref   # TODO: does this ever happen?
          #p $1.to_i(16)
          ObjectSpace._idref($1.to_i(16))
        else
          mod.const_get(cref)
        end
      end
    else
      Object
    end
  end

Returns all the namespaces of this module according ordered from nearest and moving outwards. The receiver is not contained within the result.

  module ::EncExample
    module M
      module N
      end
    end
  end

  EncExample.enclosures        #=> [Object]
  EncExample::M.enclosures     #=> [EncExample, Object]
  EncExample::M::N.enclosures  #=> [EncExample::M, EncExample, Object]

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/enclosure.rb, line 55
  def enclosures
    n = []
    name.split(/::/).inject(self) do |mod, cref|
      c = mod.const_get(cref) ; n.unshift(c) ; c
    end
    n << Object # ?
    n.shift # we really don't need +self+ too.
    n
  end

Eclosure name.

  module ::EncExample
    module M
      module N
      end
    end
  end

  EncExample::M::N.encname  #=> "EncExample::M"

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/enclosure.rb, line 78
  def encname
    /::[^:]+\Z/ =~ self.name ? $` : nil
  end

Include a module via a specified space.

  module T
    def t ; "HERE" ; end
  end

  class X
    include_as :test => T
    def t ; test.t ; end
  end

  X.new.t  #=> "HERE"

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/method_space.rb, line 95
  def include_as(h)
    h.each{ |name, mod| method_space(name, mod) }
  end

Converts module methods into instance methods such that the first parameter is passed self. This promotes DRY programming when wishing to offer both inheritable and module callable procedures.

This method is modeled after module_function which essentially has the the opposite effect. Due to implementation limitations, this must use the callback singleton_method_added to emulate module_function when no method names are given.

  module MyModule
    instance_function

    def self.jumble(obj, arg)
      obj + arg
    end
  end

  MyModule.jumble("Try", "Me")  #=> "TryMe"

  s = "Try"
  s.extend MyModule
  s.jumble("Me")                #=> "TryMe"

Note: This used to be a module called PromoteSelf and later Instantize, before becoming a method.

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/instance_function.rb, line 30
  def instance_function(*meths)
    this = self
    if meths.empty?
      extend InstanceFunction
    else
      meths.each do |meth|
        module_eval do
          define_method(meth) do |*args|
            this.__send__(meth, self, *args)
          end
        end
        ##class_eval %{
        ##  def #{meth}(*args)
        ##    #{self.name}.#{meth}(self,*args)
        ##  end
        ##}
      end
    end
  end

Create a memoized method. This method has been popularized by RSpec.

  class LetExample
    let(:seed) { rand }
  end

  eg = LetExample.new
  eg.seed == eg.seed

CREDIT: Howard Yeh

[Source]

# File lib/facets/core-uncommon/facets/module/let.rb, line 13
  def let(var,&block)
    name = "@#{var}"
    self.class_eval do
      define_method(var) do
        if instance_variable_defined?(name)
          instance_variable_get(name)
        else
          val = self.instance_eval(&block)
          instance_variable_set(name,val)
        end
      end
    end
  end

Creates a class-variable attribute that can be accessed both on an instance and class level.

  c = Class.new do
    mattr :a
    def initialize
      @@a = 10
    end
  end

  c.new.a       #=> 10
  c.a           #=> 10

NOTE: The mattr methods may not be as useful for modules as the cattr methods are for classes, becuase class-level methods are not "inherited" across the metaclass for included modules.

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: David Heinemeier Hansson

[Source]

# File lib/facets/core-uncommon/facets/module/cattr.rb, line 144
  def mattr(*syms)
    writers, readers = syms.flatten.partition{ |a| a.to_s =~ /=$/ }
    writers = writers.collect{ |e| e.to_s.chomp('=').to_sym }
    ##readers.concat( writers ) # writers also get readers

    mattr_writer( *writers )
    mattr_reader( *readers )

    return readers + writers
  end

Creates a class-variable attr_accessor that can be accessed both on an instance and class level.

  c = Class.new do
    mattr_accessor :a
  end

  c.a = 10
  c.a           #=> 10

  x = c.new
  x.a           #=> 10

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: David Heinemeier Hansson

[Source]

# File lib/facets/core-uncommon/facets/module/cattr.rb, line 247
  def mattr_accessor(*syms)
    mattr_reader(*syms) + mattr_writer(*syms)
  end

Creates a class-variable attr_reader that can be accessed both on an instance and class level.

  c = Class.new do
    @@a = 10
    mattr_reader :a
  end

  c.a           #=> 10
  c.new.a       #=> 10

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: David Heinemeier Hansson

[Source]

# File lib/facets/core-uncommon/facets/module/cattr.rb, line 170
  def mattr_reader( *syms )
    syms.flatten.each do |sym|
      module_eval("unless defined? @@\#{sym}\n@@\#{sym} = nil\nend\n\ndef self.\#{sym}\n@@\#{sym}\nend\n\ndef \#{sym}\n@@\#{sym}\nend\n", __FILE__, __LINE__)
    end
    return syms
  end

Creates a class-variable attr_writer that can be accessed both on an instance and class level.

  c = Class.new do
    mattr_writer :a
    def self.a
      @@a
    end
  end

  c.a = 10
  c.a            #=> 10

  c.new.a = 29
  c.a            #=> 29

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: David Heinemeier Hansson

[Source]

# File lib/facets/core-uncommon/facets/module/cattr.rb, line 210
  def mattr_writer(*syms)
    syms.flatten.each do |sym|
      module_eval("unless defined? @@\#{sym}\n@@\#{sym} = nil\nend\n\ndef self.\#{sym}=(obj)\n@@\#{sym} = obj\nend\n\ndef \#{sym}=(obj)\n@@\#{sym}=(obj)\nend\n", __FILE__, __LINE__)
    end
    return syms
  end

This is here for backward compatibility.

[Source]

# File lib/facets/core-uncommon/facets/module/memoize.rb, line 6
  def memoize(*args)
    include Memoizable
    Memoizable.instance_method(:memoize).bind(self).call(*args)
    #super(*args)  # TODO: why is super not working here?
  end

Detect method name clash between modules and/or classes, regardless of method visibility:

  module MethodClashExample

    module A
      def c; end
    end

    module B
      private
      def c; end
    end

    A.method_clash(B)  #=> [:c]

  end

CREDIT: Thomas Sawyer, Robert Dober

[Source]

# File lib/facets/core-uncommon/facets/module/method_clash.rb, line 27
  def method_clash(other)
    common_ancestor = (ancestors & other.ancestors).first

    s = []
    s += public_instance_methods(true)
    s += private_instance_methods(true)
    s += protected_instance_methods(true)

    o = []
    o += other.public_instance_methods(true)
    o += other.private_instance_methods(true)
    o += other.protected_instance_methods(true)

    c = s & o

    if common_ancestor
      c -= common_ancestor.public_instance_methods(true)
      c -= common_ancestor.private_instance_methods(true)
      c -= common_ancestor.protected_instance_methods(true)
    end

    return c
  end

Uses method_clash to return true or false if there are method name clashes.

[Source]

# File lib/facets/core-uncommon/facets/module/method_clash.rb, line 53
  def method_clash?(other) 
    c = method_clash(other) 
    !c.empty?
  end

Create method namespaces, allowing for method chains but still accessing the object‘s instance.

  class A
    attr_writer :x
    method_space :inside do
      def x; @x; end
    end
  end

  a = A.new
  a.x = 10
  a.inside.x  #=> 10

  expect NoMethodError do
    a.x
  end

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: Pit Captain

[Source]

# File lib/facets/core-uncommon/facets/module/method_space.rb, line 28
  def method_space(name, mod=nil, &blk)

    ## If block is given then create a module, otherwise
    ## get the name of the module.
    if block_given?
      name = name.to_s
      raise ArgumentError if mod
      mod  = Module.new(&blk)
    else
      if Module === name
        mod = name
        name = mod.basename.downcase
      end
      mod  = mod.dup
    end

    ## Include the module. This is neccessary, otherwise
    ## Ruby won't let us bind the instance methods.
    include mod

    ## Save the instance methods of the module and
    ## replace them with a "transparent" version.
    methods = {}
    mod.instance_methods(false).each do |m|
      methods[m.to_sym] = mod.instance_method(m)
      mod.module_eval %{
        def #{m}(*a,&b)
          super(*a,&b)
        end
      }
      ##mod.instance_eval do
      ##  define_method(m)
      ##    super
      ##  end
      ##end
    end

    ## Add a method for the namespace that delegates
    ## via the Functor to the saved instance methods.
    define_method(name) do
      mtab = methods
      Functor.new do |op, *args|
        if meth = mtab[op.to_sym]
          meth.bind(self).call(*args)
        else
          #self.__send__(op, *args)
          raise NoMethodError, "undefined method `#{m}'"
        end
      end
    end
  end

Load file directly into module/class namespace.

Please use this with careful consideration. It is best suited to loading plugin-type scripts, and should generally not be used as a substitue for Ruby‘s standard load system.

NOTE: This is not (presently) a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: Trans

[Source]

# File lib/facets/core-uncommon/facets/module/module_load.rb, line 15
  def module_load( path )
    if path =~ /^[\/~.]/
      file = File.expand_path(path)
    else
      $LOAD_PATH.each do |lp|
        file = File.join(lp,path)
        break if File.exist?(file)
        file = nil
      end
    end
    raise LoadError, "no such file to load -- #{path}" unless file
    module_eval(File.read(file))
  end

Require file into module/class namespace.

Unlike load this keeps a per-module cache and will not load the same file into the same module more than once despite repeated attempts.

The cache is kept in a global var called +$module_require+.

Please use this with careful consideration. It is best suited to loading plugin-type scripts, and should generally not be used as a substitue for Ruby‘s standard load system.

NOTE: This is not a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT: Trans

[Source]

# File lib/facets/core-uncommon/facets/module/module_load.rb, line 47
  def module_require( path )
    if path =~ /^[\/~.]/
      file = File.expand_path(path)
    else
      $LOAD_PATH.each do |lp|
        file = File.join(lp,path)
        break if File.exist?(file)
        file += '.rb'
        break if File.exist?(file)
        file = nil
      end
    end
    raise LoadError, "no such file to load -- #{path}" unless file
    # per-module load cache
    $module_require ||= {}
    $module_require[self] ||= {}
    loaded = $module_require[self]
    if loaded.key?(file)
      false
    else
      loaded[file] = true
      script = File.read(file)
      module_eval(script)
      true
    end
  end

Prepend an aspect module to a module. This only works at the module level.

  module ::PreX
    def x; "x"; end
  end

  module ::PreU
    def x; '{' + super + '}'; end
  end

  PreX.preextend(PreU)

  PreX.x  # => "{x}"

NOTE: This is not a common core extension and is not loaded automatically when using require ‘facets‘.

CREDIT Trans

[Source]

# File lib/facets/core-uncommon/facets/module/preextend.rb, line 23
  def preextend(aspect)
    aspect.__send__(:include, self)
    extend aspect
  end

Prepend module.

  class X
    def a; "Xa"; end
  end

  module M
    def a; "M" + super ; end
  end

  class X
    prepend M
  end

  X.new.a  #=> MXa

IMPORTANT! prepend is not dynamic, rather it copies all methods when included on a class or module. For this reason one must be careful to invoke prepend AFTER any method definitions that are to be effected. Ideally this would not be necessary, but it would require support in Ruby‘s C+ source to make it possible.

NOTE: This is not a common core extension and is not loaded automatically when using require ‘facets‘.

[Source]

# File lib/facets/core-uncommon/facets/module/prepend.rb, line 55
  def prepend(mod)
    include Prependable
    include mod
  end

[Validate]