Date: Sun, 1 Jul 2001 02:02:49 -0500 From: "Rich" Subject: Re: inline average Message-Id: "David Frauzel" wrote in message news:9hm1cs$2h15$1@news.aros.net... > This is perhaps esoteric, but I'm curious. > > Let's say I have the hash: > > %values = ( > "red" => 5.0, > "orange" => 4.0, > "yellow" => 5.5, > ... > ) > > I'd like to have a final element in the hash, "average", which always points > to the average of all of the other elements - something like an inline > function. I'm thinking it would look like this: > > $values{"average"} = { > my $total = 0; > foreach $color (@spectrum) { > $total += $values{$color}; > } > $total = $total / ($#spectrum + 1); > return $total; > } > > (The above is obviously not real perl, it's just for the sake of > illustration.) You were on the right track. You want to use an anonymous subroutine. #!/usr/bin/perl -w use strict; my %values = ( red => 5.0, orange => 4.0, yellow => 5.5, average => "", ); $values{average} = &{sub { my $total = 0; my $colors = 0; #number of valid color values to average foreach my $color (keys %values) { if ($color ne "average" && # Don't use value of $values{$color} unless it's a number $values{$color} =~ /^-?(?:(?:\d+\.?\d*)|(?:\d*\.\d+))$/) { $total += $values{$color}; $colors++; } } return sprintf("%.2f", $total /= $colors); }}; print "The average is $values{average}"; __END__ sub { ..code..} produces a reference. Wrapping it in &{ } de-references the value before assigning it to $values{average} I didn't spend a lot of time on the example, you can adjust it to suit your needs. If you are certain that all colors will have a valid numeric value, you could eliminate the check. Keep checking back, I'm certain their will be many posts to follow that will provide micro-efficiency corrections as well as many different ways to get the same results. Rich