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

Hi Monks,

I have what I think is a simple question, but so far my research has been fruitless. How do I restore the defaults for special variables such as $", $,, $#, etc.? If there is no good way to do this, is there a place that lists all the defaults so I can manually set them back (since for some, such as $# the default format is not immediately obvious).

oh, also, is there a way to get perl to recognize "0." as a number? it seems to think it is a string....(so $# formatting does not apply when it outputs "0.").

Thanks!
Justin

Replies are listed 'Best First'.
Re: restoring special variable defaults
by Roger (Parson) on Feb 07, 2004 at 01:06 UTC
    The best way to use perl special variables is to create a lexical scope, localize the special variables and modify their behaviour, and when the lexical scope ends perl automatically restores them back to their previous settings.

    Examples:
    { # localize special variables and assign different values local $" = '|'; # do something with the modified special variables print "@fields\n"; # when the lexical scope ends, perl automatically # restores the special variables to their previous value } my $text = do { local $/; <DATA> }

    You also need to be aware of the side effects of localized special variables because the effects are visible globally when calling other functions. As a rule, I always try to keep the code as simple as possible when localizing special variables, and try to avoid calling other subs, just to keep the effect as temporary and as local as possible.

Re: restoring special variable defaults
by Berik (Sexton) on Feb 07, 2004 at 01:16 UTC
    For the "0." thing, if you are litteraly using "0." (with the quotes), you _are_ defining a string.

    You could either define it as a number (Could even use 0. for that in perl altough I advise you to just use 0), or convert your value explicitly to a number: "0." + 0 (or int( "0." ) to make it an integer).

    This will make sure that -whatever you are defining- contains the number '0' at the end.
Re: restoring special variable defaults
by ysth (Canon) on Feb 09, 2004 at 04:25 UTC
    You would usually say
    { local $#; ... do some stuff }
    to have e.g. $# restored at the end of a block.

    To force something to stringize as a number, first convert it with the 0+ operator and then use it in a string context:$x = "0.";  $x = 0+ $x;  print $x; Just kidding, there is no 0+ operator; but simply adding 0 as above will produce something with a numeric value and no string value; then using it in string context will cause the numeric value to be stringized, invoking $# (unless the newish preserve-integers-where possible logic kicks in).

    By the way, $# is deprecated; use printf/sprintf directly instead; that will save you having to do the conversion: $x = "0."; printf "%.15e", $x and will avoid the aforementioned problem with perl bypassing floating point.

      In that case, can I do something like:

      printf "%5.3f",@yummy;

      to print all the elements of yummy in that format? My problem is that I have an array of variable length that I want to print out nicely, which is why $# seemed the only reasonable solution.

      BTW, the scope thing should work for me, I was just curious.

        No, you would need to do printf "%5.3f " x @yummy, @yummy or print join " ", map sprintf("%5.3f",$_), @yummy (both untested).