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

Hi, I'm getting a strange behavior within a function call, I want to print to the browser the value of a variable after passing it the value by a function.
sub loadFabricantProperties { local our $string; local our $fabricant = shift || ''; local our $libelle = shift || $SERVER{'fabricant'}; local our $enchere = shift || ''; local our $encherereur; if ($enchere) { $encherereur= $articleClass->getLastEnchereurDe +tail();} $string .= "<tr><td align=\"left\">$libelle</td><td align=\"left\" +><input type=\"text\" name=\"fabricant\" value=\"$ARTICLE{'author'}\" + onchange=\"validateInput();\"></td>$encherereur</tr>"; return $string; }
it's print in my browser LoadProperties=HASH(0xa75ee00) for the value of $fabricant instead of the value Any suggestion ? Thanks

Replies are listed 'Best First'.
Re: perl variable displayed as a hash value
by space_monk (Chaplain) on May 30, 2013 at 15:47 UTC
    If you are returning large amounts of text/html, consider using "heredocs". It means you don't need to escape quotes and the HTML you output can be read easily. The code is at the bottom of this comment.

    Doing it this way shows several things more clearly:

    1. Why use "local our" instead of "my" to declare your subroutine variables? If you read the Perl documentation it says in the first para you probably should not be using it
    2. $enchereurer may be undefined if $enchere is empty or undefined. You had also best check that $articleClass->getLastEnchereurDetail() is guaranteed to return a string of some sort
    3. Where is the %ARTICLE hash and the $articleClass object declared? Using global data inside routines is (normally, but not always) bad practice.
    4. You are concatenating on to the end of $string even though you have not defined it. Perl may or may not accept this, but it's poor coding.
    sub loadFabricantProperties { my $fabricant = shift || ''; my $libelle = shift || $SERVER{'fabricant'}; my $enchere = shift || ''; # just because the bidder loves ternary operators.... my $encherereur = $enchere ? $articleClass->getLastEnchereurDetail() : ''; my $string = <<EOF; <tr> <td align="left">$libelle</td> <td align="left"> <input type="text" name="fabricant" value="$ARTICLE{'author'}" onchange="validateInput();"> </td> $encherereur </tr> EOF return $string; }
    If you spot any bugs in my solutions, it's because I've deliberately left them in as an exercise for the reader! :-)
      The hash %ARTICLE is shared from another package and used in the package where the call is done
      package LoadProperties; use SharedVariable qw (%ARTICLE)
      and loadFabricantProperties is called from another package LoadPage within a code like this
      $fabricant = $lp->loadFabricantProperties($ARTICLE{'marque'},'',$value +);
      in this package I also make a use of the package SharedVariable
      package SharedVariable; use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); use Time::HiRes qw(gettimeofday); use Compress::Zlib; use CGI::Session qw/-ip-match/; use vars qw (%ENV $session_dir $page $dir $dirLang $dirError $imgdir $ +action $t0 $session_id $can_do_gzip $current_ip $lang $LANG %ARTICLE +%SESSION %SERVER %USER $CGISESSID %LABEL %ERROR %VALUE $COMMANDID %CO +MMAND %DATE %PAYPALL $INDEX %LINK $query $session $host $t0 $client +); #Set the values to the global variables $query = CGI->new ; $current_ip = $ENV{'REMOTE_ADDR'}; $client = $ENV{'HTTP_USER_AGENT'}; $t0 = gettimeofday(); $host = "http://avant-garde.no-ip.biz"; %ERROR = ();%LABEL = ();$LANG = "";%LINK = ();%ARTICLE = ();%SESSION = + ();%SERVER = (); % $action = $query->param('action'); $page = $query->param("page"); $session_id = $query->param('session'); $can_do_gzip = ($ENV{'HTTP_ACCEPT_ENCODING'} =~ /gzip/i) ? 1 : 0; $dir = "/home/alexandre/apache/site/recordz1/"; $dirLang = "/home/alexandre/apache/site/recordz1/lang"; $dirError = "/home/alexandre/apache/site/recordz1/lang"; $imgdir= "/home/alexandre/apache/site/recordz1/upload"; $session_dir = "/home/alexandre/apache/site/recordz/sessions"; $action = $query->param('action'); $session_id = $query->param('session'); if ($session_id eq '' or $session_id eq '$SESSIONID') { $session = new CGI::Session("driver:File", undef, {Directory=>"$se +ssion_dir"}); $session_id = $session->id(); } #load html label loadLanguage (); #load error label loadError(); sub new { my $class = shift; my ($opts)= @_; my $self = {}; return bless $self, $class; } sub loadLanguage { $lang = $query->param("lang"); #$lang = substr ($ENV{'HTTP_ACCEPT_LANGUAGE'},0,2); #$lang =~ s/[^A-Za-z0-9 ]//; $lang = uc ($lang); open (FILE, "<$dirLang/$lang.conf") or die "cannot open file $dirL +ang/$lang.conf"; while (<FILE>) { (local our $label, local our $value) = split(/=/); $SERVER{$label} = $value; } close (FILE); } sub loadError { $lang = lc ($query->param('lang'));#=~ s/[^A-Za-z0-9 ]//; #$lang=~ s/[^A-Za-z0-9 ]//; open (FILE, "<$dirError/$lang.conf") or die "cannot open file $dir +Error/$lang.conf"; while (<FILE>) { (local our $label, local our $value) = split(/=/); $SERVER{$label} = $value; } close (FILE); } BEGIN { use Exporter (); @SharedVariable::ISA = qw(Exporter); @SharedVariable::EXPORT = qw(gettimeofday()); @SharedVariable::EXPORT_OK = qw ($session_dir $page $action $di +r $dirLang $dirError $imgdir $session_id $can_do_gzip $current_ip $la +ng $LANG %ARTICLE %SESSION %SERVER %USER $CGISESSID %LABEL %ERROR %VA +LUE $COMMANDID %COMMAND %DATE %PAYPALL $INDEX %LINK $query $session +$host $t0 $client); } 1;
      In this package I want to share the global variable to the other package $articleClass is a variable that define the usage of another package Article.pm where some functions are defined like the call to this
      sub getLastEnchereurDetail { local our $string;local our $article = $query->param("article"); local our $ref_max_enchereur; local our $max_enchere; ($ARTICLE{'max_enchere'})=$mydb->sqlSelect1("MAX(prix)", "enchere" +, "ref_article = '$article'"); if ($ARTICLE{'max_enchere'} ne '') { ($ARTICLE{'max_enchereur'},$ARTICLE{'id_enchere'})=$mydb-> +sqlSelect1("ref_enchereur,id_enchere", "enchere", "ref_article = '$ar +ticle' AND prix = $ARTICLE{'max_enchere'}"); ($ARTICLE{'nom_utilisateur_acheteur'},$ARTICLE{'email_acheteur +'},$ARTICLE{'acheteur_lang'},$ARTICLE{'acheteur_adresse'},$ARTICLE{'a +cheteur_ville'},$ARTICLE{'acheteur_npa'},$ARTICLE{'acheteur_telephone +'},$ARTICLE{'acheteur_nom'},$ARTICLE{'acheteur_prenom'})= sqlSelect(" +nom_utilisateur,email,lang,adresse,ville,npa,no_telephone,nom,prenom" +, "personne", "id_personne = '$ref_max_enchereur'"); } $string .= "<td align=\"left\" width=\"200\"><label id=\"label_cat +egory_name\">$SERVER{'last_enchereur'}</label></td>"; $string .= "<td align=\"left\"><a href=\"/cgi-bin/recordz.cgi?lang +=$lang&amp;session=$session_id&page=profil_vendeur&username=$ARTICLE{ +'nom_utilisateur_acheteur'}\" class=\"menulink\" >$ARTICLE{'nom_utili +sateur_acheteur'}</a></label></td>"; return $string; }
      Where $ARTICLE are also been shared within the use of SharedVariable
        More questions:
        1. Why does the second sqlSelect statement not have a $mydb reference? At the best you are being inconsistent.
        2. The following code will not handle undefined items gracefully. I hope the database can be guaranteed to return empty strings if no data is present for fields.
        3. You should separate getting the data into %ARTICLE from its presentation in HTML. i.e. separate the Model from the View

        sub getLastEnchereurDetail { my $article = $query->param("article"); my $ref_max_enchereur; my $max_enchere; ($ARTICLE{'max_enchere'})=$mydb->sqlSelect1("MAX(prix)", "enchere" +, "ref_article = '$article'"); if ($ARTICLE{'max_enchere'} ne '') { ($ARTICLE{'max_enchereur'},$ARTICLE{'id_enchere'})=$mydb->sqlS +elect1("ref_enchereur,id_enchere", "enchere", "ref_article = '$articl +e' AND prix = $ARTICLE{'max_enchere'}"); # why is this not $mydb->sqlSelect1 like above? my @result = sqlSelect("nom_utilisateur,email,lang,adresse,vil +le,npa,no_telephone,nom,prenom", "personne", "id_personne = '$ref_max +_enchereur'"); ($ARTICLE{'nom_utilisateur_acheteur'},$ARTICLE{'email_ +acheteur'}, $ARTICLE{'acheteur_lang'},$ARTICLE{'acheteur_adresse'}, $ARTICLE{'acheteur_ville'},$ARTICLE{'acheteur_npa'}, $ARTICLE{'acheteur_telephone'},$ARTICLE{'acheteur_nom'}, $ARTICLE{'acheteur_prenom'})= @result; } my $string =<<EOF; <td align="left" width="200"><label id="label_category_name">$SERVER{' +last_enchereur'}</label></td> <td align="left"> <a href="/cgi-bin/recordz.cgi?lang=$lang&amp;session=$session_id&p +age=profil_vendeur&username=$ARTICLE{'nom_utilisateur_acheteur'}" cla +ss="menulink"> $ARTICLE{'nom_utilisateur_acheteur'}</a></label> </td> EOF return $string; }
        If you spot any bugs in my solutions, it's because I've deliberately left them in as an exercise for the reader! :-)
Re: perl variable displayed as a hash value
by choroba (Cardinal) on May 30, 2013 at 15:26 UTC
    In the sub, LoadProperties is not printed. Where does the output come from? How do you call the sub?
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ