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
12: def cattr( *syms )
13: writers, readers = syms.flatten.partition{ |a| a.to_s =~ /=$/ }
14: writers = writers.collect{ |e| e.to_s.chomp('=').to_sym }
15: readers.concat( writers ) # writers also get readers
16: cattr_writer( *writers )
17: cattr_reader( *readers )
18: return readers + writers
19: end
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 102
102: def cattr_accessor(*syms)
103: cattr_reader(*syms) + cattr_writer(*syms)
104: end
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
33: def cattr_reader( *syms )
34: syms.flatten.each do |sym|
35: class_eval("unless defined? @@\#{sym}\n@@\#{sym} = nil\nend\n\ndef self.\#{sym}\n@@\#{sym}\nend\n\ndef \#{sym}\n@@\#{sym}\nend\n", __FILE__, __LINE__)
36: end
37: return syms
38: end
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 69
69: def cattr_writer(*syms)
70: syms.flatten.each do |sym|
71: class_eval("unless defined? @@\#{sym}\n@@\#{sym} = nil\nend\n\ndef self.\#{sym}=(obj)\n@@\#{sym} = obj\nend\n\ndef \#{sym}=(obj)\n@@\#{sym}=(obj)\nend\n", __FILE__, __LINE__)
72: end
73: return syms
74: end
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
12: def descendents
13: subclass = []
14: ObjectSpace.each_object( Class ) do |c|
15: if c.ancestors.include?( self ) and self != c
16: subclass << c
17: end
18: end
19: return subclass
20: end
Translate a class name to a suitable method name.
My::CoolClass.methodize => "my__cool_class"
# File lib/core/facets/class/methodize.rb, line 9
9: def methodize
10: name.methodize
11: end
Converts a class name to a unix path.
My::CoolClass.pathize #=> "my/cool_class"
# File lib/core/facets/class/pathize.rb, line 9
9: def pathize
10: name.pathize
11: end
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
30: def prepend( aspect )
31: _new = method(:new)
32: _allocate = method(:allocate)
33: (class << self; self; end).class_eval do
34: define_method(:new) do |*args|
35: o = _new.call(*args)
36: o.extend aspect
37: o
38: end
39: define_method(:allocate) do |*args|
40: o = _allocate.call(*args)
41: o.extend aspect
42: o
43: end
44: end
45: end
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
18: def to_proc
19: proc{|*args| new(*args)}
20: end