I've in one directory all my pictures (only gif and jpg). I would like to show on my starting page which is also perl generated a random picture from this directory. So everytime a user visits my page the picture should be randomly selected. The pictures have even similar names. e.g.

05d2.albumimage.jpg

940d.albumimage.jpg

12r3.albumimage.jpg

...

The pictures are in a database and the first four characters mean its ID number. Can anyone give me tips how I could do this?

If anyone's interested in knowing how this works, here is a simplified explanation:

grep { /\.(jpg|gif)$/i } glob "$_[0]*"

[url=http://www.perldoc.com/perl5.6.1/pod/func/grep.html]grep is an operator that uses an expression to search a list. The expression in this case is { /\.(jpg|gif)$/i } (files that end jpg and gif files only). This expression needs to know what directory to look in, and [url=http://www.perldoc.com/perl5.6.1/pod/func/glob.html]glob takes care of that by using the wildcard * to look at all files that directory. The brackets around this entire expression create an anonymous array, which is passed to the [url=http://www.perldoc.com/perl5.6.1/pod/func/map.html]map line because map also works on a list.

map { $_->[ rand @$_ ] }

So this line is now working on the results of the grep line (an anonymous array). All it's doing is selecting and returning a random element in the anonymous array.

First of all, an anonymous array holding some color strings is created. The anonymous array constructor [ .. ] returns a reference to the newly created array. So this reference is the only item in the list that gets passed to map.

But why would you use map if you list would always consist of only one item? Because you can access that item with the $_ variable. Since the array reference isn't explicitly stored in another variable, this is the only way to access the anonymous array twice.

We need to access the anonymous array twice because we need its size for the rand function and we need to dereference a random element. To get the size of the anonymous array, we explicitly convert the array reference $_ into an array by prefixing the reference with an @. Since rand forces scalar context on its argument, @$_ will return the size of the anonymous array referenced by $_. The rand function will now return a random index into the array. Using the array dereference operator -> on the anonymous array reference $_ again, we can dereference that random item and return it. The random item will be the return value of the map function.

You could write the above more readable (but less golfy) as:

Code

$ref = ['red', 'green', 'blue', 'yellow']; $ref->[rand @$ref];

or even without an anonymous array:

Code

@ary = ('red', 'green', 'blue', 'yellow'); $ary[rand @ary];

Hope this makes things a little clearer.

-- mhx At last with an effort he spoke, and wondered to hear his own words, as if some other will was using his small voice. "I will take the Ring," he said, "though I do not know the way."