Class: ValueSemantics::DSL

Inherits:
Object
  • Object
show all
Defined in:
lib/value_semantics/dsl.rb

Overview

Builds a Recipe via DSL methods

DSL blocks are instance_evald against an object of this class.

Constant Summary collapse

IDENTITY_COERCER =
:itself.to_proc

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDSL

Returns a new instance of DSL.



30
31
32
# File 'lib/value_semantics/dsl.rb', line 30

def initialize
  @__attributes = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, **kwargs) ⇒ Object



99
100
101
102
103
104
105
# File 'lib/value_semantics/dsl.rb', line 99

def method_missing(name, *args, **kwargs)
  if respond_to_missing?(name)
    def_attr(name, *args, **kwargs)
  else
    super
  end
end

Instance Attribute Details

#__attributesObject (readonly)

Returns the value of attribute __attributes.



28
29
30
# File 'lib/value_semantics/dsl.rb', line 28

def __attributes
  @__attributes
end

Class Method Details

.run { ... } ⇒ Recipe

Builds a Recipe from a DSL block

Yields:

  • to the block containing the DSL

Returns:



22
23
24
25
26
# File 'lib/value_semantics/dsl.rb', line 22

def self.run(&block)
  dsl = new
  dsl.instance_eval(&block)
  Recipe.new(attributes: dsl.__attributes.freeze)
end

Instance Method Details

#AnythingObject



42
43
44
# File 'lib/value_semantics/dsl.rb', line 42

def Anything
  Anything
end

#ArrayCoercer(element_coercer) ⇒ Object



65
66
67
# File 'lib/value_semantics/dsl.rb', line 65

def ArrayCoercer(element_coercer)
  ArrayCoercer.new(element_coercer)
end

#ArrayOf(element_validator) ⇒ Object



46
47
48
# File 'lib/value_semantics/dsl.rb', line 46

def ArrayOf(element_validator)
  ArrayOf.new(element_validator)
end

#BoolObject



34
35
36
# File 'lib/value_semantics/dsl.rb', line 34

def Bool
  Bool
end

#def_attr(*args, **kwargs) ⇒ Object

Defines one attribute.

This is the method that gets called under the hood, when defining attributes the typical #method_missing way.

You can use this method directly if your attribute name results in invalid Ruby syntax. For example, if you want an attribute named then, you can do:

include ValueSemantics.for_attributes {
  # Does not work:
  then String, default: "whatever"
  #=> SyntaxError: syntax error, unexpected `then'

  # Works:
  def_attr :then, String, default: "whatever"
}


94
95
96
97
# File 'lib/value_semantics/dsl.rb', line 94

def def_attr(*args, **kwargs)
  __attributes << Attribute.define(*args, **kwargs)
  nil
end

#Either(*subvalidators) ⇒ Object



38
39
40
# File 'lib/value_semantics/dsl.rb', line 38

def Either(*subvalidators)
  Either.new(subvalidators)
end

#HashCoercer(keys: IDENTITY_COERCER, values: IDENTITY_COERCER) ⇒ Object



70
71
72
# File 'lib/value_semantics/dsl.rb', line 70

def HashCoercer(keys: IDENTITY_COERCER, values: IDENTITY_COERCER)
  HashCoercer.new(key_coercer: keys, value_coercer: values)
end

#HashOf(key_validator_to_value_validator) ⇒ Object



50
51
52
53
54
55
56
57
58
59
# File 'lib/value_semantics/dsl.rb', line 50

def HashOf(key_validator_to_value_validator)
  unless key_validator_to_value_validator.size.equal?(1)
    raise ArgumentError, "HashOf() takes a hash with one key and one value"
  end

  HashOf.new(
    key_validator_to_value_validator.keys.first,
    key_validator_to_value_validator.values.first,
  )
end

#RangeOf(subvalidator) ⇒ Object



61
62
63
# File 'lib/value_semantics/dsl.rb', line 61

def RangeOf(subvalidator)
  RangeOf.new(subvalidator)
end

#respond_to_missing?(method_name, _include_private = nil) ⇒ Boolean

Returns:

  • (Boolean)


107
108
109
110
# File 'lib/value_semantics/dsl.rb', line 107

def respond_to_missing?(method_name, _include_private=nil)
  first_letter = method_name.to_s.each_char.first
  first_letter.eql?(first_letter.downcase)
end