Class Module
In: lib/core/facets/comparable/comparable.rb
lib/core/facets/metaid.rb
lib/core/facets/module/abstract.rb
lib/core/facets/module/alias_accessor.rb
lib/core/facets/module/alias_method_chain.rb
lib/core/facets/module/alias_module_function.rb
lib/core/facets/module/ancestor.rb
lib/core/facets/module/basename.rb
lib/core/facets/module/can.rb
lib/core/facets/module/class.rb
lib/core/facets/module/conflict.rb
lib/core/facets/module/include_function_module.rb
lib/core/facets/module/instance_methods.rb
lib/core/facets/module/is.rb
lib/core/facets/module/methodize.rb
lib/core/facets/module/modspace.rb
lib/core/facets/module/module_load.rb
lib/core/facets/module/nesting.rb
lib/core/facets/module/op.rb
lib/core/facets/module/pathize.rb
lib/core/facets/module/prepend.rb
lib/core/facets/module/redefine_method.rb
lib/core/facets/module/redirect_method.rb
lib/core/facets/module/rename_method.rb
lib/core/facets/module/revise.rb
lib/core/facets/module/spacename.rb
lib/core/facets/module/wrap_method.rb
lib/more/facets/1stclassmethod.rb
lib/more/facets/annotations.rb
lib/more/facets/attr.rb
lib/more/facets/capsule.rb
lib/more/facets/class_extension.rb
lib/more/facets/classmethods.rb
lib/more/facets/dependency.rb
lib/more/facets/equatable.rb
lib/more/facets/memoize.rb
lib/more/facets/methodspace.rb
lib/more/facets/overload.rb
lib/more/facets/paramix.rb
lib/more/facets/settings.rb
Parent: Object

Methods

External Aliases

extend -> can
  An alias for extend.
  class X
    can Forwardable
  end

BTW, why is Forwardable an -able? It‘s not a mixin!

=== -> class?
  Alias for #===. This provides a verbal method for inquery.
  s = "HELLO"
  String.class?(s)  #=> true
remove_method -> remove
undef_method -> nodef
attr_reader -> plain_reader
attr_writer -> plain_writer
attr_accessor -> plain_accessor
attr_accessor -> attribute
  TODO Should attribute alias be kept?
const_missing -> const_missing_before_autoimport
  $autoimport_activated = true
append_features -> append_features_without_class_extension

Public Class methods

[Source]

# File lib/more/facets/class_extension.rb, line 85
      def self.append_features(mod)
        append_features_without_class_extension(mod)
      end

Public Instance methods

Rename methods.

  module A
    def a; "a"; end
  end

  B = A * { :a => :b }

  class X; include B; end

  X.new.b    #=> "a"

  CREDIT: Thomas Sawyer
  CREDIT: Robert Dober

[Source]

# File lib/core/facets/module/op.rb, line 83
  def *(rename_map)
    base = self
    Module.new do
      include base
      rename_map.each do |from, to|
        alias_method to, from
        undef_method from
      end
    end
  end

Combine modules.

  module A
    def a; "a"; end
  end

  module B
    def b; "b"; end
  end

  C = A + B

  class X; include C; end

  X.new.a    #=> "a"
  X.new.b    #=> "b"

Note that in the old version of traits.rb we cloned modules and altered their copies. Eg.

    def +(other)
      mod1 = other.clone
      mod2 = clone
      mod1.module_eval{ include mod2 }
    end

Later it was realized that this thwarted the main benefit that Ruby‘s concept of modules has over traditional traits, inheritance.

  CREDIT: Thomas Sawyer
  CREDIT: Robert Dober

[Source]

# File lib/core/facets/module/op.rb, line 36
  def +(other)
    base = self
    Module.new do
      include base
      include other
    end
  end

Subtract modules.

  TODO: Should this use all instance_methods, not just public?

  CREDIT: Thomas Sawyer
  CREDIT: Robert Dober

[Source]

# File lib/core/facets/module/op.rb, line 51
  def -(other)
    case other
    when Array
      subtract = instance_methods(true) & other.collect{|m| m.to_s}
    when Module
      subtract = instance_methods(true) & other.instance_methods(true)  # false?
    when String, Symbol
      subtract = instance_methods(true) & [other.to_s]
    end
    base = self
    Module.new do
      include base
      subtract.each{ |x| undef_method x }
    end
  end

Automatically generate sorting defintions base on attribute fields.

  include SortOn(:a, :b)

is equivalent to including a module containing:

  def <=>(other)
    cmp = self.a <=> other.a; return cmp unless cmp == 0
    cmp = self.b <=> other.b; return cmp unless cmp == 0
    0
  end

[Source]

# File lib/core/facets/comparable/comparable.rb, line 28
  def Comparable(*accessors)
    define_method(:comparability){ accessors }
    code = %{
      def <=>(other)
        comparability.each do |a|
          cmp = (send(a) <=> other.send(a)); return cmp unless cmp == 0
        end
      end
    }
    module_eval code
    return Comparable
  end

This function provided a "shortcut" for creating the identity method based on given accessors and returns the Equatable module for inclusion.

 include Equatable(:a, :b)

is equivalent to including a module containing:

  def ==(other)
    self.a == other.a && self.b == other.b
  end

  def eql?(other)
    self.a.eql?(other.a) && self.b.eql?(other.b)
  end

  def hash()
    self.a.hash ^ self.b.hash
  end

[Source]

# File lib/more/facets/equatable.rb, line 115
  def Equatable(*accessors)
    Equatable.identify(self, *accessors)
  end

Create an abstract method. If it is not overridden, it will raise a TypeError when called.

  class C
    abstract :a
  end

  c = C.new
  c.a  #=> Error: undefined abstraction #a

 CREDIT: Trans

[Source]

# File lib/core/facets/module/abstract.rb, line 15
  def abstract( *sym )
    sym.each { |s|
      define_method( s ) { raise TypeError, "undefined abstraction ##{s}" }
    }
  end

Create aliases for flag accessors.

 CREDIT: Trans

[Source]

# File lib/more/facets/attr.rb, line 117
  def alias_accessor!(*args)
    orig = args.last
    args = args - [orig]
    args.each do |name|
      alias_method("#{name}?", "#{orig}?")
      alias_method("#{name}!", "#{orig}!")
    end
  end

Encapsulates the common pattern of:

  alias_method :foo_without_feature, :foo
  alias_method :foo, :foo_with_feature

With this, you simply do:

  alias_method_chain :foo, :feature

And both aliases are set up for you.

Query and bang methods (foo?, foo!) keep the same punctuation:

  alias_method_chain :foo?, :feature

is equivalent to

  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.

 CREDIT: Bitsweat
 CREDIT: Rails Team

[Source]

# File lib/core/facets/module/alias_method_chain.rb, line 28
  def alias_method_chain(target, feature)
    # Strip out punctuation on predicates or bang 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?

    with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"

    alias_method without_method, target
    alias_method target, with_method

    case
      when public_method_defined?(without_method)
        public target
      when protected_method_defined?(without_method)
        protected target
      when private_method_defined?(without_method)
        private target
    end
  end

Create aliases for flag reader.

 CREDIT: Trans

[Source]

# File lib/more/facets/attr.rb, line 159
  def alias_reader!(*args)
    orig = args.last
    args = args - [orig]
    args.each do |name|
      alias_method("#{name}?", "#{orig}?")
    end
  end
alias_reader?(*args)

Alias for alias_reader!

Alias an accessor. This create an alias for both a reader and a writer.

  class X
    attr_accessor :a
    alias_accessor :b, :a
  end

  x = X.new
  x.b = 1
  x.a        #=> 1

 CREDIT: Trans

[Source]

# File lib/more/facets/attr.rb, line 81
  def alias_setter(*args)
    args = args - [orig]
    args.each do |name|
      alias_method(name, orig)
    end
  end
alias_switcher(*args)

Alias for alias_accessor!

alias_tester(*args)

Alias for alias_reader!

alias_toggler(*args)

Alias for alias_accessor!

Create aliases for validators.

[Source]

# File lib/more/facets/attr.rb, line 24
  def alias_validator(*args)
    orig = args.last
    args = args - [orig]
    args.each do |name|
      #alias_method(name, orig)
      alias_method("#{name}=", "#{orig}=")
    end
  end

Create aliases for flag writer.

 CREDIT: Trans

[Source]

# File lib/more/facets/attr.rb, line 200
  def alias_writer!(*args)
    orig = args.last
    args = args - [orig]
    args.each do |name|
      alias_method("#{name}!", "#{orig}!")
    end
  end

List all instance methods, equivalent to

  public_instance_methods +
  protected_instance_methods +
  private_instance_methods

TODO: Better name for all_instance_methods?

 CREDIT: Trans

[Source]

# File lib/core/facets/module/instance_methods.rb, line 13
  def all_instance_methods(include_super=true)
    public_instance_methods(include_super) +
    protected_instance_methods(include_super) +
    private_instance_methods(include_super)
  end

Is a given class or module an ancestor of this class or module?

 class X ; end
 class Y < X ; end

  X.ancestor?(Y)

[Source]

# File lib/core/facets/module/ancestor.rb, line 11
  def ancestor?( mod )
    ancestors.include? mod
  end

Set or read annotations.

[Source]

# File lib/more/facets/annotations.rb, line 123
  def ann( ref, keys_or_class=nil, keys=nil )
    return heritage(ref) unless keys_or_class or keys

    if Class === keys_or_class
      keys ||= {}
      keys[:class] = keys_or_class
    else
      keys = keys_or_class
    end

    if Hash === keys
      ref = ref.to_sym
      annotations[ref] ||= {}
      annotations[ref].update(keys.rekey)
    else
      key = keys.to_sym
      heritage(ref)[key]
    end
  end

To change an annotation‘s value in place for a given class or module it first must be duplicated, otherwise the change may effect annotations in the class or module‘s ancestors.

[Source]

# File lib/more/facets/annotations.rb, line 147
  def ann!( ref, keys_or_class=nil, keys=nil )
    #return heritage(ref) unless keys_or_class or keys
    return annotations[ref] unless keys_or_class or keys

    if Class === keys_or_class
      keys ||= {}
      keys[:class] = keys_or_class
    else
      keys = keys_or_class
    end

    if Hash === keys
      ref = ref.to_sym
      annotations[ref] ||= {}
      annotations[ref].update(keys.rekey)
    else
      key = keys.to_sym
      annotations[ref][key] = heritage(ref)[key].dup
    end
  end

[Source]

# File lib/more/facets/annotations.rb, line 108
  def annotations
    #$annotations[self]
    @annotations ||= {}
  end

[Source]

# File lib/more/facets/class_extension.rb, line 95
  def append_features(mod)
    append_features_without_class_extension(mod)
    mod.extend(class_extension)
    if mod.instance_of? Module
      mod.__send__(:class_extension).__send__(:include, class_extension)
    end
  end

[Source]

# File lib/more/facets/classmethods.rb, line 163
  def append_features( base )
    result = append_features_without_classmethods( base )
    if const_defined?( :ClassMethods )
      base.extend( self::ClassMethods )
      unless base.is_a?( Class )
        unless base.const_defined?( :ClassMethods )
          base.const_set( :ClassMethods, Module.new )
        end
        my = self
        base::ClassMethods.class_eval do
          include my::ClassMethods
        end
      end
    end
    result
  end
append_features_without_classmethods(mod)

Alias for append_features

[Source]

# File lib/more/facets/annotations.rb, line 222
  def attr( *args )
    args.flatten!
    case args.last
    when TrueClass
      args.pop
      attr_accessor( *args )
    when FalseClass
      args.pop
      attr_reader( *args )
    else
      attr_reader( *args )
    end
  end

Create a toggle attribute. This creates two methods for each given name. One is a form of tester and the other is used to toggle the value.

  attr_accessor! :a

is equivalent to

  def a?
    @a
  end

  def a!(value=true)
    @a = value
    self
  end

 CREDIT: Trans

[Source]

# File lib/more/facets/attr.rb, line 107
  def attr_accessor!(*args)
    attr_reader!(*args) + attr_writer!(*args)
  end

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

  attr_reader! :a

is equivalent to

  def a?
    @a ? true : @a
  end

[Source]

# File lib/more/facets/attr.rb, line 139
  def attr_reader!(*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
attr_reader?(*args)

Alias for attr_reader!

Create an attribute method for both getting and setting an instance variable.

  attr_setter :a

_is equivalent to_

  def a(*args)
    if args.size > 0
      @a = args[0]
      self
    else
      @a
    end
  end

 CREDIT: Trans

[Source]

# File lib/more/facets/attr.rb, line 53
  def attr_setter(*args)
    code, made = '', []
    args.each do |a|
      code << %{
        def #{a}(*args)
          args.size > 0 ? ( @#{a}=args[0] ; self ) : @#{a}
        end
      }
      made << "#{a}".to_sym
    end
    module_eval code
    made
  end
attr_switcher(*args)

Alias for attr_accessor!

attr_tester(*args)

Alias for attr_reader!

attr_toggler(*args)

Alias for attr_accessor!

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

  CREDIT: ?

[Source]

# File lib/more/facets/attr.rb, line 8
  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

Create a flaggable attribute. This creates a single methods used to set an attribute to "true".

  attr_writer! :a

is equivalent to

  def a!(value=true)
    @a = value
    self
  end

[Source]

# File lib/more/facets/attr.rb, line 181
  def attr_writer!(*args)
    code, made = '', []
    args.each do |a|
      code << %{
        def #{a}!(value=true)
          @#{a} = value
          self
        end
      }
      made << "#{a}!".to_sym
    end
    module_eval code
    made
  end

Returns the root name of the module/class.

  module Example
    class Demo
    end
  end

  Demo.name       #=> "Example::Demo"
  Demo.basename   #=> "Demo"

For anonymous modules this will provide a basename based on Module#inspect.

  m = Module.new
  m.inspect       #=> "#<Module:0xb7bb0434>"
  m.basename      #=> "Module_0xb7bb0434"

  CREDIT: Trans

[Source]

# File lib/core/facets/module/basename.rb, line 22
  def basename
    if name and not name.empty?
      name.gsub(/^.*::/, '')
    else
      nil #inspect.gsub('#<','').gsub('>','').sub(':', '_')
    end
  end

Defines an instance method within a class.

  CREDIT: WhyTheLuckyStiff

[Source]

# File lib/core/facets/metaid.rb, line 82
  def class_def name, &blk
    class_eval { define_method name, &blk }
  end
class_inherit( &yld )

Alias for class_methods

class_load( path )

Alias for module_load

[Source]

# File lib/more/facets/classmethods.rb, line 180
  def class_methods( &yld )
    if const_defined?( :ClassMethods )
      self::ClassMethods.class_eval( &yld )
    else
      self.const_set( :ClassMethods, Module.new( &yld ) )
    end
    extend( self::ClassMethods )
    self::ClassMethods
  end
class_require( path )

Alias for module_require

Return list of attributes that have a :class annotation.

  class MyClass
    attr_accessor :test
    attr_accessor :name, String, :doc => 'Hello'
    attr_accessor :age, Fixnum
  end

  MyClass.instance_attributes # => [:test, :name, :age, :body]
  MyClass.classified_attributes # => [:name, :age]

[Source]

# File lib/more/facets/annotations.rb, line 295
  def classified_attributes
    instance_attributes.find_all do |a|
      self.ann(a, :class)
    end
  end

Detect conflicts.

  module A
    def c; end
  end

  module B
    def c; end
  end

  A.conflict?(B)  #=> ["c"]

  TODO: All instance methods, or just public?

 CREDIT: Thomas Sawyer
 CREDIT: Robert Dober

[Source]

# File lib/core/facets/module/conflict.rb, line 21
  def conflict?(other)
    common_ancestor = (ancestors & other.ancestors).first
    c = []
    c += (public_instance_methods(true) & other.public_instance_methods(true))
    c += (private_instance_methods(true) & other.private_instance_methods(true))
    c += (protected_instance_methods(true) & other.protected_instance_methods(true))
    c -= common_ancestor.public_instance_methods(true)
    c -= common_ancestor.private_instance_methods(true)
    c -= common_ancestor.protected_instance_methods(true)
    c.empty? ? false : c
  end

[Source]

# File lib/more/facets/dependency.rb, line 120
  def define_dependency( name, *deps )
    @dependency ||= {}
    if @dependency[name.to_sym]
      @dependency[name.to_sym] = deps
    else
      @dependency[name.to_sym] = deps
      deplist = lambda{ dependencies(name) }
      alias_method("#{name}:execute",name)
      define_method(name) do |*a|
        # run dependencies
        deplist.call.each do |d|
          if respond_to?("#{d}:execute")
            send("#{d}:execute",*a) #,&b)
          else
            send(d,*a) #,&b)
          end
        end
        # run core method
        send("#{name}:execute",*a) #,&b)
      end
    end
  end

[Source]

# File lib/more/facets/dependency.rb, line 90
  def depend( name_and_deps=nil )
    if Hash === name_and_deps
      name_and_deps.to_h.each do |name, deps|
        deps = [deps].flatten
        define_dependency(name, *deps)
      end
    elsif name_and_deps
      @dependency ||= {}
      @dependency[name_and_deps.to_sym]
    else
      @dependency ||= {}
    end
  end

Compile list of all unique prerequisite calls.

[Source]

# File lib/more/facets/dependency.rb, line 106
  def dependencies(name, build=[])
    @dependency ||= {}
    deps = @dependency[name.to_sym]
    return build unless deps
    deps.each do |dep|
      build.unshift(dep)
      dependencies(dep,build)
    end
    build.uniq!
    build
  end

[Source]

# File lib/more/facets/annotations.rb, line 113
  def heritage(ref)
    ref = ref.to_sym
    ancestors.inject({}) { |memo, ancestor|
      ancestor.annotations[ref] ||= {}
      ancestor.annotations[ref] + memo
    }
  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"

[Source]

# File lib/more/facets/methodspace.rb, line 103
  def include_as(h)
    h.each{ |name, mod| method_space(name, mod) }
  end

Easy access to method as objects, and they retain state!

  module K
    def hello
      puts "Hello World!"
    end
  end
  p K.instance_method!(:hello)   #=> <UnboundMethod: #hello>

NOTE: This is limited to the scope of the current module/class.

[Source]

# File lib/more/facets/1stclassmethod.rb, line 134
  def instance_method!(s)
    #( @@__instance_methods__ ||= {} )[s] ||= instance_method(s)  # TODO when fixed
    ( @__instance_methods__ ||= {} )[s] ||= instance_method(s)
  end

Query whether a public instance method is defined for the module.

 CREDIT: Gavin Sinclair
 CREDIT: Noah Gibbs

[Source]

# File lib/core/facets/module/instance_methods.rb, line 24
  def instance_method_defined?(meth)
    instance_methods(true).find{ |m| m == meth.to_s }
  end

Using integrate is just like using include except the module included is a reconstruction of the one given altered by the commands given in the block.

Convenient commands available are: rename, redef, remove, nodef and wrap. But any module method can be used.

  module W
    def q ; "q" ; end
    def y ; "y" ; end
  end

  class X
    integrate W do
      nodef :y
    end
  end

  x = X.new
  x.q  #=> "q"
  x.y  #=> missing method error

This is like revisal, but revisal only returns the reconstructred module. It does not include it.

 CREDIT: Trans

[Source]

# File lib/core/facets/module/revise.rb, line 51
  def integrate(mod, &block)
    #include mod.revisal( &blk )
    m = Module.new{ include mod }
    m.class_eval(&block)
    include m
  end

alias_method :is, :include

[Source]

# File lib/core/facets/module/is.rb, line 27
  def is(*mods)
    mods.each do |mod|
      if mod.const_defined?(:Self)
        extend mod::Self
        # pass it along if module
        if instance_of?(Module)
          const_set(:Self, Module.new) unless const_defined?(:Self)
          const_get(:Self).send(:include, mod::Self)
        end
      end
    end
    include(*mods)
  end

Is a given class or module an ancestor of this class or module?

 class X ; end
 class Y < X ; end

  Y.is?(X)  #=> true

  CREDIT: Trans

[Source]

# File lib/core/facets/module/is.rb, line 13
  def is?(base)
    ancestors.slice(1..-1).include?(base)
  end

Directive for making your functions faster by trading space for time. When you "memoize" a method/function its results are cached so that later calls with the same arguments returns results in the cache instead of recalculating them.

  class T
    def initialize(a)
      @a = a
    end
    def a
      "#{@a ^ 3 + 4}"
    end
    memoize :a
  end

  t = T.new
  t.a.__id__ == t.a.__id__  #=> true

[Source]

# File lib/more/facets/memoize.rb, line 61
  def memoize(*meths)
    @_MEMOIZE_CACHE ||= Hash.new
    meths.each do |meth|
      mc = @_MEMOIZE_CACHE[meth] = Hash.new
      old = instance_method(meth)
      new = proc do |*args|
        if mc.has_key? args
          mc[args]
        else
          mc[args] = old.bind(self).call(*args)
        end
      end
      send(:define_method, meth, &new)
    end
  end

[Source]

# File lib/more/facets/overload.rb, line 25
  def method_overloads
    @method_overloads ||= {}
  end

Define a simple method namespace.

  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
  a.x  # no method error

[Source]

# File lib/more/facets/methodspace.rb, line 48
  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.instance_eval do
        define_method(m) do
          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|
        mtab[op].bind(self).call(*args)
      end
    end
  end

Translate a module name to a suitable method name.

  My::CoolClass.methodize => "my__cool_class"

[Source]

# File lib/core/facets/module/methodize.rb, line 9
  def methodize
    name.methodize
  end

Store for parametric mixin parameters.

Returns a hash, the keys of which are the parametric mixin module and the values are the parameters associacted with this module/class.

  class C
    include P(:x=>1)
  end

  C.mixin_parameters[P]   #=> {:x=>1}

[Source]

# File lib/more/facets/paramix.rb, line 196
  def mixin_parameters
    @mixin_parameters ||= {}
  end
mixin_params()

Alias for mixin_parameters

Returns the module‘s container module.

  module Example
    class Demo
    end
  end

  Example::Demo.modspace   #=> Example

See also Module#basename.

  CREDIT: Trans

[Source]

# File lib/core/facets/module/modspace.rb, line 16
  def modspace
    space = name[ 0...(name.rindex( '::' ) || 0)]
    space.empty? ? Object : eval(space)
  end

Load file into module/class namespace.

  CREDIT: Trans

[Source]

# File lib/core/facets/module/module_load.rb, line 9
    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
module_method_defined?(meth)

Alias for singleton_method_defined?

Require file into module/class namespace.

  CREDIT: Trans

[Source]

# File lib/core/facets/module/module_load.rb, line 27
    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
      @loaded ||= {}
      if @loaded.key?(file)
        false
      else
        @loaded[file] = true
        script = File.read(file)
        module_eval(script)
        true
      end
    end

Show a modules nesting in module namespaces.

  A::B::C.nesting  #=> [ A, A::B ]

 CREDIT: Trans

[Source]

# File lib/core/facets/module/nesting.rb, line 9
  def nesting
    n = []
    name.split(/::/).inject(self) do |mod, name|
      c = mod.const_get(name) ; n << c ; c
    end
    return n
  end

Overload methods.

  class X
    def x
      "hello"
    end

    overload :x, Integer do |i|
      i
    end

    overload :x, String, String do |s1, s2|
      [s1, s2]
    end
  end

[Source]

# File lib/more/facets/overload.rb, line 45
  def overload( name, *signiture, &block )
    raise ArgumentError unless signiture.all?{|s| s.instance_of?(Class)} 

    name = name.to_sym

    if method_overloads.key?( name )
      method_overloads[name][signiture] = block

    else
      method_overloads[name] = {}
      method_overloads[name][signiture] = block

      if method_defined?( name )
        #method_overloads[name][nil] = instance_method( name ) #true
        alias_method( "#{name}Generic", name )
        has_generic = true
      else
        has_generic = false
      end

      define_method( name ) do |*args|
        ovr = self.class.method_overloads["#{name}".to_sym]
        sig = args.collect{ |a| a.class }
        hit = nil
        faces = ovr.keys #.sort { |a,b| b.size <=> a.size }
        faces.each do |cmp|
          next unless cmp.size == sig.size
          if (0...cmp.size).all?{ |i| cmp[i] >= sig[i] }
            break hit = cmp
          end
        end 
        if hit
          ovr[hit].call(*args)
        else
          if has_generic #ovr[nil]
            send( "#{name}Generic", *args )
            #ovr[nil].bind(self).call(*args)
          else
            raise NoMethodError
          end
        end

      end

    end

  end

Converts a class name to a unix path

Examples

  CoolClass.pathize       #=> "cool_class"
  My::CoolClass.pathize   #=> "my/cool_class"

[Source]

# File lib/core/facets/module/pathize.rb, line 11
  def pathize
    name.pathize
    #to_s.
    #  gsub(/::/, '/').
    #  gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
    #  gsub(/([a-z\d])([A-Z])/,'\1_\2').
    #  tr("-", "_").
    #  downcase
  end

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

  module X
    def x; "x"; end
  end

  module U
    def x; '{' + super + '}'; end
  end

  X.prepend U

  X.x  # => "{x}"

 CREDIT Trans

[Source]

# File lib/core/facets/module/prepend.rb, line 20
  def prepend(aspect)
    aspect.__send__(:include, self)
    extend aspect
  end

Like conflict?, but checks only private methods.

[Source]

# File lib/core/facets/module/conflict.rb, line 47
  def private_conflict?(other)
    common_ancestor = (ancestors & other.ancestors).first
    c = private_instance_methods(true) & other.private_instance_methods(true)
    c -= common_ancestor.private_instance_methods(true)
    c.empty? ? false : c
  end

Like conflict?, but checks only protected methods.

[Source]

# File lib/core/facets/module/conflict.rb, line 55
  def protected_conflict?(other)
    common_ancestor = (ancestors & other.ancestors).first
    c = protected_instance_methods(true) & other.protected_instance_methods(true)
    c -= common_ancestor.protected_instance_methods(true)
    c.empty? ? false : c
  end

Like conflict?, but checks only public methods.

[Source]

# File lib/core/facets/module/conflict.rb, line 39
  def public_conflict?(other)
    common_ancestor = (ancestors & other.ancestors).first
    c = public_instance_methods(true) & other.public_instance_methods(true)
    c -= common_ancestor.public_instance_methods(true)
    c.empty? ? false : c
  end
revisal(&blk)

Alias for revise

Return a new module based on another. This includes the original module into the new one.

 CREDIT: Trans

[Source]

# File lib/core/facets/module/revise.rb, line 13
  def revise(&blk)
    base = self
    nm = Module.new{ include base }
    nm.class_eval(&blk)
    nm
  end

Defines a configuration setting for the enclosing class.

Example

class Compiler

  setting :template_root, :default => 'src/template', :doc => 'The template root dir'

end

[Source]

# File lib/more/facets/settings.rb, line 233
  def setting(sym, options = {})
    Settings.add_setting(self, sym, options)

    module_eval %{
      def self.#{sym}
        Settings[#{self}][:#{sym}].value
      end

      def self.#{sym}=(obj)
        Settings.setting #{self}, :#{sym}, :value => obj
      end
    }
  end

Query whether a normal (singleton) method is defined for the module.

 CREDIT: Gavin Sinclair
 CREDIT: Noah Gibbs

[Source]

# File lib/core/facets/module/instance_methods.rb, line 33
  def singleton_method_defined?(meth)
    singleton_methods(true).find{ |m| m == meth.to_s }
  end

Returns the name of module‘s container module.

  module Example
    class Demo
    end
  end

  Demo.name         #=> "Example::Demo"
  Demo.spacename    #=> "Example"

This used to be called dirname.

See also Module#basename.

 CREDIT: Trans

[Source]

# File lib/core/facets/module/spacename.rb, line 19
  def spacename
    name[0...(name.rindex('::') || 0)]
    #name.gsub(/::[^:]*$/, '')
  end
wrap( sym, &blk )

Alias for wrap_method

Creates a new method wrapping the previous of the same name. Reference to the old method is passed into the new definition block as the first parameter.

  wrap_method( sym ) { |old_meth, *args|
    old_meth.call
    ...
  }

Keep in mind that this can not be used to wrap methods that take a block.

  CREDIT: Trans

[Source]

# File lib/core/facets/module/wrap_method.rb, line 20
  def wrap_method( sym, &blk )
    old = instance_method(sym)
    define_method(sym) { |*args| blk.call(old.bind(self), *args) }
  end

[Validate]