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

I have done this before and It just won't work now. I am trying to print a dollar amount, but it keeps only showing the .00 (cents). Here is my code:
# Tried this: $_table_data .= qq~ </td> <td align="center" valign="top" style="padding-top: 5px"> \$~ . sprintf("%.2f", "$_srp_price") . qq~ </td> </tr>~; # Result: .95 SHOULD be: 4.95 # And this: $_table_data .= qq~ </td> <td align="center" valign="top" style="padding-top: 5px"> ~ . '$' . sprintf("%.2f", "$_srp_price") . qq~ </td> </tr>~; # Result: .95 # And This: $_table_data .= "\$"; $_table_data .= sprintf("%.2f", "$_srp_price"); # Result: Same thing: .95 # And This: $_table_data .= '$'; $_table_data .= "$_srp_price"; # Result: Same thing: .95 # And This: $_table_data .= '\$'; $_table_data .= $_srp_price; # Result: .95 Same thing again. # And this: $_table_data .= '\\$'; $_table_data .= $_srp_price; # Result: \.95 # And this (works without the dollar sign $_table_data .= sprintf("%.2f", "$_srp_price"); # Result: 4.95
I have tried all kinds of different variations. I cannot get this to work no matter what I try!

Later in the code I have $_table_data inserted into another variable which is inside a html table.

I don't know what I did different, but this is just one page of a lot of them. Here is my main index.cgi file that calls the different 'modules' I am using:
use CGI::Carp qw(fatalsToBrowser); use CGI qw(:standard :cgi-lib escapeHTML); use Mail::Sendmail; use Digest::MD5; use Crypt::CBC; use Crypt::Blowfish; use LWP::UserAgent; use Calendar::Simple; use OGC::Sid; use strict; use Time::Duration; use vars qw($cookie $sessid $sessref $page $loggedin $pgtitle $_title +%in $_pp_browser $reqdir $pg $_page_content $_dur_time); $_dur_time = time(); ReadParse(\%in);
Any ideas?

I would really appreciate any advice as to how I can do this. I don't know if one of the modules I'm using is messing this up. I also call HTTP::BrowserDetect later in a config file.
thx,
Richard

Replies are listed 'Best First'.
Re: Printing a dollar sign..
by davorg (Chancellor) on Aug 26, 2004 at 11:03 UTC

    What do you think is in $_srp_price? Can we see the code that sets it?

    I'm guessing that you have code something like:

    $_srp_price = "$4.95"; print $_srp_price;

    Here's an example

    $ perl -le '$_ = "$4.95"; print' .95

    Adding the -w flag tells us what is going wrong

    $ perl -wle '$_ = "$4.95"; print' Use of uninitialized value in concatenation (.) or string at -e line 1 +. .95

    Perl is looking for a variable called $4 and failing to find it.

    The fix is to either use single quotes

    $ perl -wle '$_ = q($4.95); print' $4.95

    Or to escape the dollar sign

    $ perl -wle '$_ = "\$4.95"; print' $4.95
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Actually it's called out of a database. Here is the code:

      $db_s_id = param("scid"); my $sth = $dbh->prepare (qq{ SELECT * FROM `prods` WHERE ? IN (sub +_cat1,sub_cat2,sub_cat3) AND `u` = "1"}); $sth->execute($db_s_id); my $_cell_cnt = 0; while($row = $sth->fetchrow_hashref()) { $_cell_cnt++; $_srp_price = $row->{srp}; $_table_data .= qq~ <tr valign="middle"> <td align="center"> <a href="javascript:;" onclick="window.open('$_img +url/ShowPic.cgi?pid=$row->{pid}','POPUP','status=no,menu=no,location= +no,resizable=yes,scrollbars=yes,width=400,height=400,top=25,left=25') +; return false" onmouseover="window.status='Opens in New window'; ret +urn true" onmouseout="window.status=''; return true">~; if(-e "/home/<<user_replaced>>/www/images/prod_images/$row->{pid}. +gif") { $_table_data .= qq~<img src="$_imgurl/images/prod_images/$row- +>{pid}.gif" width="75" alt="$row->{name}" border="0">~; } else { $_table_data .= qq~<img src="$_imgurl/images/no_image.gif" wid +th="75" alt="No Image Yet Available. Sorry." border="0">~; } $_table_data .= qq~</a> </td> <td align="center"> <a href="javascript:;" onclick="window.open('$_url +?pg=$in{pg}&view=showFullItem&pid=$row->{pid}&nw=1$inc_sess_id','FULL +VIEW','status=no,menu=no,location=no,resizable=yes,scrollbars=yes,wid +th=400,height=400,top=25,left=25'); return false" onmouseover="window +.status='Opens in New window'; return true" onmouseout="window.status +=''; return true">$row->{name}</a><br>~; if($row->{instock} && ($row->{instock} == 1)) { $_stock_message = "In Stock"; $_table_data .= qq~[<a href="$_surl?pg=products&view=cart&do=a +dd_prod&pid=$row->{pid}$inc_sess_id">Add to Cart</a>] ~; } else { $_stock_message = qq~<font class="stand_out">Out of Stock</fon +t>~; } if($_logged_in && ($_logged_in == 1)) { $_table_data .= qq~[<a href="$_url?pg=products&view=wish_list& +do=add&id=$row->{pid}$inc_sess_id">Add to Wish List</a>]~; } $_table_data .= qq~<br> $row->{desc}<br> Item Number: $row->{pid}~; if($row->{itemSize} && ($row->{itemSize} ne "")) { $_table_data .= qq~ .:. Size: $row->{itemSize}~; } $_table_data .= qq~ $_stock_message~; if($row->{uom} && ($row->{uom} ne "")) { $_table_data .= qq~ .:. Unit of Measure: $row->{uom}~; } $_table_data .= qq~ </td> <td align="center" valign="top" style="padding-top: 5p +x"> ~ . escapeHTML(sprintf("%.2f", "$_srp_price")) . q +q~ </td> </tr> ~; } $sth->finish();
      I will try the code you suggested and see if it works, I'll post the results. BTW, I don't eval the $_page_content which is the variable that $_table_data gets put into. I do eval $vars{} variables that contain <code></code> tags. That is the only ones I use eval on.

      thx,
      Richard
Re: Printing a dollar sign..
by tachyon (Chancellor) on Aug 26, 2004 at 10:52 UTC

    I don't quite know what you are doing, besides unnecessarily stringifying your vars. The first example you quote does work, as does the second. All I can suggest is that you go on to eval the string at some point so the $123.45 is evaluated by perl - perl will see the $123 as a var (undef value) and thus leave you with .45 I suspect you have not got warnings turned on as it would be warning you about interpolating an undef string. I suggest you use warnings;. This works as you can see.

    $_srp_price = 123.456789; $cost = sprintf "\$%.2f", $_srp_price; $string = "Cost $cost\n"; print $string; __DATA__ Cost $123.46

    cheers

    tachyon

      I figured it out. You guys were right. :o) I did have an eval in there. I had it do a search for variables and switch them out of the HTML:
      $_template_code =~ s/(\$[a-zA-Z0-9\{\'\}_]+)/ eval($1) /ge; # Switch a +ll the $variables... (This is the WHOLE html document, $_page_content + is in the main table for the main content. This will switch any vari +ables with the data.
      I fixed it by adding this to it:
      $_template_code =~ s/(\$[a-zA-Z0-9\{\'\}_]+)/ eval($1) /ge if $1; # Sw +itch all the $variables...
      adding the 'if $1' fixed it because the variable is undefined so it won't switch it.

      Thank you guys for pointing me in the write direction :)
      thx,
      Richard

        Consider HTML::Template or at least using its syntax. Using $VAR in templates and eval is not exactly best practice.

        cheers

        tachyon

Re: Printing a dollar sign..
by borisz (Canon) on Aug 26, 2004 at 10:56 UTC
    I think you eval the data in $data_table and then $4 ( from 4.95 ) is interpreted as a variable. If you try $_table_data .= '\\\$'; it might work. Or do sprintf '\$%.2f',$value.
    Boris