I've been finding more and more uses for Hash::AsObject recently, it's great when you need an object, but you don't really care what that object is. For example today I had to write some reporting code, and call some existing code that expected a "cart" object to be passed in. It did something like:
foreach my $item ($cart->contents) {
printf "%d of %s for \$%.2f\n",
$item->qty, $item->code, $item->unit_price;
}
The problem was that I didn't have a "cart" to pass it. One of the great things about dynamic languages is that it doesn't matter if it's a "cart" or not, just that it looks like a cart:
my @cart = map {
$_->{unit_price} = defined $_->{sale_price}
? $_->{sale_price} : $_->{price};
Hash::AsObject->new($_)
} @{ $dbh->selectall_arrayref(
'SELECT qty, code, price, sale_price FROM cart',
{ Slice => {} }
)};
my $cart = Class::Object->new;
$cart->sub('contents', sub { return @cart });
Class::Object is useful in this case to get around the issue of not being able to return a list.