Class: Engineering::Builder::Model
- Inherits:
-
Object
- Object
- Engineering::Builder::Model
- Includes:
- Model::DSL
- Defined in:
- lib/builder/model.rb
Overview
Build a Model subclass
Class Method Summary collapse
-
.build(&block) ⇒ Object
Convenience method for creating a new builder and evaluating a block.
Instance Method Summary collapse
-
#build(super_class = ::Model, &block) ⇒ Object
Evaluate a block and return a new Model subclass Use the trick found here www.dan-manges.com/blog/ruby-dsls-instance-eval-with-delegation to allow the DSL block to call methods in the enclosing lexical scope.
-
#initialize ⇒ Model
constructor
A new instance of Model.
-
#method_missing(method, *args, &block) ⇒ Object
The second half of the instance_eval delegation trick mentioned at www.dan-manges.com/blog/ruby-dsls-instance-eval-with-delegation.
Methods included from Model::DSL
#attr_accessor, #attr_reader, #attr_writer
Constructor Details
#initialize ⇒ Model
Returns a new instance of Model.
16 17 18 |
# File 'lib/builder/model.rb', line 16 def initialize @attribute_defaults = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
The second half of the instance_eval delegation trick mentioned at
http://www.dan-manges.com/blog/ruby-dsls-instance-eval-with-delegation
55 56 57 58 59 60 61 |
# File 'lib/builder/model.rb', line 55 def method_missing(method, *args, &block) if @klass.respond_to? method @klass.send method, *args, &block else @self_before_instance_eval.send method, *args, &block end end |
Class Method Details
.build(&block) ⇒ Object
Convenience method for creating a new builder and evaluating a block
12 13 14 |
# File 'lib/builder/model.rb', line 12 def self.build(&block) self.new.build(&block) end |
Instance Method Details
#build(super_class = ::Model, &block) ⇒ Object
Evaluate a block and return a new Engineering::Builder::Model subclass
Use the trick found here http://www.dan-manges.com/blog/ruby-dsls-instance-eval-with-delegation
to allow the DSL block to call methods in the enclosing *lexical* scope
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/builder/model.rb', line 23 def build(super_class=::Model, &block) @klass = Class.new(super_class) if block_given? @self_before_instance_eval = block.binding.eval('self') self.instance_eval(&block) # Instance variable values for read-only attributes need special handling = @attribute_defaults.select {|k,v| @klass.respond_to? k.to_s + '=' } # Find the ones that can be set normally instance_variable_defaults = @attribute_defaults.reject {|k,v| @klass.respond_to? k.to_s + '=' } # These must be set directly @klass.send :define_method, :initialize do |*args, &block| # Directly set the read-only instance variables instance_variable_defaults.each {|k,v| instance_variable_set('@' + k.to_s, v) } # Handle the others normally, while evaluating any blocks super(*(.map {|k,v| { k => (v.respond_to?(:call) ? v.call : v) } }), *args, &block) # Push the default geometry self.class.instance_variable_get(:@elements).each do |a| if a.is_a? Array push a.first.new(*a.last) else push a end end end end @klass end |