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

I have a format declared in a regular script (yes, using strict). I will use it to generate a purchase order from an online listing of products. I originally put it in a class definition, but I kept getting errors like:

Global symbol "$city" requires explicit package name at lib/PurchaseOrder.pm line 192

So, it works flawlessly in the regular script, but it doesn't work at all in the method of this class. I want the method to generate the purchase order and save it to a database. It seems like there's no way to use strict and these formats at the same time in the class. At least, I can't figure out how to do it. The format declaration expects those variables to be globals. I have them declared with my() inside the method declaration, but that's not cutting it. Any ideas on how to get the format's expected variables to be "global" enough so the format can use them inside a class?

More for code, in case it's helpful.
Here's the code working in the script:
my ($sku, $description, $price, $qty); foreach my $item (@items) { ($sku, $description, $price, $qty) = @$item; write(PURCHASEORDER); }
And of course it gets put into a sub when it gets dropped into the class, thus the issue with the globals.
Updated to fix formatting.

Replies are listed 'Best First'.
Re: format declaration in a class
by broquaint (Abbot) on May 25, 2004 at 02:39 UTC
    Declare your format variables with either vars or our and then within the loop use local e.g
    use vars qw($sku, $description, $price, $qty); foreach my $item (@items) { local($sku, $description, $price, $qty) = @$item; write(PURCHASEORDER); }
    Or you could fully qualify your variables in your format and localize the appropriate variables i.e
    use strict; format STDOUT = @<<<<<<< $::foo . local $::foo = 'a string'; write STDOUT; __output__ a string
    Or you can declare the lexicals before the format, if that's feasible. See. perlform for more info.
    HTH

    _________
    broquaint

    update: added second to last sentence and finished the incomplete middle sentence

      Hi and thanks for your help. The use vars seems to work fine, although when I tried our (in fact I tried it first before I posted to perlmonks.org), I got (and continue to get) these errors:

      Variable "$sku" is not imported at lib/PurchaseOrder.pm line 206
      Global symbol "$sku" requires explicit package name at lib/PurchaseOrder.pm line 206.


      So my only solution (I guess?) is to use vars.
      I'm going to do more research to figure out exactly what that does. Thanks a lot! Update: Well I was mistaken, I need to put the our declarations external to a sub. In which case it works perfectly. Thanks again!
Re: format declaration in a class
by Stevie-O (Friar) on May 25, 2004 at 03:03 UTC
    Your problem is that my does NOT make global variables, it makes local ones. broquaint above has described very well what to do -- use 'our' and 'local' together to achieve your goals.
    --Stevie-O
    $"=$,,$_=q>|\p4<6 8p<M/_|<('=> .q>.<4-KI<l|2$<6%s!<qn#F<>;$, .=pack'N*',"@{[unpack'C*',$_] }"for split/</;$_=$,,y[A-Z a-z] {}cd;print lc
Re: format declaration in a class
by jmcnamara (Monsignor) on May 25, 2004 at 19:47 UTC