Class Module
In: 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/all_instance_methods.rb
lib/core/facets/module/ancestor.rb
lib/core/facets/module/anonymous.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/home.rb
lib/core/facets/module/include_function_module.rb
lib/core/facets/module/instance_method.rb
lib/core/facets/module/is.rb
lib/core/facets/module/instance_method_defined.rb
lib/core/facets/module/integrate.rb
lib/core/facets/module/method_clash.rb
lib/core/facets/module/methodize.rb
lib/core/facets/module/module_def.rb
lib/core/facets/module/nodef.rb
lib/core/facets/module/op.rb
lib/core/facets/module/pathize.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/set.rb
lib/core/facets/module/spacename.rb
lib/core/facets/module/to_obj.rb
lib/core/facets/module/wrap_method.rb
lib/tour/facets/module/attr_class_accessor.rb
lib/tour/facets/module/attr_inheritor.rb
lib/tour/facets/module/attr_tester.rb
lib/tour/facets/module/attr_validator.rb
lib/tour/facets/module/cattr.rb
lib/tour/facets/module/class_accessor.rb
lib/tour/facets/module/class_extend.rb
lib/tour/facets/module/class_inheritor.rb
lib/tour/facets/module/copy_inheritor.rb
lib/tour/facets/module/enclosure.rb
lib/tour/facets/module/instance_function.rb
lib/tour/facets/module/memoize.rb
lib/tour/facets/module/method_space.rb
lib/tour/facets/module/module_load.rb
lib/tour/facets/module/preextend.rb
lib/tour/facets/module/prepend.rb
Parent: Object

Methods

Included Modules

Memoizable Prependable

Classes and Modules

Module Module::InstanceFunction

External Aliases

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

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

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

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

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

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

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

Create aliases for flag reader.

CREDIT: Trans

Create aliases for validators.

List all instance methods, equivalent to

  public_instance_methods +
  protected_instance_methods +
  private_instance_methods

TODO: Better name for all_instance_methods?

CREDIT: Trans

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

 class X ; end
 class Y < X ; end

  X.ancestor?(Y)

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"

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

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

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

CREDIT: ?

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

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

  class CARExample
    @@a = 10
    cattr :a
  end

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

CREDIT: David Heinemeier Hansson

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

  class CAAExample
    cattr_accessor :a
  end

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

CREDIT: David Heinemeier Hansson

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

  class CARExample
    @@a = 10
    cattr_reader :a
  end

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

CREDIT: David Heinemeier Hansson

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

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

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

CREDIT: David Heinemeier Hansson

Defines an instance method within a class/module.

CREDIT: WhyTheLuckyStiff

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.

CREDIT: Daniel Schierbeck, Thomas Sawyer

THANKS: Nobu Nakada, Ulysses

Class Inheritor

Create an dynamic class inheritable attribute.

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

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

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

  class Y < X
  end

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

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

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

CREDIT: Thomas Sawyer

class_load( path )

Alias for module_load

class_method_defined?(meth)

Alias for singleton_method_defined?

class_require( path )

Alias for module_require

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

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

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

  d.x  #=> ['x']

CREDIT: Thomas Sawyer

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

  module ::EncExample
    module M
      module N
      end
    end
  end

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

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

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

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

  module ::EncExample
    module M
      module N
      end
    end
  end

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

Eclosure name.

  module ::EncExample
    module M
      module N
      end
    end
  end

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

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.

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.

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

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"

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

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

  module MyModule
    instance_function

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

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

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

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

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.

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

CREDIT: Gavin Sinclair, Noah Gibbs

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

An alias for include.

  class IsExample
    is Enumerable
  end

CREDIT: Trans

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

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

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

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

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

CREDIT: David Heinemeier Hansson

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

  c = Class.new do
    mattr_accessor :a
  end

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

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

CREDIT: David Heinemeier Hansson

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

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

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

CREDIT: David Heinemeier Hansson

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

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

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

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

CREDIT: David Heinemeier Hansson

This is here for backward compatibility.

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

  module MethodClashExample

    module A
      def c; end
    end

    module B
      private
      def c; end
    end

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

  end

CREDIT: Thomas Sawyer, Robert Dober

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

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

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

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

  expect NoMethodError do
    a.x
  end

CREDIT: Pit Captain

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"
modname()

Alias for homename

Defines an instance method within a class/module.

CREDIT: WhyTheLuckyStiff

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

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

Converts a class name to a unix path.

  module ::ExamplePathize
    module Example
    end
  end

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

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

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

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

  PreX.preextend(PreU)

  PreX.x  # => "{x}"

CREDIT Trans

Prepend module.

  class X
    def a; "Xa"; end
  end

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

  class X
    prepend M
  end

  X.new.a  #=> MXa

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

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

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)

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

CREDIT: Gavin Sinclair, Noah Gibbs

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

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

[Validate]