class Module

It would nice if we could the following. Then the middle portion of the #Comparable method would not be needed. But I fear it might break others code.

 module Comparable

  def <=>(other)
    comparability.each do |field|
      cmp = send(field) <=> other.send(field); return cmp unless cmp == 0
    end
  end

end

Public Class Methods

append_features(mod) click to toggle source
# File lib/more/facets/class_extend.rb, line 87
def self.append_features(mod)
  append_features_without_class_extension(mod)
end

Public Instance Methods

*(rename_map) click to toggle source

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

# 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
+(other) click to toggle source

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

# File lib/core/facets/module/op.rb, line 35
def +(other)
  base = self
  Module.new do
    include base
    include other
  end
end
-(other) click to toggle source

Subtract modules.

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

CREDIT: Thomas Sawyer, Robert Dober

# 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
Comparable(*accessors) click to toggle source

Automatically generate sorting definitions based on attribute fields.

include Comparable(: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
# File lib/core/facets/comparable/comparable.rb, line 28
def Comparable(*accessors)
  define_method(:comparability){ accessors }
  code = %Q{
    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
Equitable(*accessors) click to toggle source

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
# File lib/more/facets/equitable.rb, line 115
def Equitable(*accessors)
  Equitable.identify(self, *accessors)
end
abstract( *sym ) click to toggle source

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

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

Create aliases for flag accessors.

CREDIT: Trans

# 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
Also aliased as: alias_switcher, alias_toggler
alias_method_chain(target, feature) { |aliased_target, punctuation| ... } click to toggle source

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

# 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_setter(*args) click to toggle source

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

# 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!
alias_tester(*args) click to toggle source

Create aliases for flag reader.

CREDIT: Trans

# 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
Also aliased as: alias_reader?
alias_toggler(*args)
Alias for: alias_accessor!
alias_validator(*args) click to toggle source

Create aliases for validators.

# 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
alias_writer!(*args) click to toggle source

Create aliases for flag writer.

CREDIT: Trans

# 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
all_instance_methods(include_super=true) click to toggle source

List all instance methods, equivalent to

public_instance_methods +
protected_instance_methods +
private_instance_methods

TODO: Better name for all_instance_methods?

CREDIT: Trans

# 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
ancestor?( mod ) click to toggle source

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

class X ; end
class Y < X ; end

 X.ancestor?(Y)
# File lib/core/facets/module/ancestor.rb, line 11
def ancestor?( mod )
  ancestors.include? mod
end
append_features(mod) click to toggle source

Override append_features to handle class-inheritable extensions.

# File lib/more/facets/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
append_features_without_class_extension(mod)
Alias for: append_features
attr_reader?(*args)
Alias for: attr_tester
attr_setter(*args) click to toggle source

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

# File lib/core/facets/module/attr_setter.rb, line 21
def attr_setter(*args)
  code, made = '', []
  args.each do |a|
    code << %Q{
      def #{a}(*args)
        args.size > 0 ? ( @#{a}=args[0] ; self ) : @#{a}
      end
    }
    made << "#{a}".to_sym
  end
  module_eval code
  made
end
attr_switch_accessor(*args) click to toggle source

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

# File lib/more/facets/module/attr.rb, line 22
def attr_switch_accessor(*args)
  attr_reader!(*args) + attr_writer!(*args)
end
attr_tester(*args) click to toggle source

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
# File lib/more/facets/module/attr_tester.rb, line 14
def attr_tester(*args)
  code, made = '', []
  args.each do |a|
    code << %Q{
      def #{a}?(truth=nil)
        @#{a} ? truth || @#{a} : @#{a}
      end
    }
    made << "#{a}?".to_sym
  end
  module_eval code
  made
end
Also aliased as: attr_reader?
attr_toggler(*args) click to toggle source

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
# File lib/more/facets/module/attr_toggler.rb, line 25
def attr_toggler(*args)
  code, made = '', []
  args.each do |a|
    code << %Q{
      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
attr_validator(*symbols, &validator) click to toggle source

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

CREDIT: ?

# 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
attr_writer!(*args) click to toggle source

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
# File lib/more/facets/module/attr.rb, line 55
def attr_writer!(*args)
  code, made = '', []
  args.each do |a|
    code << %Q{
      def #{a}!(value=true)
        @#{a} = value
        self
      end
    }
    made << "#{a}!".to_sym
  end
  module_eval code
  made
end
basename() click to toggle source

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

# 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
class_def(name, &blk) click to toggle source

Defines an instance method within a class/module.

CREDIT: WhyTheLuckyStiff

# File lib/core/facets/module/module_def.rb, line 7
def class_def name, &blk
  class_eval { define_method name, &blk }
end
class_extend(*mods, &block) click to toggle source

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.

# File lib/more/facets/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
Also aliased as: class_extension
class_extension(*mods, &block)

TODO: DEPRECATE

Alias for: class_extend
class_load( path )
Alias for: module_load
class_require( path )
Alias for: module_require
conflict?(other) click to toggle source

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

# 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
include_as(h) click to toggle source

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"
# File lib/more/facets/methodspace.rb, line 108
def include_as(h)
  h.each{ |name, mod| method_space(name, mod) }
end
instance_function(*meths) click to toggle source

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.

# 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 %Q{
        def #{meth}(*args)
          #{self.name}.#{meth}(self,*args)
        end
      }
    end
  end
end
instance_method!(s) click to toggle source

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.

# 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
instance_method_defined?(meth) click to toggle source

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

CREDIT: Gavin Sinclair, Noah Gibbs

# 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
integrate(mod, &block) click to toggle source

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

# 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
is(*mods) click to toggle source

An alias for include.

class X
  is Enumerable
end

CREDIT: Trans

# File lib/core/facets/module/is.rb, line 25
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?(base) click to toggle source

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

# File lib/core/facets/module/is.rb, line 13
def is?(base)
  Module===base && ancestors.slice(1..-1).include?(base)
end
method_space(name, mod=nil, &blk) click to toggle source

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
# 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.module_eval %Q{
      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|
      mtab[op].bind(self).call(*args)
    end
  end
end
methodize() click to toggle source

Translate a module name to a suitable method name.

My::CoolClass.methodize => "my__cool_class"
# File lib/core/facets/module/methodize.rb, line 9
def methodize
  name.methodize
end
modspace() click to toggle source

Returns the module's container module.

module Example
  class Demo
  end
end

Example::Demo.modspace   #=> Example

See also #basename.

CREDIT: Trans

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

Defines an instance method within a class/module.

CREDIT: WhyTheLuckyStiff

# File lib/core/facets/module/module_def.rb, line 15
def module_def name, &blk
  module_eval { define_method name, &blk }
end
module_load( path ) click to toggle source

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

# 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
Also aliased as: class_load
module_method_defined?(meth)
module_require( path ) click to toggle source

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

# 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
Also aliased as: class_require
nesting() click to toggle source

Show a modules nesting in module namespaces.

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

CREDIT: Trans

# 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
pathize() click to toggle source

Converts a class name to a unix path

Examples

CoolClass.pathize       #=> "cool_class"
My::CoolClass.pathize   #=> "my/cool_class"
# 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(aspect) click to toggle source

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

# File lib/core/facets/module/prepend.rb, line 20
def prepend(aspect)
  aspect.__send__(:include, self)
  extend aspect
end
private_conflict?(other) click to toggle source

Like conflict?, but checks only private methods.

# 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
protected_conflict?(other) click to toggle source

Like conflict?, but checks only protected methods.

# 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
public_conflict?(other) click to toggle source

Like conflict?, but checks only public methods.

# 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
revise(&blk) click to toggle source

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

CREDIT: Trans

# 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
Also aliased as: revisal
singleton_method_defined?(meth) click to toggle source

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

CREDIT: Gavin Sinclair, Noah Gibbs

# 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
Also aliased as: module_method_defined?
spacename() click to toggle source

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

CREDIT: Trans

# 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
wrap_method( sym, &blk ) click to toggle source

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

# 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
Also aliased as: wrap

Private Instance Methods

alias_accessor(*args) click to toggle source

As with alias_method, but alias both reader and writer.

attr_accessor :x
self.x = 1
alias_accessor :y, :x
y #=> 1
self.y = 2
x #=> 2
# File lib/core/facets/module/alias_accessor.rb, line 14
def alias_accessor(*args)
  orig = args.last
  args = args - [orig]
  args.each do |name|
    alias_method(name, orig)
    alias_method("#{name}=", "#{orig}=")
  end
end
alias_module_function(new, old) click to toggle source

Alias a module function so that the alias is also a module function. The typical alias_method does not do this.

module Demo
  module_function
  def hello
    "Hello"
  end
end

Demo.hello    #=> Hello

module Demo
  alias_module_function( :hi , :hello )
end

Demo.hi       #=> Hello
# File lib/core/facets/module/alias_module_function.rb, line 24
def alias_module_function(new, old)
  alias_method(new, old)
  module_function(new)
end
alias_reader(*args) click to toggle source

As with #alias_accessor, but just for the reader. This is basically the same as alias_method.

# File lib/core/facets/module/alias_accessor.rb, line 26
def alias_reader(*args)
  orig = args.last
  args = args - [orig]
  args.each do |name|
    alias_method(name, orig)
  end
end
alias_writer(*args) click to toggle source

As with alias_method but does the writer instead.

# File lib/core/facets/module/alias_accessor.rb, line 36
def alias_writer(*args)
  orig = args.last
  args = args - [orig]
  args.each do |name|
    alias_method("#{name}=", "#{orig}=")
  end
end
include_function_module(*mod) click to toggle source

Include module and apply module_fuction to the included methods.

module Utils
  module_function
  def foo; "foo"; end
end

module UtilsPlus
  include_function_module Utils
end

CREDIT: Trans

# File lib/core/facets/module/include_function_module.rb, line 19
def include_function_module *mod
  include(*mod)
  module_function(*mod.collect{|m| m.private_instance_methods & m.methods(false)}.flatten)
end
redef(sym, aka=nil, &blk)
Alias for: redefine_method
redefine_method(sym, aka=nil, &blk) click to toggle source

Creates a new method for a pre-existing method.

If aka is given, then the method being redefined will first be aliased to this name.

class Greeter
  def hello ; "Hello" ; end
end

Greeter.new.hello   #=> "Hello"

class Greeter
  redefine_method( :hello, :hi ) do
    hi + ", friend!"
  end
end

Greeter.new.hello   #=> "Hello, friend!"

CREDIT: Trans

# File lib/core/facets/module/redefine_method.rb, line 26
def redefine_method(sym, aka=nil, &blk)
  raise ArgumentError, "method does not exist" unless method_defined?( sym )
  alias_method( aka, sym ) if aka
  undef_method( sym )
  define_method( sym, &blk )
end
Also aliased as: redef
redirect( method_hash )
Alias for: redirect_method
redirect_method( method_hash ) click to toggle source

Redirect methods to other methods. This simply defines methods by the name of a hash key which calls the method with the name of the hash's value.

class Example
  redirect_method :hi => :hello, :hey => :hello
  def hello(name)
    puts "Hello, #{name}."
  end
end

e = Example.new
e.hello("Bob")    #=> "Hello, Bob."
e.hi("Bob")       #=> "Hello, Bob."
e.hey("Bob")      #=> "Hello, Bob."

The above class definition is equivalent to:

class Example
  def hi(*args)
    hello(*args)
  end
  def hey(*args)
    hello(*args)
  end
  def hello
    puts "Hello"
  end
end

CREDIT: Trans

# File lib/core/facets/module/redirect_method.rb, line 37
def redirect_method( method_hash )
  method_hash.each do |targ,adv|
    define_method(targ) { |*args| send(adv,*args) }
  end
end
Also aliased as: redirect
rename( to_sym, from_sym )
Alias for: rename_method
rename_method( to_sym, from_sym ) click to toggle source

Aliases a method and undefines the original.

rename_method( :to_method, :from_method  )

CREDIT: Trans

# File lib/core/facets/module/rename_method.rb, line 11
def rename_method( to_sym, from_sym )
  raise ArgumentError, "method #{from_sym} does not exist" unless method_defined?( from_sym )
  alias_method( to_sym, from_sym )
  undef_method( from_sym )
end
Also aliased as: rename