class Class

Public Instance Methods

cattr( *syms ) click to toggle source

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

NOTE This used to be a Module method. But turns out it does not work as expected when included. The class-level method is not carried along. So it is now just a Class method. Accordingly, mattr has been deprecated.

CREDIT: David Heinemeier Hansson

# File lib/core/facets/class/cattr.rb, line 12
def cattr( *syms )
  writers, readers = syms.flatten.partition{ |a| a.to_s =~ %r=$/ }
  writers = writers.collect{ |e| e.to_s.chomp('=').to_sym }
  readers.concat( writers ) # writers also get readers
  cattr_writer( *writers )
  cattr_reader( *readers )
  return readers + writers
end
cattr_accessor(*syms) click to toggle source

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

class MyClass
  cattr_accessor :a
end

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

CREDIT: David Heinemeier Hansson

# File lib/core/facets/class/cattr.rb, line 100
def cattr_accessor(*syms)
  cattr_reader(*syms) + cattr_writer(*syms)
end
cattr_reader( *syms ) click to toggle source

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

class MyClass
  @@a = 10
  cattr_reader :a
end

MyClass.a           #=> 10
MyClass.new.a       #=> 10

CREDIT: David Heinemeier Hansson

# File lib/core/facets/class/cattr.rb, line 33
  def cattr_reader( *syms )
    syms.flatten.each do |sym|
      class_eval("        unless defined? @@#{sym}
          @@#{sym} = nil
        end

        def self.#{sym}
          @@#{sym}
        end

        def #{sym}
          @@#{sym}
        end
", __FILE__, __LINE__)
    end
    return syms
  end
cattr_writer(*syms) click to toggle source

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

class MyClass
  cattr_writer :a
  def a
    @@a
  end
end

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

CREDIT: David Heinemeier Hansson

# File lib/core/facets/class/cattr.rb, line 68
  def cattr_writer(*syms)
    syms.flatten.each do |sym|
      class_eval("        unless defined? @@#{sym}
          @@#{sym} = nil
        end

        def self.#{sym}=(obj)
          @@#{sym} = obj
        end

        def #{sym}=(obj)
          @@#{sym}=(obj)
        end
", __FILE__, __LINE__)
    end
    return syms
  end
class_extend(*mods, &block) click to toggle source

For Class, class_extend is the same as class_eval. The alternative is to "undef_method :#class_extend", but this seems uneccessarily limited.

# File lib/more/facets/class_extend.rb, line 118
def class_extend(*mods, &block)
  m = Module.new
  m.__send__(:include, *mods)
  m.module_eval(&block)
  extend(m)
  m
end
descendents() click to toggle source

List all descedents of this class.

class X ; end
class A < X; end
class B < X; end
X.descendents  #=> [A,B]

NOTE: This is a intesive operation. Do not expect it to be super fast.

# File lib/core/facets/class/descendents.rb, line 12
def descendents
  subclass = []
  ObjectSpace.each_object( Class ) do |c|
    if c.ancestors.include?( self ) and self != c
      subclass << c
    end
  end
  return subclass
end
methodize() click to toggle source

Translate a class name to a suitable method name.

My::CoolClass.methodize => "my__cool_class"
# File lib/core/facets/class/methodize.rb, line 9
def methodize
  name.methodize
end
new(*args, &blk) click to toggle source
# File lib/more/facets/preinitialize.rb, line 90
def new(*args, &blk)
  o = allocate

  #if respond_to?(:default_instance_variables)
  #  default_instance_variables.each{|k,v| o.instance_variable_set( "@#{k.to_s.gsub(/\W$/,'')}",v )}
  #end

  a = ancestors
  until a.empty?
    m = a.pop
    #if m.private_instance_methods.include?('preinitialize') or m.public_instance_methods.include?('preinitialize')
    if m.method_defined?('preinitialize') or m.private_method_defined?('preinitialize')
      im = instance_method('preinitialize')
      im.arity == 0 ? im.bind(o).call : im.bind(o).call(*args, &blk)
    end
  end

  o.__send__(:initialize, *args, &blk) if o.object_class.private_method_defined?(:initialize)

  o
end
Also aliased as: postinitialize_new
pathize() click to toggle source

Converts a class name to a unix path.

My::CoolClass.pathize  #=> "my/cool_class"
# File lib/core/facets/class/pathize.rb, line 9
def pathize
  name.pathize
end
postinitialize_new(*args, &blk) click to toggle source
Alias for: new
prepend( aspect ) click to toggle source

Prepend an "aspect module" to a class.

class Firetruck
  def put_out_fire(option)
    "Put out #{option}"
  end
end

module FastFiretruck
  def put_out_fire(option)
    super("very #{option}!")
  end
end

Firetruck.prepend(FastFiretruck)

ft = Firetruck.new
ft.put_out_fire('fast') #=> "Put out very fast!"

Implementation of this method has some limitations, in that it works by overriding new and allocate.

CREDIT: Trans

TODO: Perhaps rename this to preallocate, b/c of the way it works. It is not really a clean prepend, like that of Module#prepend.

# File lib/core/facets/class/prepend.rb, line 30
def prepend( aspect )
  _new      = method(:new)
  _allocate = method(:allocate)
  (class << self; self; end).class_eval do
    define_method(:new) do |*args|
      o = _new.call(*args)
      o.extend aspect
      o
    end
    define_method(:allocate) do |*args|
      o = _allocate.call(*args)
      o.extend aspect
      o
    end
  end
end
to_proc() click to toggle source

Convert instatiation of a class into a Proc.

class Person
  def initialize(name)
    @name = name
  end

  def inspect
    @name.to_str
  end
end

%w(john bob jane hans).map(&Person) => [john, bob, jane, hans]

CREDIT: Daniel Schierbeck

# File lib/core/facets/class/to_proc.rb, line 18
def to_proc
  proc{|*args| new(*args)}
end