Class Module
In: lib/facets/core/facets/module/instance_method_defined.rb
lib/facets/core/facets/module/all_instance_methods.rb
lib/facets/core/facets/module/redirect_method.rb
lib/facets/core/facets/module/pathize.rb
lib/facets/core/facets/module/integrate.rb
lib/facets/core/facets/module/nodef.rb
lib/facets/core/facets/module/instance_method.rb
lib/facets/core/facets/module/is.rb
lib/facets/core/facets/module/home.rb
lib/facets/core/facets/module/set.rb
lib/facets/core/facets/module/op.rb
lib/facets/core/facets/module/can.rb
lib/facets/core/facets/module/alias_module_function.rb
lib/facets/core/facets/module/module_def.rb
lib/facets/core/facets/module/rename_method.rb
lib/facets/core/facets/module/revise.rb
lib/facets/core/facets/module/anonymous.rb
lib/facets/core/facets/module/class.rb
lib/facets/core/facets/module/spacename.rb
lib/facets/core/facets/module/include_function_module.rb
lib/facets/core/facets/module/redefine_method.rb
lib/facets/core/facets/module/ancestor.rb
lib/facets/core/facets/module/methodize.rb
lib/facets/core/facets/module/basename.rb
lib/facets/core/facets/module/alias_accessor.rb
lib/facets/core/facets/module/abstract.rb
lib/facets/core/facets/module/to_obj.rb
lib/facets/core/facets/module/alias_method_chain.rb
lib/facets/core/facets/module/attr_setter.rb
lib/facets/core/facets/module/wrap_method.rb
Parent: Object

Methods

External Aliases

undef_method -> nodef
  Alias for undef_method. This has been called "nodef" instead of undef to help clarify that it doesn‘t get rid of the method, but rather represses repsonse.
remove_method -> remove
  Alias for remove_method. This method actually "undefines" a method and will raise an error is the method is not defined in receiver.
extend -> can
  An alias for extend.
  module EgCan
    def foo; "foo"; end
  end

  class EgCanClass
    can EgCan
  end

  EgCanClass.foo  #=> 'foo'

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
alias_method -> alias_setter
  Alias an accessor. This create an alias for both a reader and a writer.
  class AttrSetterExample
    attr_setter :a
    alias_setter :b, :a
  end

  x = AttrSetterExample.new
  x.b(1)
  x.a        #=> 1

CREDIT: Trans

Public Instance methods

Rename methods.

  module AStar
    def a; "a"; end
  end

  BStar = AStar * { :a => :b }

  class XStar; include BStar; end

  XStar.new.b    #=> "a"

CREDIT: Thomas Sawyer, Robert Dober

[Source]

# File lib/facets/core/facets/module/op.rb, line 95
  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 APlus
    def a; "a"; end
  end

  module BPlus
    def b; "b"; end
  end

  CPlus = APlus + BPlus

  class XPlus; include CPlus; end

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

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

  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/facets/core/facets/module/op.rb, line 35
  def +(other)
    base = self
    Module.new do
      include base
      include other
    end
  end

Subtract modules.

  module AMinus
    def a; "a"; end
    def b; "b"; end
  end

  CMinus = AMinus - [:a]

  class XMinus; include CMinus; end

  expect NameError do
    XMinus.new.a  #=> "a"
  end

  XMinus.new.b    #=> "b"

TODO: Should this use all instance methods, not just public?

CREDIT: Thomas Sawyer, Robert Dober

[Source]

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

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

  class AbstractExample
    abstract :a
  end

  c = AbstractExample.new

  expect TypeError do
    c.a
  end

CREDIT: Trans

[Source]

# File lib/facets/core/facets/module/abstract.rb, line 18
  def abstract(*sym)
    sym.each do |s|
      define_method(s){ raise TypeError, "undefined abstraction ##{s}" }
    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

For example

  class AliasMethodChainExample
    def foo
      "foo"
    end

    def foo_with_feature
      "foo!"
    end

    alias_method_chain :foo, :feature
  end

And both aliases are set up for you.

  example = AliasMethodChainExample.new
  example.foo #=> "foo!"
  example.foo_without_feature #=> "foo"

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

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/facets/core/facets/module/all_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/facets/core/facets/module/ancestor.rb, line 11
  def ancestor?( mod )
    ancestors.include?(mod)
  end

A module may or may not have a name.

module M; end M.name # => "M"

m = Module.new m.name # => ""

A module gets a name when it is first assigned to a constant. Either via the module or class keyword or by an explicit assignment:

m = Module.new # creates an anonymous module M = m # => m gets a name here as a side-effect m.name # => "M"

[Source]

# File lib/facets/core/facets/module/anonymous.rb, line 18
  def anonymous?
    # The name of an anonymous class is an empty
    # string in 1.8, and nil in 1.9.
    name.nil? || name.empty?
  end

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/facets/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

Returns the root name of the module/class.

  module ::BaseName
    class Example
    end
  end

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

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/facets/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/module.

CREDIT: WhyTheLuckyStiff

[Source]

# File lib/facets/core/facets/module/module_def.rb, line 7
  def class_def name, &blk
    class_eval { define_method name, &blk }
  end
class_method_defined?(meth)

Alias for singleton_method_defined?

Returns the module or class containing the receiver.

  module ::HomeExample
    module M
      module N
      end
    end
  end

  HomeExample::M::N.home  #=> HomeExample::M

The home of a top-level module/class is Object.

  HomeExample.home   #=> Object

This method is called home because techinally a module or class is just a constant reference, and as such can reside with multiple namespaces, like any variable. For example:

  module OtherPlace
    M = ::HomeExample::M
  end

In this example, you might think that +OtherPlace::M+’s home would be OtherPlace, but +OtherPlace::M+ is the same object as +HomeExample::M+, and it can have only one "home" —the original location of it‘s definition.

[Source]

# File lib/facets/core/facets/module/home.rb, line 29
  def home
    #homename = /::[^:]+\Z/ =~ name ? $` : nil
    if homename
      homename.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 the name of module or class containing the receiver.

  module ::HomeExample
    module M
      module N
      end
    end
  end

  HomeExample::M::N.homename  #=> "HomeExample::M"

See also Module#basename.

[Source]

# File lib/facets/core/facets/module/home.rb, line 57
  def homename
    /::[^:]+\Z/ =~ name ? $` : nil
  end

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

  module ::HouseExample
    module M
      module N
      end
    end
  end

  HouseExample.housing        #=> [Object]
  HouseExample::M.housing     #=> [HouseExample, Object]
  HouseExample::M::N.housing  #=> [HouseExample::M, HouseExample, Object]

Compare this to +Module.nesting+.

[Source]

# File lib/facets/core/facets/module/home.rb, line 80
  def housing
    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

Access method as a singleton object and retain state.

  module ::K
    def hello
      puts "Hello World!"
    end
  end

  K.instance_method!(:hello).inspect   #=> "#<UnboundMethod: K#hello>"

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

[Source]

# File lib/facets/core/facets/module/instance_method.rb, line 18
  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/facets/core/facets/module/instance_method_defined.rb, line 7
  def instance_method_defined?(meth)
    instance_methods(true).find{ |m| m.to_sym == meth.to_sym }
  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 IntegrateExampleModule
    def q ; "q" ; end
    def y ; "y" ; end
  end

  class InegrateExampleClass
    integrate IntegrateExampleModule do
      undef_method :y
    end
  end

  x = InegrateExampleClass.new
  x.q  #=> "q"

  expect NameError do
    x.y
  end

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

CREDIT: Trans

[Source]

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

An alias for include.

  class IsExample
    is Enumerable
  end

CREDIT: Trans

[Source]

# File lib/facets/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 a given class or module an ancestor of this class or module?

  class IsX ; end
  class IsY < IsX ; end

  IsY.is?(IsX)  #=> true

CREDIT: Trans

[Source]

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

Translate a module name to a suitable method name.

  module ::EgMethodize
    module Eg
    end
  end

  EgMethodize.methodize      #=> "eg_methodize"
  EgMethodize::Eg.methodize  #=> "eg_methodize__eg"

[Source]

# File lib/facets/core/facets/module/methodize.rb, line 15
  def methodize
    name.methodize
  end
modname()

Alias for homename

Defines an instance method within a class/module.

CREDIT: WhyTheLuckyStiff

[Source]

# File lib/facets/core/facets/module/module_def.rb, line 15
  def module_def name, &blk
    module_eval { define_method name, &blk }
  end
module_method_defined?(meth)

Alias for singleton_method_defined?

Converts a class name to a unix path.

  module ::ExamplePathize
    module Example
    end
  end

  ExamplePathize.pathize           #=> "example_pathize"
  ExamplePathize::Example.pathize  #=> "example_pathize/example"

[Source]

# File lib/facets/core/facets/module/pathize.rb, line 15
  def pathize
    name.pathize
  end
revisal(&blk)

Alias for revise

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

  module ReviseExample
    def foo; "foo"; end
  end

  ReviseExample2 = ReviseExample.revise do
    alias_method :bar, :foo
  end

  object = Object.new
  object.extend ReviseExample2
  object.bar  #=> 'foo'

CREDIT: Trans

[Source]

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

Sets an option to the given value. If the value is a proc, the proc will be called every time the option is accessed.

CREDIT: Blake Mizerany (Sinatra)

[Source]

# File lib/facets/core/facets/module/set.rb, line 10
    def set(option, value=self, &block)
      raise ArgumentError if block && value != self
      value = block if block
      if value.kind_of?(Proc)
        if value.arity == 1
          yield self
        else
          (class << self; self; end).module_eval do
            define_method(option, &value)
            define_method("#{option}?"){ !!__send__(option) }
            define_method("#{option}="){ |val| set(option, Proc.new{val}) }
          end
        end
      elsif value == self
        option.each{ |k,v| set(k, v) }
      elsif respond_to?("#{option}=")
        __send__("#{option}=", value)
      else
        set(option, Proc.new{value})
      end
      self
    end

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

CREDIT: Gavin Sinclair, Noah Gibbs

[Source]

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

Returns the name of module‘s container module.

  module ::SpaceName
    class Example
    end
  end

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

This used to be called dirname.

See also Module#basename.

CREDIT: Trans

[Source]

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

Create an instance of Object and extend it with self.

  mod = Module.new do
    def foo; "foo"; end
  end

  obj = mod.to_obj

  obj.foo #=> "foo"

[Source]

# File lib/facets/core/facets/module/to_obj.rb, line 13
  def to_obj
    o = Object.new
    o.extend self
    o
  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.

  class WrapExample
    def foo
      "foo"
    end

    wrap_method(:foo) do |old_meth, *args|
      old_meth.call + '!'
    end
  end

  example = WrapExample.new
  example.foo #=> 'foo!'

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

CREDIT: Trans

[Source]

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

Private Instance methods

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

[Source]

# File lib/facets/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 a module function so that the alias is also a module function. The typical alias_method does not do this.

  module AliasExample
    module_function
    def hello
      "Hello"
    end
  end

  AliasExample.hello  #=> 'Hello'

  module AliasExample
    alias_module_function( :hi , :hello )
  end

  AliasExample.hi     #=> 'Hello'

[Source]

# File lib/facets/core/facets/module/alias_module_function.rb, line 24
  def alias_module_function(new, old)
    alias_method(new, old)
    module_function(new)
  end

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

[Source]

# File lib/facets/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

As with alias_method but does the writer instead.

[Source]

# File lib/facets/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 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

[Source]

# File lib/facets/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

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

[Source]

# File lib/facets/core/facets/module/redefine_method.rb, line 26
  def redefine_method(sym, aka=nil, &blk)
    alias_method(aka, sym) if aka
    ## prevent warning about method overwrite
    begin remove_method(sym) rescue NameError end
    ## define replacelemt method
    define_method(sym, &blk)
  end
redirect( method_hash )

Alias for redirect_method

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 RedirectExample
    redirect_method :hi => :hello, :hey => :hello
    def hello(name)
      "Hello, #{name}."
    end
  end

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

The above class definition is equivalent to …

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

CREDIT: Trans

[Source]

# File lib/facets/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
rename( to_sym, from_sym )

Alias for rename_method

Aliases a method and undefines the original.

  class RenameExample
    def foo; "foo"; end
    rename_method(:bar, :foo)
  end

  example = RenameExample.new
  example.bar  #=> 'foo'

  expect NoMethodError do
    example.foo
  end

CREDIT: Trans

[Source]

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

[Validate]