The Perl Advent Calendar needs more articles for 2022. Submit your idea today!


Mock::Data::Set - Generator which returns one item from a set


  $generator= Mock::Data::Set->new(items => [ 1, 2, 3, 4 ]);
  $value= $generator->generate($mock);   # 25% chance of each of the items
  $generator= Mock::Data::Set->new(items => [ 1, 2 ], weights => [ 1, 9 ]);
  $value= $generator->generate($mock);   # 10% chance of '1', 90% chance of '2'

  use Mock::Data::Util qw( weighted_set uniform_set coerce_generator );
  $generator= uniform_set(1, 2, 3, 4);  # same as above
  $generator= weighted_set( 1 => 1, 2 => 9 ); # same as above
  $generator= coerce_generator([ 1, 2, 3, 4 ]);
  $generator= coerce_generator({ 1 => 1, 2 => 9 });
  # coerce_generator is recursive, Set constructor is not
  uniform_set([1, [2, 3]])->generate;       # 50% chance of returning arrayref [2,3]
  uniform_set("{a}")->generate;             # 100% chance of returning string '{a}'
  coerce_generator([1, [2, 3]])->generate;  # 25% chance of returning 2
  coerce_generator(["{a}"])->generate;      # 100% chance of calling generator named 'a'


This object selects a random element from a list. All items are equal probability unless weights are specified to change the probability. The items of the list may be values or generator objects. Plain coderefs are also considered values, not generators. (If you want automatic coercion, see "coerce_generator" in Mock::Data::Util).



  $set= Mock::Data::Set->new(%attrs);

Takes a list or hashref of attributes and returns them as an object. If you pass an arrayref as the only parameter, it is assumed to be the "items" attribute.


  $set= Mock::Data::Set->new_weighted($item => $weight, ...);

Construct a Set from a list of pairs of ($item, $weight). This constructor takes a list, not a hashref or arrayref.



The arrayref of items which can be returned by this generator. Do not modify this array. If you need to change the list of items, assign a new array to this attribute.


An optional arrayref of values, one value per element of items. The weight values are on an arbitrary scale chosen by the user, such that the sum of them is considered to be 100%.



  $val= $set->generate($mock, \%params);
  $val= $set->generate;

Return one random item from the set. This should normally be called with the reference to a Mock::Data instance and optional named parameters, but this module doesn't actually use them. (though a subclass or future version could)


  my $sub= $set->compile

Return a coderef that calls this generator.


  my $merged= $self->combine_generator($peer);

If the $peer is an instance of Mock::Data::Set, this will take the items and weights of the peer, combine with the items and weights of the current object, and create a new set.


Michael Conrad <>


version 0.03


This software is copyright (c) 2021 by Michael Conrad.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.