The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Randomize - Perl extension for randomizing things.

SYNOPSIS

  use Randomize;
  my $randomizer = Randomize->new(\@rules);
  print "There are ", $randomizer->permutations(),
        " different possible outcomes.\n";
  while (1) {
    my $random_hash = $randomizer->generate();
  }

DESCRIPTION

This packages takes a set of randomization rules in the form of an array reference, and creates random hashes on request based on the rules given.

I know that doesn't make sense, so here's an example.

  my @randomizer_rules =
    [ {Field  => 'Street',
       Values => [{Data   => ['Preston', 'Hillcrest'],
                   Weight => 1},
                  {Data   => ['Coit'],
                   Weight => 2}]},
      {Field  => 'Number', 
       Values => [18100..18299]}
    };

  my $randomizer = Randomize->new(\@randomizer_rules);
  while (1)
    my $hashref = $randomizer->generate();
  }

The key is @randomizer_rules. What this list tells Randomizer is that, every time you invoke the generate() method, you want to get back a reference to a hash that looks like:

  $hashref = { Street => 'Preston', 
               Number => 18111 };

where the Number is between 18100 and 18299 and the Street is either Preston, Hillcrest, or Coit. Further, you want the numbers to be evenly distributed, but you want the street to be Coit half the time, and evenly distributed between Preston and Hillcrest the rest of the time.

So, if you called $randomizer->generate() 1000 times, you'd get roughly 500 addresses on Coit and 250 addresses each on Preston and Hillcrest.

Let's look at a more complicated @randomizer_rules now.

  my @randomizer_rules =
    ( {Field  => 'Street',
       Values => [{Data   => ['Preston', 'Hillcrest'],
                   Weight => 1},
                  {Data   => ['Coit'],
                   Weight => 2}]},
      {Field  => 'Number', 
       Values => [{Precondition => "<<Street>> eq 'Preston'",
                   Alternatives => [{Data => [18100..18199],
                                     Weight => 1},
                                    {Data => [18200..18299],
                                     Weight => 9}]},
                  {Precondition    => 'DEFAULT',
                   Alternatives => [{Data => [18100..18299],
                                     Weight => 1}]}]}
    );

Given this, the generate() method will still return a hash reference in the form

  $hashref = { Street => 'Preston', 
               Number => 18111 };

with the same streets and address ranges. However, if the street picked happens to be Preston, 90% of the addresses generated will be in the range 18200 to 18299.

In final example, note the Retry_If clause:

  my @randomizer_rules =
    ( {Field  => 'Street',
       Values => [{Data   => ['Preston', 'Hillcrest'],
                   Weight => 1},
                  {Data   => ['Coit'],
                   Weight => 2}]},
      {Field  => 'Number', 
       Values => [{Precondition => "<<Street>> eq 'Preston'",
                   Alternatives => [{Data => [18100..18199],
                                     Weight => 1},
                                    {Data => [18200..18299],
                                     Weight => 9}],
                   Retry_If     => ['defined $main::addr1 && <<Number>> == $main::addr1->{Number}']},
                  {Precondition    => 'DEFAULT',
                   Alternatives => [{Data => [18100..18299],
                                     Weight => 1}]}]}
    );

  my $randomizer = Randomize->new(\@randomizer_rules);
  while (1)
    $main::addr1 = $main::addr2 = undef;
    $main::addr1 = $randomizer->generate();
    $main::addr2 = $randomizer->generate();
  }

In this example, we're generating pairs of addresses. The Retry_If clause ensures that we never get a pair of identical addresses on Preston. It's still possible to get identical addresses on Coit or Hillcrest, however.

Retry_If clauses may also appear at the same level as Field and Values, like so:

  my @randomizer_rules =
    ( {Field  => 'Street',
       Values => ['Preston', 'Hillcrest', 'Coit']},
      {Field  => 'Number', 
       Values => [18100..18299],
       Retry_If => ['<<Street>> eq 'Coit' && <<Number>> eq 18200']}
    );

This ruleset tells Randomize to try again if the address generated is 18200 Coit.

There is also one special rule that Randomize looks for: "DEBUG". A "DEBUG ON" rule turns debugging messages on so you can see what's happening when you call generate(). It also attempts to print the code it generates to a file. You can optionally pass the filename in, like "DEBUG ON myfile.code", or if you don't specify a file, the default output file is "Randomize.code". If the file can't be opened for writing, a warning is sent to standard error, but execution of your program is otherwise unaffected.

Correspondingly, a "DEBUG OFF" rule turns debugging off, although the code is still printed. Placement of "DEBUG ON" and "DEBUG OFF" statements determines which fields debugging information is printed for. For example, take a look at the following ruleset:

  my @randomizer_rules =
    ( 'DEBUG ON',
      {Field  => 'Street',
       Values => ['Preston', 'Hillcrest', 'Coit']},
      'DEBUG OFF',
      {Field  => 'Number', 
       Values => [18100..18299],
       Retry_If => ['<<Street>> eq 'Coit' && <<Number>> eq 18200']},
    );

This ruleset results in debugging information being printed for generation of the "Street" field, but not for the "Number" field, and code will be printed to the file "Randomize.code".

NOTE: Randomize cannot currently generate anything other than simple hashes. If you want a complex data structure, you'll have to either build it yourself by moving items around in the returned hash, or by using multiple randomize objects.

EXPORT

None.

AUTHOR

Brand Hilton

PUBLIC METHODS

new

Description

This is the constructor for Randomize objects. It takes one parameter: a reference to an array containing randomizer rules. From these rules, the generate() and permutations() methods are created. If an error is detected in the rules, the package variable $Randomize::errmsg will contain the error message and new() will return undef.

Syntax

  $randomizer = Randomize->new(\@rules);

    $randomizer  - On success, a Randomize object.  On failure, undef
                   is returned and $Randomize::errmsg will contain a
                   descriptive error message.

    \@rules      - A reference to an array containing Randomize rules, 
                   as described in the DESCRIPTION section.

generate

Description

This method returns a reference to a hash. The hash contains the fields you specified in your randomizer rules. Each call to generate() gives you a new hash, with a new set of randomized values.

NOTE: If you wish to specify a value for one or more fields of the hash, you can pass in the field and its value.

Syntax

  $hashref = $randomizer->generate( [ $fieldname, $value, ... ] );

    $hashref    - A hash reference returned by generate().

    $randomizer - A Randomize object.

    $fieldname  - The name of a field in the hash.

    $value      - The value you wish that field to take 
                  this time through.

permutations

Description

This method returns the number of permutations of the hash you've specified.

NOTE: If you wish to specify a value for one or more fields of the hash, you can pass in the field and its value.

Syntax

  $permutations = $randomizer->permutations( [ $fieldname, $value, ... ] );

    $permutations - The exact number of permutations of the
                    hash you've specified.

    $randomizer   - A Randomize object.

    $fieldname    - The name of a field in the hash.
                 
    $value        - The value you wish that field to take 
                    this time through.

generate_all

Description

This method returns a list containing every permutation of the hash you've specified.

NOTE: If you wish to specify a value for one or more fields of the hash, you can pass in the field and its value.

Syntax

  @permutations = $randomizer->generate_all( [ $fieldname, $value, ... ] );

    @permutations - A list containing every possible permutation
                    of the hash you've specified.

    $randomizer   - A Randomize object.

    $fieldname    - The name of a field in the hash.
                 
    $value        - The value you wish that field to take 
                    this time through.