George_Sherston has asked for the wisdom of the Perl Monks concerning the following question:

Sibling monks, I humbly solicit your advice. I often find myself wanting to populate a hash, not with plain values, but with the results of calculations or functions. For example, a lot of the modules I'm using (Mail::Sendmail, HTML::Template) seem to accept data in hash format. But doing it directly, by placing the function inside the hash, doesn't seem to work. I've resorted to assigning the result of each calculation / function to its own scalar, and then putting the scalars into the hash. But this doesn't feel like the best solution - it's two steps where I only want one, and it uses memory unproductively.

Here's an example from what I'm working on now (I'm generating an email to a customer - the info for the email is pulled out of some db tables and put into hashrefs all called $ref_something) (n.b. the "Message" is all on one line in my script - I've broken it up here just to make it easier to read):
use Mail::Sendmail; my $Date = substr(gmtime $ref_event->{'EventStartDateTime'},0,10); my $SecID = int rand 16777216; my %m; # what I'd like to do except it doesn't work: %m = ( To => $ref_provider->{'ProviderEmail'}, From => 'management@trainingboard.co.uk', Subject => 'COURSE AVAILABILITY INQUIRY', Message => "We have received an inquiry about availability on the following course run by you:\n\n Course Title:\t\t\t $ref_course->{'CourseTitle'}\n \nCourse Date:\t\t\t$Date\n\n Number of Places Requested:\t\t $ref_booking->{'NumberOfAttendees'}\n\n Please confirm within 24 hours whether sufficient places are available (and if not, what alternatives there may be) by visiting the following site: http://www.trainingboard.co.uk/dmp/ $ref_provider->{'ProviderID'}/booking.pl? Action=Confirm Availability&BookingID= $ref->{'BookingID'}&SecID=$SecID", ); # what I am doing at present but hope to improve on: my $To = $ref_provider->{'ProviderEmail'}; my $Message = "We have received an inquiry about availability on the following course run by you:\n\n Course Title:\t\t\t $ref_course->{'CourseTitle'}\n \nCourse Date:\t\t\t$Date\n\n Number of Places Requested:\t\t $ref_booking->{'NumberOfAttendees'}\n\n Please confirm within 24 hours whether sufficient places are available (and if not, what alternatives there may be) by visiting the following site: http://www.trainingboard.co.uk/dmp/ $ref_provider->{'ProviderID'}/booking.pl? Action=Confirm Availability&BookingID= $ref->{'BookingID'}&SecID=$SecID"; %m = ( To => $To, From => 'management@trainingboard.co.uk', Subject => 'COURSE AVAILABILITY INQUIRY', Message => $Message, );
I'd be most grateful if anybody can tell me a neater way to do it. I feel this is something I ought to know - if so, I apologise for my ignorance!

§ George Sherston

Replies are listed 'Best First'.
Re: Passing functions etc into hashes
by htoug (Deacon) on Sep 17, 2001 at 12:51 UTC
    When assigning values to a hash you are in array-context. This can (will!) change the output of some functions, and may (will!) cause great confusion.

    You don't say what goes wrong - so I may be barking up the wrong tree (in the wrong forrest possibly).

      Ah. Often I only realise what's really going on in my life by acting on the assumption that it's actually something different. Don't try this at home, kids, as it may end up with you living in the wrong country, with the wrong number of internal organs, married to a person of the wrong sex. THEN you'll know. Lucky for me, the present instance was not so earth-shattering. But I found out it wasn't to do with passing functions into hashes. They calculate fine in hashes, and my preferred method set out above DOES actually work. So - sorry to waste your time; but thanks for providing a sounding board which obliged me to formulate my problem, and then challenged me to determine whether it was a problem or not. One day I'll be able to do this for myself...

      § George Sherston

      I wish => would force scalar context upon both of its operands...

              - tye (no, really, that is all I have to say on this)