Class: Engineering::Builder::Sketch

Inherits:
Object
  • Object
show all
Includes:
Sketch::DSL
Defined in:
lib/builder/sketch.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSketch

Returns a new instance of Sketch.



13
14
15
# File 'lib/builder/sketch.rb', line 13

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


54
55
56
# File 'lib/builder/sketch.rb', line 54

def method_missing(method, *args, &block)
		@self_before_instance_eval.send method, *args, &block
end

Class Method Details

.build(&block) ⇒ Object

Convenience method for creating a new builder and evaluating a block



9
10
11
# File 'lib/builder/sketch.rb', line 9

def self.build(&block)
		self.new.build(&block)
end

Instance Method Details

#build(super_class = ::Sketch, &block) ⇒ Object

Evaluate a block and return a new 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


20
21
22
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
# File 'lib/builder/sketch.rb', line 20

def build(super_class=::Sketch, &block)
		@klass = Class.new(super_class)
		if block_given?
 @klass.singleton_class.send :attr_accessor, :elements
 @klass.instance_variable_set('@elements', [])

 @self_before_instance_eval = block.binding.eval('self')
 self.instance_eval(&block)

 # Instance variable values for read-only attributes need special handling
 setter_defaults = @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) }

			super(setter_defaults, *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