package Thread::Rand;
# start the Thread::Tie thread now if not already started (as clean as possible)
use Thread::Tie ();
# initializations
$VERSION= '0.07';
# be as strict as possble
use strict;
# modules that we need
use load;
# Make sure we have something tied to the thread
tie my $RAND, 'Thread::Tie', { module => 'Thread::Rand::Thread' };
# satisfy -require-
1;
#-------------------------------------------------------------------------------
#
# Exportable Subroutines
#
#-------------------------------------------------------------------------------
# IN: 1 range for random value (default: 0..1)
# OUT: 1 random value
sub rand {
my $rand= $RAND;
return defined( $_[0] )
? $rand * ( shift || 1 )
: $rand;
} #rand
#-------------------------------------------------------------------------------
# IN: 1 new value for seed
sub srand { $RAND= shift } #srand
#-------------------------------------------------------------------------------
# The following subroutines are loaded on demand only
__END__
#-------------------------------------------------------------------------------
#
# Class Methods
#
#-------------------------------------------------------------------------------
# global
#
# hijack rand/srand
sub global {
no strict 'refs';
*CORE::GLOBAL::rand= \&rand;
*CORE::GLOBAL::srand= \&srand;
} #global
#-------------------------------------------------------------------------------
#
# standard Perl features
#
#-------------------------------------------------------------------------------
# IN: 1 class (ignored)
# 2 .. N subs to import
sub import {
shift;
# set namespace and subs
my $namespace= caller().'::';
@_= qw( rand seed ) if !@_;
# export the subs
no strict 'refs';
*{$namespace.$_}= \&$_ foreach @_;
return;
} #import
#---------------------------------------------------------------------------
__END__
=head1 NAME
Thread::Rand - repeatable random sequences between threads
=head1 VERSION
This documentation describes version 0.07.
=head1 SYNOPSIS
use Thread::Rand; # exports rand() and srand()
use Thread::Rand (); # must call fully qualified subs
BEGIN { Thread::Rand->global } # replace rand() and srand() globally
=head1 DESCRIPTION
*** A note of CAUTION ***
This module only functions on Perl versions 5.8.0 and later.
And then only when threads are enabled with -Dusethreads. It
is of no use with any version of Perl before 5.8.0 or without
threads enabled.
*************************
The Thread::Rand module allows you to create repeatable random sequences
between different threads. Without it, repeatable random sequences can
only be created B<within> a thread.
=head1 SUBROUTINES
There are only two subroutines.
=head2 rand
my $value = rand(); # a value between 0 and 1
my $value = rand(number); # a value between 0 and number-1 inclusive
The "rand" subroutine functions exactly the same as the normal rand() function.
=head2 srand
srand( usethis );
The "srand" subroutine functions exactly the same as the normal srand()
function.
=head1 CLASS METHODS
There is one class method.
=head2 global
use Thread::Rand ();
BEGIN { Thread::Rand->global }
The "global" class method allows you to replace the rand() and srand() system
functions in all programs by the version supplied by Thread::Rand. To ensure
that the right subroutines are called, you B<must> call this class method from
within a BEGIN {} block.
=head1 REQUIRED MODULES
load (any)
Thread::Tie (0.09)
=head1 CAVEATS
A bug in Perl 5.8.0 causes random sequences to be identical in threads if the
rand() function was called in the parent thread. You can circumvent this
problem by adding a CLONE subroutine thus:
sub CLONE { srand() } # needed for bug in 5.8.0
This will make sure that each thread gets its own unique seed and therefore
its own unique sequence of random numbers. Alternately, you could also solve
this with Thread::Rand and a call to the L<global> class method thus:
use Thread::Rand ();
BEGIN { Thread::Rand->global }
You should however keep monitoring whether future versions of Perl will have
this problem fixed. You can then take these circumventions out again.
=head1 AUTHOR
Elizabeth Mattijsen, <liz@dijkmat.nl>.
Please report bugs to <perlbugs@dijkmat.nl>.
=head1 COPYRIGHT
Copyright (c) 2002, 2003, 2012 Elizabeth Mattijsen <liz@dijkmat.nl>. All rights
reserved. This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=head1 SEE ALSO
L<Thread::Tie>.
=cut