Module: Doodle::Factory
- Defined in:
- lib/doodle.rb
Overview
A factory function is a function that has the same name as a class which acts just like class.new. For example:
Cat(:name => 'Ren')
is the same as:
Cat.new(:name => 'Ren')
As the notion of a factory function is somewhat contentious [xref ruby-talk], you need to explicitly ask for them by including Factory in your base class:
class Base < Doodle::Root
include Factory
end
class Dog < Base
end
stimpy = Dog(:name => 'Stimpy')
etc.
Constant Summary collapse
- RX_IDENTIFIER =
/^[A-Za-z_][A-Za-z_0-9]+\??$/
Class Method Summary collapse
-
.factory(konst) ⇒ Object
create a factory function in appropriate module for the specified class.
-
.included(other) ⇒ Object
inherit the factory function capability.
Class Method Details
.factory(konst) ⇒ Object
create a factory function in appropriate module for the specified class
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 |
# File 'lib/doodle.rb', line 870 def factory(konst) name = konst.to_s names = name.split(/::/) name = names.pop if names.empty? # top level class - should be available to all klass = Object method_defined = begin method(name) true rescue Object false end if name =~ Factory::RX_IDENTIFIER && !method_defined && !klass.respond_to?(name) && !eval("respond_to?(:#{name})", TOPLEVEL_BINDING) eval("def #{ name }(*args, &block); ::#{name}.new(*args, &block); end", ::TOPLEVEL_BINDING, __FILE__, __LINE__) end else klass = names.inject(self) {|c, n| c.const_get(n)} # todo[check how many times this is being called] if name =~ Factory::RX_IDENTIFIER && !klass.respond_to?(name) klass.module_eval("def self.#{name}(*args, &block); #{name}.new(*args, &block); end", __FILE__, __LINE__) end end end |
.included(other) ⇒ Object
inherit the factory function capability
897 898 899 900 901 |
# File 'lib/doodle.rb', line 897 def included(other) super # make +factory+ method available factory other end |