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 =~ /=$/ } 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
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 def cattr_accessor(*syms) cattr_reader(*syms) + cattr_writer(*syms) 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 def cattr_reader( *syms ) syms.flatten.each do |sym| 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__) end return syms 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 def cattr_writer(*syms) syms.flatten.each do |sym| 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__) end return syms 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 def descendents subclass = [] ObjectSpace.each_object( Class ) do |c| if c.ancestors.include?( self ) and self != c subclass << c end end return subclass 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 def methodize name.methodize end
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
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
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