Phoenix.pm: Please help, my brain is fried

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:
> 
> << sub create_login_id {
>      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



More information about the Phoenix-pm mailing list