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.



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

def initialize
  @__attributes = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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



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

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.



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

def __attributes
  @__attributes
end

Class Method Details

.run { ... } ⇒ Recipe

Builds a Recipe from a DSL block

Yields:

  • to the block containing the DSL

Returns:



16
17
18
19
20
# File 'lib/value_semantics/dsl.rb', line 16

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

Instance Method Details

#AnythingObject



36
37
38
# File 'lib/value_semantics/dsl.rb', line 36

def Anything
  Anything
end

#ArrayCoercer(element_coercer) ⇒ Object



59
60
61
# File 'lib/value_semantics/dsl.rb', line 59

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

#ArrayOf(element_validator) ⇒ Object



40
41
42
# File 'lib/value_semantics/dsl.rb', line 40

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

#BoolObject



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

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"
}


88
89
90
91
# File 'lib/value_semantics/dsl.rb', line 88

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

#Either(*subvalidators) ⇒ Object



32
33
34
# File 'lib/value_semantics/dsl.rb', line 32

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

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



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

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

#HashOf(key_validator_to_value_validator) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'lib/value_semantics/dsl.rb', line 44

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



55
56
57
# File 'lib/value_semantics/dsl.rb', line 55

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

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

Returns:

  • (Boolean)


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

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