Perl Advent Calendar 2010-12-19++

So, umm, I told Santa what I wanted and he was totally, like, whatever…

by Adam Russell & Jerrad Pierce

The elves in Santa's shop are a fun-loving but superstitious folk, and pranced about with glee when they discovered that today's entry aligned with another Perl Advent Calendar. Whatever allows us to use some of Perl 6's "whatever-star" magic in P5. What does this give us? How does it work? use Whatever; to access "whatever-terms" &*,$*1, &@ , and &_; as punctuation variables these are magically global. All four behave in the same way: you get back a coderef which will later perform the actions defined by the statement they are used in when a value is passed for it to act upon. In computer sciencey words you could say that the whole expression is returned as a closure, resulting in a curried2 function.

The differences between the four spellings of whatever alter what it stands in for:

Let's delight the easily-amused3 with some small tricks…

mod19.pl

   1 # Whatever does this code do?
   2 # Adam Russell ac.russell@live.com
   3 use Whatever; 
   4 
   5 $add_2 = 2 + $*; # A typical example of currying   
   6 print "\$* \$add_2->(5)=",$add_2->(5),"\n";
   7 
   8 $add_2 = 2 + &*; # Same example with &*   
   9 print "&* \$add_2->(5)=",$add_2->(5),"\n";
  10 
  11 #Can be used with map()
  12 @test_data=(0,1,2,3,4,5,6,7,8,9);
  13 @test_data_plus_2=map ($add_2->($_), @test_data);
  14 $with_2_added=join ',',@test_data_plus_2;
  15 print "test_data_array_plus_2 $with_2_added\n";
  16 
  17 # A more complex example. Uses multiple whatever-star terms
  18 @test_data=(0,1,2,3,4,5,6,7,8,9);
  19 $sum=&*;
  20 foreach (0..($#test_data-1)){
  21     $sum=$sum + &*;
  22 }
  23 $a=$sum->(@test_data);
  24 print "sum ","$a\n";
  25 
  26 # star terms bind lazily. This allows us to change a variable between calls
  27 $mod=0;
  28 my $filter=(($* % 2) == $mod);
  29 # filter evens
  30 @evens = grep($filter->($_),@test_data);  
  31 print "evens ",join(' ',@evens),"\n";
  32 # filter odds
  33 $mod=1;
  34 @odds=grep($filter->($_),@test_data); 
  35 print "odds  ",join(' ',@odds),"\n";
  36 
  37 # Finally, whatever-stars can be used to dereference a hash or array
  38 %test_hash=(0,=>"zero", 1=>"one", 2=>"two");
  39 $val_2=$*->{2};
  40 $val=$val_2->(\%test_hash);
  41 print "val  ",$val,"\n";

1. Prior to its deprecation in 5.10, $* enabled multi-line matching.

2. Additional details on currying.

3. You try not to be amused by the littlest thing after spending 12 hours gluing heads on nutcrackers.

View Source (POD)