Hash::AsObject

gav on 2004-12-08T19:36:23

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.