Module: Quick::Sampler::DSL::SimpleCombinators

Included in:
Quick::Sampler::DSL
Defined in:
lib/quick/sampler/dsl/simple_combinators.rb

Overview

DSL methods that allow to combine samplers in various ways.

Recursive samplers

Some of the combinators are recursive: given a nested structure of Arrays and Hashes containing samplers and non-sampler values they would produce an analogous structure where samplers are replaced by their #next value.

Instance Method Summary collapse

Instance Method Details

#combine(*samplers) {|samples| ... } ⇒ Quick::Sampler

Custom sampler combinator

combine allows to implement a custom combination of samplers: the method expects individual samplers as arguments and the combination implementation as a block. The resulting sampler will sample each of the supplied sub-samplers, pass the sampled values to the block and emit block result as combined sample.

Parameters:

Yield Parameters:

  • samples (*Anything)

    sampled values from each of the combined samplers

Yield Returns:

  • (Anything)

    combined sampled value

Returns:



146
147
148
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 146

def combine *samplers, &block
  list_like(*samplers).map(&block)
end

#hash_like(template) ⇒ Quick::Sampler<Hash>

Sampler of hashe's that in turn may contain Arrays, Hashes and Quick::Samplers.

Parameters:

  • pattern (Hash)

    a hash that will be used as a template for samples

Returns:



88
89
90
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 88

def hash_like template
  send_to list_like(template), :first
end

#list_like(*args) ⇒ Quick::Sampler

Sampler of arbitrary nested structures made up of Arrays, Hashes, Quick::Samplers and non-sampler values

Parameters:

  • args (Array)

    a template structure

Returns:



79
80
81
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 79

def list_like *args
  feed { args.map { |arg| recursive_sample(arg) } }
end

#list_of(sampler, size: 1..10) ⇒ Quick::Sampler

Sampler of uniform arrays

Parameters:

  • sampler (Quick::Sampler)

    a sampler to sample array elements from

  • size (Integer, Range, Quick::Sampler<Intger>) (defaults to: 1..10)

    value to use as, range to pick from or sampler to sample from the list size

Returns:

  • (Quick::Sampler)

    a sampler that produces arrays of values sampled from its argument



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 58

def list_of sampler, size: 1..10
  size = case size
         when Quick::Sampler
           size
         when Range
           pick_from(size)
         when Numeric
           const(size.to_i)
         else
           raise "Cant use #{size.inspect} as size"
         end
  feed { sampler.first(size.next) }
end

#merge(*samplers) ⇒ Quick::Sampler<Hash>

Sampler of merged hashes

Parameters:

  • *samplers (Hash, *Quick::Sampler<Hash>)

    Hashes or samplers emitting Hash values to merge

Returns:



156
157
158
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 156

def merge *samplers
  combine(*samplers) { |hashes| hashes.reduce(:merge) }
end

#object_like(the_class, *args) ⇒ Object

Arbitrary object sampler.

Parameters:

  • the_class (Class, Quick::Sampler<Class>)

    a class of the object to create (or a sampler producing classes)

  • *args (*Anything)

    arguments to pass to the constructor (may contain samplers)



126
127
128
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 126

def object_like the_class, *args
  send_to(the_class, :new, *args)
end

#one_of(*args) ⇒ Quick::Sampler

Returns a sampler that recursively samples on of the arguments at random.

Returns:

  • (Quick::Sampler)

    a sampler that recursively samples on of the arguments at random



25
26
27
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 25

def one_of *args
  feed { recursive_sample(args.sample) }
end

#one_of_weighted(expression_weights) ⇒ Quick::Sampler

Returns a sampler that recursively samples on of the expressions at random, with likelyhood of picking one of the expressions depends on its weight.

Returns:

  • (Quick::Sampler)

    a sampler that recursively samples on of the expressions at random, with likelyhood of picking one of the expressions depends on its weight.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 32

def one_of_weighted expression_weights
  total_weight, expressions = expression_weights
    .reduce([0, {}]) { |(total_weight, expressions), (expression, weight)|
      if weight > 0
        total_weight += weight
        [total_weight, expressions.merge(total_weight => expression)]
      else
        [total_weight, expressions]
      end
    }

  feed {
    dice = rand * total_weight
    weight_class = expressions.keys.find{|w| dice < w}
    recursive_sample(expressions[weight_class])
  }
end

#pick_from(source) ⇒ Quick::Sampler

Returns a sampler producing values from the range or array.

Returns:

  • (Quick::Sampler)

    a sampler producing values from the range or array



14
15
16
17
18
19
20
21
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 14

def pick_from source
  case source
  when Range
    feed { rand(source) }
  else
    feed { source.to_a.sample }
  end
end

#send_to(recipient, message, *args) ⇒ Quick::Sampler #send_to(sampler) ⇒ Quick::Sampler

Sampler of arbitrary message send ("method call") results

Overloads:

  • #send_to(recipient, message, *args) ⇒ Quick::Sampler

    Parameters:

    • recipient (Object, Quick::Sampler<Object>)

      message recipient or a sampler producing recipients

    • message (Symbol, Quick::Sampler<Symbol>)

      message to send or a sampler producing messages

    • args (Array)

      argument list that may contain samplers producing arguments

  • #send_to(sampler) ⇒ Quick::Sampler

    Parameters:

    • sampler (Quick::Sampler<[Object, Symbol, *Anything]>)

      a sampler producing the message send details

Returns:

  • (Quick::Sampler)

    a sampler of dynamically generated message send results



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 108

def send_to *args
  call_sampler = if args.count > 1
                   list_like *args
                 else
                   args.first
                 end
  feed {
    object, message, *args = call_sampler.next
    object.send( message, *args )
  }
end