APLawrence.com -  Resources for Unix and Linux Systems, Bloggers and the self-employed

Random subroutines in Perl


© November 2007 Anthony Lawrence

I'll bet your first question might be "why on earth would I ever want to call subroutines randomly?". Admittedly, it isn't a need that comes up that often, but (for example) it's used right here on this very page that you are reading.

Ayup, you guessed it, it's ads again. I know, I know: you hate the ads, but they pay the bills, and actually every now and then there's something that actually might be of interest, so there it is and there they are. If you need to see the page without ads, disabling Javascript will get rid of a lot of them, and clicking on the "Printer Friendly" link will absolutely remove them all.

OK, now that you've accepted the inevitable, let's look at things from the publisher's point of view. We have various ads to run, and places to run them. What runs where? Well, duh, you put the best performing ads first. OK, then what? Second best? Sure, but what happens when you don't know what works best? Like right about to the left of this paragraph, what works best there?

Or maybe I just want them random to help combat that awful "ad blindness" that comes from people seeing the the same thing in the same place and therefore not really seeing it at all. Maybe mixing things up will help.

Whatever the reason, I have a choice of three or four ads I could stick over there, but I'm not sure which I want first. Maybe I want random Perl subroutines?

Why subroutines rather than just variables containing the text of the various ads? Well, you could do it that way, but subroutines seem cleaner to me. It comes down to doing something like this:

# define a subroutine 
$rads[0] = sub {
  print "This is the zeroth sub\n";
  print "Testvar is set\n" if $testvar;
  }
 

Or this:

$temp="This is the zeroth sub\n";
$temp .= "Testvar is set\n" if $testvar;
$rads[0]=$temp;
 

I think the first form (an anonymous subroutine) is neater and less confusing to modify. So let's use that. This example defines a few anonymous subroutines and then runs through them randomly::

#!/usr/bin/perl
#
# define some subroutines
#
$s[0]=sub {
   print "s1\n";
};

$s[1]=sub {
   print "s2\n";
};

$s[2]=sub {
   print "s3\n";
};

$s[3]=sub {
   print "s4\n";
};

#
# mix the order up randomly
#

shuffle(\@s);

#
# how many did we define?
#

$x=scalar(@s);

# 
# run through the subs
#

while ($x--) {
   $s[$x]->();
}

#
# randomly shuffle an array
#

sub shuffle {
my $array=shift;
return 0 if scalar @array < 2;
my $i;
for ($i = @$array; --$i; ) {
   my $j= int rand ($i+1);
   next if $i == $j;
   @$array[$i,$j]= @$array[$j,$i];
}
}
 

The "shuffle" subroutine was cribbed from Perl Cookbook; I'm far too lazy to cobble that up myself.

Easy enough, isn't it? At the time I am writing this, I am using something very much like this to produce the ads in the left column of this page. However, it's always possible that you are reading this years later, so I may be doing something completely different - I might not even have a left column! But you get the idea, right?

You don't have to use anonymous arrays - if you have existing subroutines you can take references to those. Here's how I might choose between two existing ad subroutines:

push @adsub, \&googleadmidpage;
push @adsub, \&yahooadmidpage;
&{$adsub[int(rand(2))]}();
 

I know: the brackets, the &'s, it's awful.. but that's the way it works.


Got something to add? Send me email.





(OLDER)    <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

->
-> Random subroutines in Perl

2 comments


Inexpensive and informative Apple related e-books:

Are Your Bits Flipped?

Take Control of Pages

Digital Sharing Crash Course

Photos: A Take Control Crash Course

Take Control of IOS 11




More Articles by © Anthony Lawrence






Sat Nov 17 20:51:09 2007: 3260   DarrenMeyer


That shuffle() is acceptable, I suppose, but Math::Random::MT::Auto has a shuffle() that uses the Mersenne (sp?) Twister PRNG. I've used it in several applications requiring closer-to-really-random shuffling -- like card game simulators.



Sat Nov 17 21:08:10 2007: 3261   TonyLawrence

gravatar
Thanks, that's good to know - though for this, with only a small number of items to sort, nothing is going to be very unpredictable.



------------------------


Printer Friendly Version

Have you tried Searching this site?

This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.

Contact us


Printer Friendly Version





The man who receives five thousand dollars a year wants six thousand dollars a year, and the man who owns eight or nine hundred thousand dollars will want a hundred thousand dollars more to make it a million, while the man who has his millions will want everything he can lay his hands on and then raise his voice against the poor devil who wants ten cents more a day. (Samuel Gompers)




Linux posts

Troubleshooting posts


This post tagged:

Code

Perl

Programming

Web/HTML



Unix/Linux Consultants

Skills Tests

Unix/Linux Book Reviews

My Unix/Linux Troubleshooting Book

This site runs on Linode