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/attr_setter.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/extend.rb
lib/core/facets/module/include_function_module.rb
lib/core/facets/module/instance_method.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/capsule.rb
lib/more/facets/equitable.rb
lib/more/facets/instance_function.rb
lib/more/facets/methodspace.rb
lib/more/facets/module/attr.rb
lib/more/facets/module/attr_tester.rb
lib/more/facets/module/attr_toggler.rb
lib/more/facets/module/attr_validator.rb
lib/more/facets/module/class_extend.rb
Parent: Object

Methods

Classes and Modules

Module Module::InstanceFunction

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
extend -> _extend
remove_method -> remove
undef_method -> nodef
const_missing -> const_missing_before_autoimport
  $autoimport_activated = true
attr_accessor! -> attr_toggler
append_features -> append_features_without_class_extension

Public Class methods

[Source]

# File lib/more/facets/module/class_extend.rb, line 87
      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"

Thomas Sawyer, Robert Dober

[Source]

# File lib/core/facets/module/op.rb, line 80
  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, Robert Dober

[Source]

# File lib/core/facets/module/op.rb, line 35
  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, Robert Dober

[Source]

# File lib/core/facets/module/op.rb, line 49
  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 Equitable module for inclusion.

 include Equitable(: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/equitable.rb, line 115
  def Equitable(*accessors)
    Equitable.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/module/attr.rb, line 32
  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, Rails Team

[Source]

# File lib/core/facets/module/alias_method_chain.rb, line 27
  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
alias_reader?(*args)

Alias for alias_tester

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/core/facets/module/attr_setter.rb, line 49
  def alias_setter(*args)
    args = args - [orig]
    args.each do |name|
      alias_method(name, orig)
    end
  end
alias_switcher(*args)

Alias for alias_accessor!

Create aliases for flag reader.

CREDIT: Trans

[Source]

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

Create aliases for attr_toggler.

CREDIT: Trans

[Source]

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

Alias for alias_accessor!

Create aliases for validators.

[Source]

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

Override append_features to handle class-inheritable extensions.

[Source]

# File lib/more/facets/module/class_extend.rb, line 103
  def append_features(mod)
    append_features_without_class_extension(mod)
    mod.extend(class_extend)
    if mod.instance_of? Module
      mod.__send__(:class_extend).__send__(:include, class_extend)
    end
  end
attr_reader?(*args)

Alias for attr_tester

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/core/facets/module/attr_setter.rb, line 21
  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

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/module/attr.rb, line 22
  def attr_switch_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_tester :a

is equivalent to

  def a?
    @a ? true : @a
  end

[Source]

# File lib/more/facets/module/attr_tester.rb, line 14
  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

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

  attr_toggler :a

is equivalent to

  def a?
    @a ? true : @a
  end

  def a!(value=Exception)
    if Exception
      @a = @a ? false : true
    else
      @a = value
    end
    self
  end

[Source]

# File lib/more/facets/module/attr_toggler.rb, line 25
  def attr_toggler(*args)
    code, made = '', []
    args.each do |a|
      code << %{
        def #{a}!(value=Excception)
          if Exception
            @a = @a ? false : true
          else 
            @a = value
          end
          self
        end
      }
      made << "#{a}!".to_sym
    end
    module_eval code
    made.concat(attr_tester(*args))
    made
  end

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

CREDIT: ?

[Source]

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

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

  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.

[Source]

# File lib/more/facets/module/class_extend.rb, line 85
  def class_extend(*mods, &block)
    @class_extension ||= Module.new do
      def self.append_features(mod)
        append_features_without_class_extension(mod)
      end
    end
    @class_extension.__send__(:include, *mods)
    @class_extension.module_eval(&block) if block_given?
    extend(@class_extension)  # extend this module too
    @class_extension
  end
class_extension(*mods, &block)

Alias for class_extend

class_load( path )

Alias for module_load

class_require( path )

Alias for module_require

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, Robert Dober

[Source]

# File lib/core/facets/module/conflict.rb, line 20
  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/core/facets/module/extend.rb, line 5
  def extend(*mod, &blk)
    _extend *mod unless mod.empty?
    _extend Module.new(&blk) if blk
  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

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

  class String
    include MyModule
  end

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

  "Try".jumble( "Me" )            #=> 'TryMe'

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

[Source]

# File lib/more/facets/instance_function.rb, line 30
  def instance_function(*meths)
    if meths.empty?
      extend InstanceFunction
    else
      meths.each do |meth|
        class_eval %{
          def #{meth}(*args)
            #{self.name}.#{meth}(self,*args)
          end
        }
      end
    end
  end

Access method as a singleton object and 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/core/facets/module/instance_method.rb, line 17
  def instance_method!(s)
    #( @@__instance_methods__ ||= {} )[s] ||= instance_method(s)  # TODO: use class vars for 1.9+ ?
    #( @__instance_methods__ ||= {} )[s.to_sym] ||= instance_method(s.to_sym)
    $FIRST_CLASS_INSTANCE_METHODS[self][s.to_sym] ||= instance_method(s.to_sym)
  end

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

CREDIT: Gavin Sinclair, Noah Gibbs

[Source]

# File lib/core/facets/module/instance_methods.rb, line 23
  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

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

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 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.

CREDIT: Trans

[Source]

# File lib/core/facets/module/module_load.rb, line 12
  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.

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.

CREDIT: Trans

[Source]

# File lib/core/facets/module/module_load.rb, line 41
  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

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

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 46
  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 54
  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 38
  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

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

CREDIT: Gavin Sinclair, Noah Gibbs

[Source]

# File lib/core/facets/module/instance_methods.rb, line 31
  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]