Kevin Buettner kev at primenet.com
Thu Jan 27 13:18:47 CST 2000

```On Jan 27,  1:33pm, Beaves at aol.com wrote:

> In a message dated 1/26/00 7:57:43 PM US Mountain Standard Time,
> kev at primenet.com writes:
>
>      return join('', map \$_->[int(rand(52))],
>                 (['a'..'z','A'..'Z']) x int(rand(6)+6));
>  } >>
>
> Could you expand this code and put in a few comments about what it is doing.
> I like the conciseness, but I'm not exactly following what each section is
> doing...
> (the classic 'brevity versus understandability' dillemma)
>
> Thanks..

Okay.  Let's break it into pieces.  I'll start at the inside and
work outwards.

int(rand(6)+6)

This evaluates to an integer, chosen pseudo-randomly between
6 and 11 inclusive.

['a'..'z','A'..'Z']

This creates a list reference.  The list being referred to
contains the lower case letters and the uppercase letters.

The fact that it's a list reference is very important for
use with the map.  (It's important because a list reference
is a scalar and map needs to operate on a list of scalars,
not a list of lists.)

(['a'..'z','A'..'Z']) x int(rand(6)+6))

The 'x' is the repetition operator.  If you say something
like
"abc" x 3
this evaluates to the string "abcabcabc".

The repetition operator also works on lists.  By wrapping

['a'..'z','A'..'Z']

in parens, I created a list of one element.  (The one element
is the list reference that I talked about above).

So the complete expression,

(['a'..'z','A'..'Z']) x int(rand(6)+6))

will create a list of N hash references to a list containing
our upper/lowercase alphabetic scalars, where N is an integer
chosen pseudo-randomly between 6 and 11.

To make this more concrete, suppose that int(rand(6)+6)
evaluated to 6.  Then the expression under consideration
would evaluate to

( ['a','b','c','d',...,'z','A','B','C','D',...,'Z'],
['a','b','c','d',...,'z','A','B','C','D',...,'Z'],
['a','b','c','d',...,'z','A','B','C','D',...,'Z'],
['a','b','c','d',...,'z','A','B','C','D',...,'Z'],
['a','b','c','d',...,'z','A','B','C','D',...,'Z'],
['a','b','c','d',...,'z','A','B','C','D',...,'Z']  )

except that it would be represented much more efficiently
in that it would contain six copies of the same list reference.

map \$_->[int(rand(52))], (['a'..'z','A'..'Z']) x int(rand(6)+6)

We've just finished discussion on what the second argument
of the map is.  To recap, it'll be a list of list references.
Each list reference will refer to a list of length 52 containing
the upper and lower case letters.

The map will construct a new list out of the list in the second
argument (which is our list of list references).  It will do
this by considering each element in succesion and assign said
element to \$_.  It will then evaluate the first argument to
construct the list argument(s) corresponding to the argument
under consideration.  (If you've never seen map before, it
might be instructive to write a few example programs to test
it out for yourself.)

So... in the context of doing the map, \$_ will be set to one
of the list references and

\$_->[int(rand(52))]

will cause one of the 'a'..'z','A'..'Z' to be chosen.

When the map is done, it will have constructed a list containing
N elements where each element is one of our letters chosen at
random.

join('', map \$_->[int(rand(52))], (['a'..'z','A'..'Z']) x int(rand(6)+6))

This simply turns the list that map created into a scalar.  I.e,
it concatenates the random letters chosen by the above map into
a scalar suitable for returning from the function.

Kevin

--
Kevin Buettner
kev at primenet.com, kevinb at redhat.com

```