El módulo Test::LectroTest::Generator provee generadores para los tipos de datos mas comunes. Provee además un algebra de combinadores de generadores que permite la construcción de generadores complejos.
$ perl -wde 0 DB<1> use Test::LectroTest::Generator qw(:common Gen) DB<2> p 1<<31 2147483648 DB<3> $tg = Int(range=>[0, 2_147_483_647], sized=>0) DB<4> x $tg 0 Test::LectroTest::Generator=HASH(0x84faa78) 'generator' => CODE(0x84fa9a0) -> &Test::LectroTest::Generator::\ __ANON__[/usr/local/share/perl/5.8.7/Test/LectroTest/Generator.pm:212]\ in /usr/local/share/perl/5.8.7/Test/LectroTest/Generator.pm:210-212Una expresión como
Int(range=>[0, 2_147_483_647], sized=>0)
construye un generador
aleatorio de enteros.
Si el argumento sized fuera cierto (que es el valor por defecto) los enteros generados lo serían de acuerdo con una cierta 'política de tamaños'. El generador es un objeto que contiene un método generate . Aqui el argumento sized puesto a falso indica que los valores generados sólo están restringidos por el rango especificado.
DB<3> x $tg->generate 0 1760077938 DB<4> x scalar localtime $tg->generate 0 'Wed Jan 14 00:07:07 1998'
La subrutina Gen permite la construcción de nuevos generadores:
DB<7> $ctg = Gen { scalar localtime $tg->generate( @_ ) } DB<8> print $ctg->generate()."\n" for 1..3 Thu Aug 15 15:34:05 2019 Sat Sep 7 04:11:15 1974 Sun Jun 19 14:30:14 1977de esta forma hemos construido un generador aleatorio de fechas.
Existen múltiples generadores básicos y un conjunto de combinadores de generadores. Sigue un ejemplo que muestra la influencia del parámetro sizing guidance:
DB<1> use Test::LectroTest::Generator qw(:common :combinators) DB<2> $int_gen = Int DB<3> print $int_gen->generate($_)." " for 1..100 # El arg es sizing guidance 1 1 0 0 -2 3 -3 8 -6 6 6 6 -9 -10 2 1 -9 -11 4 12 19 -11 16 -1 -22 12 -13 -20 -12 9 \ -21 -9 21 -27 5 -19 -20 28 -18 -31 -14 2 -40 -10 33 32 1 33 6 21 3 5 45 31 -28 20 -17 \ -9 58 48 -58 2 -40 27 6 -20 -41 30 59 40 -49 -60 -38 44 -44 -63 12 -76 45 41 65 \ 63 -20 59 -5 62 0 65 63 34 71 32 59 -61 -7 -14 30 -71 -13 -58
Veamos algunos constructores de generadores básicos:
DB<4> $flt_gen = Float( range=>[0,1] ) DB<5> x $flt_gen->generate 0 0.793049252432869 DB<6> x $flt_gen->generate 0 0.543474544861482 DB<7> $bln_gen = Bool DB<8> x $bln_gen->generate 0 0 DB<9> x $bln_gen->generate 0 1 DB<10> x $bln_gen->generate 0 1 DB<11> $chr_gen = Char( charset=>"a-z" ) DB<12> x $chr_gen->generate 0 's' DB<13> x $chr_gen->generate 0 'u' DB<14> x $chr_gen->generate 0 'i' DB<15> $elm_gen = Elements("e1", "e2", "e3", "e4") DB<16> x $elm_gen->generate 0 'e2' DB<17> x $elm_gen->generate 0 'e4' DB<18> x $elm_gen->generate 0 'e2'
El combinador Frequency permite construir un generador a partir de una lista de generadores que produce los elementos con probabilidades proporcionales a las frecuencias asignadas:
DB<19> $english_dist_vowel_gen = Frequency([8.167,Unit("a")], [12.702,Unit("e")], \ [6.996,Unit("i")], [ 7.507,Unit("o")],[2.758,Unit("u")] ) DB<20> x $english_dist_vowel_gen->generate 0 'i' DB<21> x $english_dist_vowel_gen->generate 0 'e' DB<22> x $english_dist_vowel_gen->generate 0 'i' 0 'o'
Otro combinador es Paste :
DB<23> $digit_gen = Elements( 0..9 ) DB<24> $ssn_gen = Paste(Paste(($digit_gen)x3),Paste(($digit_gen)x2),Paste(($digit_gen)x4),glue => "-") DB<25> x $ssn_gen->generate 0 '168-19-1333' DB<26> x $ssn_gen->generate 0 '348-35-8320'
Veamos el generador String :
DB<27> $gen = String( length=>[3,5], charset=>"A-Z", size => 100 ) DB<28> x $gen->generate 0 'KBZNB' DB<29> x $gen->generate 0 'AAK' DB<30> x $gen->generate 0 'AZL'
Un ejemplo con List :
DB<31> $ary_gen = List( Int(sized=>0), length => 5 ) DB<32> x $ary_gen->generate 0 ARRAY(0x8563850) 0 19089 1 '-13489' 2 10390 3 5382 4 981 DB<33> x $ary_gen->generate 0 ARRAY(0x853f030) 0 17062 1 18558 2 29329 3 31931 4 2464
También podemos construir generadores de hashes:
DB<34> $gen = Hash( String( charset=>"A-Z", length=>3 ), Float( range=>[0.0, 100.0] ), length => 4) DB<35> x $gen->generate 0 HASH(0x8576a30) 'FSW' => 0.998256374071719 'KLR' => 0.0577333231717212 'PEV' => 0.834037952293134 'TNK' => 0.0146371360307889
El combinador OneOf aplica uno de varios generadores:
DB<36> $gen = OneOf( Unit(0), List(Int,length=>3) ) DB<37> x $gen->generate 0 ARRAY(0x856c454) 0 '-1' 1 0 2 0 DB<38> x $gen->generate 0 0
El combinador Each permite generar listas formados de aplicar cada uno de los generadores:
DB<39> $gen = Each( Char(charset => "aeiou"), Int( range=>[0,10], sized => 0 ) ) DB<40> x $gen->generate 0 ARRAY(0x857b770) 0 'o' 1 3 DB<41> x $gen->generate 0 ARRAY(0x85771bc) 0 'e' 1 5 DB<42> x $gen->generate 0 ARRAY(0x857b080) 0 'i' 1 3
El combinador Apply aplica el código dado al resultado producido opr los generadores especificados:
DB<42> $gen = Apply( sub { $_[0] x $_[1] }, Char( charset=>'a-z'), Unit(4) ) DB<43> x $gen->generate 0 'xxxx' DB<44> x $gen->generate 0 'hhhh' DB<45> x $gen->generate 0 'jjjj'
El siguiente ejemplo produce matrices 3x3:
DB<46> $loloi_gen = List( List( Int(sized=>0), length => 3 ), length => 3) DB<47> x $loloi_gen->generate 0 ARRAY(0x857bd1c) 0 ARRAY(0x8576a90) 0 9648 1 2796 2 9589 1 ARRAY(0x8576dcc) 0 '-29523' 1 '-21714' 2 31931 2 ARRAY(0x857658c) 0 '-9477' 1 '-2434' 2 '-3794'
[$Capacity, [$w_0, ..., $w_n], [$p_0, ..., $p_n]]
Casiano Rodríguez León