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










/Web/random_functions.html Comment posting

Comments by new and anonymous visitors are moderated and must be approved before they will appear on the site. We apologize for the necessity of this procedure.

Your name: (or leave as anonymous)
Your Website (optional): 
Your Email :

(optional - use if you want to be notified of new comments, will not be displayed )

We have strong spam controls here: preview your post to be sure it will be let through.
Comments over 6K in length cannot be posted. Please send them to me in email.

For easy cut and paste, the article text and other comments are reproduced below.


Random subroutines in Perl


2007/11/15

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 therefor 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.



Comments