[32808] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 4072 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Nov 7 00:09:37 2013

Date: Wed, 6 Nov 2013 21:09:04 -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           Wed, 6 Nov 2013     Volume: 11 Number: 4072

Today's topics:
    Re: Dumper <jl_post@hotmail.com>
        How can I pick a module depending if I have it or not? <jl_post@hotmail.com>
    Re: How can I pick a module depending if I have it or n <bill@todbe.com>
    Re: How can I pick a module depending if I have it or n <rweikusat@mobileactivedefense.com>
    Re: How can I pick a module depending if I have it or n <rweikusat@mobileactivedefense.com>
    Re: How can I pick a module depending if I have it or n <derykus@gmail.com>
    Re: How can I pick a module depending if I have it or n <ben@morrow.me.uk>
    Re: readdir <jl_post@hotmail.com>
    Re: Several Perl Questions - Nov. 5, 2013 <ben@morrow.me.uk>
    Re: Several Perl Questions - Nov. 5, 2013 <ben@morrow.me.uk>
    Re: Several Perl Questions - Nov. 5, 2013 <justin.1303@purestblue.com>
        sorting by prior value in a deeply nested hash <cartercc@gmail.com>
    Re: sorting by prior value in a deeply nested hash <jimsgibson@gmail.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Wed, 6 Nov 2013 15:21:33 -0800 (PST)
From: "jl_post@hotmail.com" <jl_post@hotmail.com>
Subject: Re: Dumper
Message-Id: <4bf11bac-8e65-4eea-b06a-a1c10e46d702@googlegroups.com>

On Tuesday, October 15, 2013 6:36:07 AM UTC-6, George Mpouras wrote:
> # this works
>=20
>=20
>=20
>=20
>=20
>=20
>=20
> use Data::Dumper; $Data::Dumper::Purity=3D1;
>=20
> my $dmp;
>=20
> my %hash1 =3D ('k1'=3D>'v1','k2'=3D>'v2');
>=20
> $dmp =3D Data::Dumper::Dumper( \%hash1 );;
>=20
> my $hash2 =3D eval $dmp; print Data::Dumper::Dumper($hash2);
>=20
>=20
>=20
>=20
>=20
> # this is not
>=20
>=20
>=20
> use strict; use warnings;
>=20
> use Data::Dumper; $Data::Dumper::Purity=3D1;
>=20
> my $dmp;
>=20
> my %hash1 =3D ('k1'=3D>'v1','k2'=3D>'v2');
>=20
> $dmp =3D Data::Dumper::Dumper( \%hash1 );;
>=20
> my $hash2 =3D eval $dmp; print Data::Dumper::Dumper($hash2);
>=20
>=20
>=20
>=20
>=20
> what I am doing wrong


Dear George,

   By now you've figured out that the $VAR1 variable in the Data::Dumper::D=
umper() output is conflicting with "use strict;", and that setting $Data::D=
umper::Terse to 1 removes that conflict.

   However, I question why you're dumping the output to Dumper into a strin=
g and then eval()ing it to assign to another hash.  Is it because you want =
a convenient way to create a deep copy of a hash/array/object?

   If so, I recommend using the Storable module instead.  It's a standard m=
odule in Perl these days.  It avoids the use of having to use eval(), and i=
t's probably considerably quicker than doing the same thing with Data::Dump=
er.

   Here I'm giving you three different ways to use the Storable module, one=
 of which should nicely match what you're trying to do:


{
   # Making a copy from a temporary string (using freeze() and thaw()):
   use strict;
   use warnings;
   my %hash1 =3D ('k1' =3D> 'v1', 'k2' =3D> 'v2');
   use Storable;
   my $tempString =3D Storable::freeze( \%hash1 );
   my %hash2 =3D %{ Storable::thaw($tempString) };
   use Data::Dumper;  print Data::Dumper::Dumper( \%hash2 );
}


{
   # Making a copy from a file (using nstore() and retrieve()):
   use strict;
   use warnings;
   my %hash1 =3D ('k1' =3D> 'v1', 'k2' =3D> 'v2');
   my $fileName =3D "file.tmp";
   use Storable;
   Storable::nstore( \%hash1, $fileName );
   my %hash2 =3D %{ Storable::retrieve($fileName) };
   use Data::Dumper;  print Data::Dumper::Dumper( \%hash2 );
}


{
   # Making a deep copy directly (using dclone()):
   use strict;
   use warnings;
   my %hash1 =3D ('k1' =3D> 'v1', 'k2' =3D> 'v2');
   use Storable;
   my %hash2 =3D %{ Storable::dclone( \%hash1 ) };
   use Data::Dumper;  print Data::Dumper::Dumper( \%hash2 );
}


   If all you want to do is to perform a deep copy on a hash/array/object, =
I advise using the third approach I listed (the one that uses Storable::dcl=
one()).  But if you want the data to a file to retrieve later, I recommend =
the approach that uses nstore() and retrieve().

   Using eval() to copy data is not always a great idea.  For one thing, if=
 you the data that you eval() comes from a file, someone could have easily =
tampered with the contents of the file, placing malicious Perl code in the =
file that ends up getting executed when you eval() it.

   So if all you want is to store data to a file (for later retrieval), use=
 Storable::nstore() (and retrieve it later with Storable::retrieve()) inste=
ad of Data::Dumper.  Or if all you want is to create a deep copy/clone of a=
n object, use Storable::dclone().

   The main reason you'd want to use Data::Dumper is to visually inspect th=
e data you're working with, which is something you can't do easily with the=
 Storable module (which is why I'm using Data::Dumper in all three of my ex=
amples above).  (But if you only really needed to visually inspect the data=
, there'd be no reason to eval() it later.)

   So my advice is to use the Storable module instead of Data::Dumper, unle=
ss you need to manually inspect the contents of a scalar/array/hash/object.

   I hope this is helpful, George.

   -- Jean-Luc


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

Date: Wed, 6 Nov 2013 10:27:21 -0800 (PST)
From: "jl_post@hotmail.com" <jl_post@hotmail.com>
Subject: How can I pick a module depending if I have it or not?
Message-Id: <ecf7064d-9290-4550-8c74-c2ab599c6c54@googlegroups.com>

Dear Perl community,

   Recently I had to debug a Perl script in a Windows environment that was =
meant for a Unix environment.  The script used the module Device::SerialPor=
t, and since I didn't have it on my Windows installation of Strawberry Perl=
, the compiler check "perl -c script.pl" was giving me errors.

   No problem, I thought; I'll just use the "cpan Device::SerialPort" to in=
stall it, and that'll be the end of my problem.  Well, I wasn't able to ins=
tall the Device::SerialPort module through Strawberry Perl, so I looked aro=
und CPAN and the internets to see what I could do.

   I discovered a very similar module named Win32::SerialPort.  It is so si=
milar to Device::SerialPort that many of the method names are the same.  An=
d I was able to install Win32::SerialPort onto my Strawberry Perl setup.  A=
fter that I was able to change:

   use Device::SerialPort;
   my $port =3D Device::SerialPort->new($portName)
      or die "Can't establish connection with $portName.\n";

to:

   use Win32::SerialPort;
   my $port =3D Win32::SerialPort->new($portName)
      or die "Can't establish connection with $portName.\n";

and the rest of the code (that involved the SerialPort, at least) compiled =
just fine.

   However, once I finished debugging the script I had to remember to chang=
e the "Win32::SerialPort" module to "Device::SerialPort" before I sent the =
script back for use on a Unix platform.  Eventually an idea came to me that=
 I could let the script determine which module to use (depending on whether=
 that module existed).  In other words, if Device::SerialPort exists, use t=
hat one, but if not, use Win32::SerialPort.  (And if neither exist, exit/di=
e with an informative error message.)

   So my question is:  How can I use a module if it is installed, or anothe=
r if it is not installed?

   I want to be able to do something like this:

   my $port =3D do
   {
      if (use Device::SerialPort)
      {
         Device::SerialPort->new($portName)
            or die "Can't establish connection with $portName.\n";
      }
      elsif (use Win32::SerialPort)
      {
         Win32::SerialPort->new($portName)
            or die "Can't establish connection with $portName.\n";
      }
      else
      {
         die "This script requires the Device::SerialPort or Win32::SerialP=
ort module.\n";
      }
   };


   Of course this code won't compile, so I was wondering if someone knows h=
ow to get a Perl script to do what I want -- that is, to detect which modul=
es (out of several) exist, and to properly load them as if I used them with=
 normal "use" syntax.

   Thanks in advance,

   -- Jean-Luc


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

Date: Wed, 06 Nov 2013 11:00:46 -0800
From: "$Bill" <bill@todbe.com>
Subject: Re: How can I pick a module depending if I have it or not?
Message-Id: <l5e3ks$o47$1@dont-email.me>

On 11/6/2013 10:27, jl_post@hotmail.com wrote:
> Dear Perl community,
>
>     Recently I had to debug a Perl script in a Windows environment that was meant for a Unix environment.  The script used the module Device::SerialPort, and since I didn't have it on my Windows installation of Strawberry Perl, the compiler check "perl -c script.pl" was giving me errors.
>
>     No problem, I thought; I'll just use the "cpan Device::SerialPort" to install it, and that'll be the end of my problem.  Well, I wasn't able to install the Device::SerialPort module through Strawberry Perl, so I looked around CPAN and the internets to see what I could do.
>
>     I discovered a very similar module named Win32::SerialPort.  It is so similar to Device::SerialPort that many of the method names are the same.  And I was able to install Win32::SerialPort onto my Strawberry Perl setup.  After that I was able to change:
>
>     use Device::SerialPort;
>     my $port = Device::SerialPort->new($portName)
>        or die "Can't establish connection with $portName.\n";
>
> to:
>
>     use Win32::SerialPort;
>     my $port = Win32::SerialPort->new($portName)
>        or die "Can't establish connection with $portName.\n";
>
> and the rest of the code (that involved the SerialPort, at least) compiled just fine.
>
>     However, once I finished debugging the script I had to remember to change the "Win32::SerialPort" module to "Device::SerialPort" before I sent the script back for use on a Unix platform.  Eventually an idea came to me that I could let the script determine which module to use (depending on whether that module existed).  In other words, if Device::SerialPort exists, use that one, but if not, use Win32::SerialPort.  (And if neither exist, exit/die with an informative error message.)
>
>     So my question is:  How can I use a module if it is installed, or another if it is not installed?
>
>     I want to be able to do something like this:
>
>     my $port = do
>     {
>        if (use Device::SerialPort)
>        {
>           Device::SerialPort->new($portName)
>              or die "Can't establish connection with $portName.\n";
>        }
>        elsif (use Win32::SerialPort)
>        {
>           Win32::SerialPort->new($portName)
>              or die "Can't establish connection with $portName.\n";
>        }
>        else
>        {
>           die "This script requires the Device::SerialPort or Win32::SerialPort module.\n";
>        }
>     };
>
>
>     Of course this code won't compile, so I was wondering if someone knows how to get a Perl script to do what I want -- that is, to detect which modules (out of several) exist, and to properly load them as if I used them with normal "use" syntax.

Try using eval - something like:

eval "use Device::SerialPort";
if ($@) {
	print "Can't find Device::SerialPort\n";
	eval "use Win32::SerialPort";
	if ($@) {
		die "Can't find Win32::SerialPort - quitting";
	} else {
		print "Found Win32::SerialPort - using it\n";
	}
} else {
	print "Found Device::SerialPort - using it\n";
}




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

Date: Wed, 06 Nov 2013 20:37:06 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: How can I pick a module depending if I have it or not?
Message-Id: <87mwlhjmh9.fsf@sable.mobileactivedefense.com>

"jl_post@hotmail.com" <jl_post@hotmail.com> writes:
>    Recently I had to debug a Perl script in a Windows environment that
>    was meant for a Unix environment.  The script used the module
>    Device::SerialPort, and since I didn't have it on my Windows
>    installation of Strawberry Perl, the compiler check "perl -c
>    script.pl" was giving me errors.

[...]

>    I discovered a very similar module named Win32::SerialPort.  It is
>    so similar to Device::SerialPort that many of the method names are
>    the same.

[...]

>    However, once I finished debugging the script I had to remember to
>    change the "Win32::SerialPort" module to "Device::SerialPort"
>    before I sent the script back for use on a Unix platform.

[...]

>    So my question is:  How can I use a module if it is installed, or
>    another if it is not installed?

Someone else must have implemented this already but you could use this
small module:

-------------
package Delegate;

sub import
{
    my ($candidates, $fname);

    shift;
    $candidates = shift;

    for (@$candidates) {
	$fname = $_;
	$fname =~ s/::/\//g;
	$fname .= '.pm';
	
	eval {
	    require $fname;
	};

	$@ || do {
	    unshift(@_, $_);
	    $_ .= "::import";
	    goto &$_;
	};
    }

    die("No way man ... \n");
}

1;
---------------

Example usage

---------------
use Delegate (['B::Mad', 'ModA'], 'for_whats_it_worth');

print(for_whats_it_worth(), "\n");
---------------

The first argument is a reference to an anonymous array containing a
list of candiate module names, the others are an ordinary import list.

NB: This doesn't duplicate the documented functionality of use ... /
require Bareword completely as it doesn't try loading a file with .pmc
at the end.


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

Date: Wed, 06 Nov 2013 22:42:00 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: How can I pick a module depending if I have it or not?
Message-Id: <87fvr9jgp3.fsf@sable.mobileactivedefense.com>

Rainer Weikusat <rweikusat@mobileactivedefense.com> writes:
> "jl_post@hotmail.com" <jl_post@hotmail.com> writes:
>>    Recently I had to debug a Perl script in a Windows environment that
>>    was meant for a Unix environment.  The script used the module
>>    Device::SerialPort, and since I didn't have it on my Windows
>>    installation of Strawberry Perl, the compiler check "perl -c
>>    script.pl" was giving me errors.
>
> [...]
>
>>    I discovered a very similar module named Win32::SerialPort.  It is
>>    so similar to Device::SerialPort that many of the method names are
>>    the same.
>
> [...]
>
>>    However, once I finished debugging the script I had to remember to
>>    change the "Win32::SerialPort" module to "Device::SerialPort"
>>    before I sent the script back for use on a Unix platform.
>
> [...]
>
>>    So my question is:  How can I use a module if it is installed, or
>>    another if it is not installed?
>
> Someone else must have implemented this already but you could use this
> small module:
>
> -------------
> package Delegate;
>
> sub import
> {
>     my ($candidates, $fname);
>
>     shift;
>     $candidates = shift;
>
>     for (@$candidates) {
> 	$fname = $_;
> 	$fname =~ s/::/\//g;
> 	$fname .= '.pm';
> 	
> 	eval {
> 	    require $fname;
> 	};
>
> 	$@ || do {
> 	    unshift(@_, $_);
> 	    $_ .= "::import";
> 	    goto &$_;
> 	};
>     }
>
>     die("No way man ... \n");
> }
>
> 1;
> ---------------

While this is a neat idea, it won't work with modules which don't define
or inherit an import method, won't work with OO-modules at all and is
restricted to a single set of delegations per program. Something more
suitable (for the problem situation which was about OO-modules) could
look like this:

-------------
sub require_one
{
    my $fname;

    for (@_) {
	$fname = $_;
	$fname =~ s/::/\//g;
	$fname .= '.pm';

	eval {
	    require $fname;
	};

	return $_ unless $@;
    }

    die("need any of ".join(', ', @_)."\n");
}
-------------

This expects a list of module names as arguments and will return the
name of the first one which could be loaded. This name can then used to
call class methods like this

$serial_class = require_one('Win32::SerialPort', 'Device::SerialPort');
$port = $serial_class->new($portName);


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

Date: Wed, 06 Nov 2013 17:09:26 -0800
From: Charles DeRykus <derykus@gmail.com>
Subject: Re: How can I pick a module depending if I have it or not?
Message-Id: <l5ep8m$f0g$1@speranza.aioe.org>

On 11/6/2013 10:27 AM, jl_post@hotmail.com wrote:
> ...
>     So my question is:  How can I use a module if it is installed, or another if it is not installed?
>
>     I want to be able to do something like this:
>
>     my $port = do
>     {
>        if (use Device::SerialPort)
>        {
>           Device::SerialPort->new($portName)
>              or die "Can't establish connection with $portName.\n";
>        }
>        elsif (use Win32::SerialPort)
>        {
>           Win32::SerialPort->new($portName)
>              or die "Can't establish connection with $portName.\n";
>        }
>        else
>        {
>           die "This script requires the Device::SerialPort or Win32::SerialPort module.\n";
>        }
>     };
>


Maybe a combination of 'use if'  and  Module::Load::Conditional ...

use Module::Load::Condition qw/check_install/;

our( $m1, $m2 );
use if $m1=check_install(module=>Device::SerialPort),Device::SerialPort;
use if $m2=check_install(module=>Win32::SerialPort), Win32::SerialPort;

die "This script requires..." unless $m1 or $m2;

-- 
Charles DeRykus


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

Date: Thu, 7 Nov 2013 02:44:18 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: How can I pick a module depending if I have it or not?
Message-Id: <2dbrka-m9b1.ln1@anubis.morrow.me.uk>


Quoth "jl_post@hotmail.com" <jl_post@hotmail.com>:
> 
>    So my question is:  How can I use a module if it is installed, or
> another if it is not installed?
> 
>    I want to be able to do something like this:
> 
>    my $port = do
>    {
>       if (use Device::SerialPort)

Since these are OO modules, so you don't need exports, just use require:

    if (eval "require Device::SerialPort; 1") {

(the "; 1" works around a rather obscure bug in some versions of 5.8;
it's probably obsolete at this point but I still put it in out of
habit.)

>       {
>          Device::SerialPort->new($portName)
>             or die "Can't establish connection with $portName.\n";
>       }
>       elsif (use Win32::SerialPort)
>       {
>          Win32::SerialPort->new($portName)
>             or die "Can't establish connection with $portName.\n";
>       }
>       else
>       {
>          die "This script requires the Device::SerialPort or
> Win32::SerialPort module.\n";
>       }
>    };

Of course, I would refactor this to
    
    my $port;
    for my $M (qw/Device::SerialPort Win32::SerialPort/) {
        if (eval "require $M; 1") {
            $port = $M->new($portName);
            last;
        }
    }
    $port or die "No serial port module found.\n";

or possibly

    use List::Util qw/first/;

    my $SerialPort = first { eval "require $_; 1" }
        qw/Device::SerialPort Win32::SerialPort/
        or die "No serial port module found.\n";

    my $port = $SerialPort->new($portName);

If you find you need imports, just spell out the 'use' explicitly:

    use List::Util qw/first/;

    my $SerialPort;
    BEGIN {
        $SerialPort = first ... # as before
        $SerialPort->import(...);
    }

    my $port = $SerialPort->new(...);

Ben



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

Date: Wed, 6 Nov 2013 10:48:48 -0800 (PST)
From: "jl_post@hotmail.com" <jl_post@hotmail.com>
Subject: Re: readdir
Message-Id: <373ebfe0-0b9b-41e6-912b-009e17564d65@googlegroups.com>

On Tuesday, October 29, 2013 4:06:59 PM UTC-6, George Mpouras wrote:
>
> Is there any way readdir to return me files by modification time ?
> I do not want keep their dates on an array and sort it .
> I want one pass like=20
>=20
> ls -ltr


Dear George,

   The readdir() function returns files in whatever order it wants.  Well, =
there's more to it than that, but you need to remember that you can't assum=
e it will ever be in any meaningful order.  That's why Perl gives us the so=
rt() function.

   You probably already know that if you want to sort filenames ASCII-betic=
ally, you can do so this way:

   @fileNames =3D sort @fileNames;

   Sorting by modification time is a bit more involved.  Fortunately, you c=
an use a Schwartzian Transform like this one:

   @fileNames =3D map {$_->[0]}
                sort {$b->[1] <=3D> $a->[1]}
                map {[$_, -M $_]} @fileNames;

(It is important to remember that the entries in @fileNames must contain a =
proper path to each file.  If the entries are just basenames (that is, they=
 have no path) and the files are not in the current working directory, then=
 this sort won't work properly.)

It's just one line long (though I had to break it up to avoid line-wrapping=
).  If it's not clear to you what it's doing, I suggest you read up on Schw=
artzian Transforms.  If you want to stick to the perldocs, you can read abo=
ut them in perlfaq4 with the command:

   perldoc -q "sort an array"

   Schwartzian Transforms can be very helpful, especially if you want to so=
rt an array of filenames in just one pass.  But they're not immediately int=
uitive, which is why it would be wise to study them enough to understand ho=
w to implement them in any programming language.

   I hope this helps, George.

   -- Jean-Luc


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

Date: Tue, 5 Nov 2013 22:05:43 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Several Perl Questions - Nov. 5, 2013
Message-Id: <nm6oka-7ni.ln1@anubis.morrow.me.uk>


Quoth "Peter J. Holzer" <hjp-usenet3@hjp.at>:
> On 2013-11-05 15:05, Ben Morrow <ben@morrow.me.uk> wrote:
> >
> > That's not actually true, though it is true that 32bit Windows won't run
> > 64bit executables. 16bit Windows used to run 32bit executables just
> > fine, and Mac OS X for quite a long time had a 32bit kernel that was
> > capable of running 64bit user processes.
> 
> There is always the question what "16 bit", "32 bit" and "64 bit" means.
> On some architectures, there were just additional instructions to access
> the longer registers. On others (like x86) there is no binary
> compatibility: You could compile a program to access EAX in 16-bit mode
> or in 32-bit mode, but the machine code would be different, and I think
> the same is true for 32/64bit x86 code.

That's not quite right: %eax is always a 32bit register, the 16bit
version is called %ax and refers to the lower half of %eax. Similarly,
%rax is a 64bit register which includes %eax as its lower half.

> On MS-DOS that mattered little
> because there was no hardware protection anyway, so any executable could
> just switch to 32-bit protected mode (and back into real mode[1] before
> exit), but any real OS (starting with Xenix-286 or protected mode
> Windows) needed to be able to set up 32-bit segments to run "real" 32
> bit executables, but without that it could of course run programs which
> just accessed the 32 bit integer registers (but only for computation,
> not as pointers). I'd hesitate to call Win95 with the Win32 subsystem a
> "16 bit OS": While large parts of it were (AIUI) still running in 16 bit
> protected mode, some parts (especially those dealing with 32 bit
> processes) were running in 32 bit mode (the segmented x86 architecture
> made stuff like that almost natural).

I was talking specifically about Win3.1, which would happily run 32bit
processes (presumably they included the appropriate setup code to switch
to 32bit mode). A notable example was Microsoft nmake, which in the
version of MSVC I had was a 32bit executable.

> I don't know about MacOS, but I
> guess you are talking about x86 here, too (AFAIK, Apple never sold
> machines with 64 bit POWER chips).

10.4 supported 64bit POSIX apps over a 32bit kernel, on amd64 or ppc
(the G5 is 64bit). 10.5 also supported 64bit GUI apps, also amd64 or
ppc. 10.6 was the first version to include a 64bit kernel, amd64 only
(10.6 was the release that dropped support for ppc), but did not always
run it by default. 10.8 was the first release not to include a 32bit
kernel at all.

Ben



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

Date: Tue, 5 Nov 2013 22:13:47 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Several Perl Questions - Nov. 5, 2013
Message-Id: <r57oka-7ni.ln1@anubis.morrow.me.uk>


Quoth "Peter J. Holzer" <hjp-usenet3@hjp.at>:
> On 2013-11-05 17:42, Ben Morrow <ben@morrow.me.uk> wrote:
> >
> > This is not true. Perl's core numerical ops are written to preserve
> > accuracy rather than for speed,
> 
> Which is almost certainly irrelevant. The numerical op itself is a
> single CPU (FPU) instruction and that's always done in extended
> precision on x86. (Unless the compiler uses SSE instructions or
> something similar, but AIUI that's only worthwhile if you are using many
> instructions).

Perl's op_add does a lot more than a machine add. When adding integers
it attempts to preserve integer precision beyond the range of a machine
IV, by upgrading the result first to UV and then to NV if that gives a
larger range with integer precision (which it does on 32bit x86, for
instance).

> > Math::Trig (and Math::Complex) are pure-Perl OO-based
> > implementations; I would expect these to be even slower.
> 
> What's object oriented about Math::Trig? That seems to me a rather
> simple collection of convenience functions.

The functions actually defined in Math/Trig.pm all call functions
imported from Math::Complex, which mostly start by converting numbers
into overloaded Math::Complex objects.

Ben



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

Date: Wed, 6 Nov 2013 11:59:44 +0000
From: Justin C <justin.1303@purestblue.com>
Subject: Re: Several Perl Questions - Nov. 5, 2013
Message-Id: <ginpka-k9g.ln1@zem.masonsmusic.co.uk>

On 2013-11-05, Henry Law <news@lawshouse.org> wrote:
>
> (This has to be by far the worst Perl code I've ever seen in my life).

Do you want to see some of mine? I'm sure I can find something quite 
horrific.


   Justin.

-- 
Justin C, by the sea.


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

Date: Wed, 6 Nov 2013 15:41:46 -0800 (PST)
From: ccc31807 <cartercc@gmail.com>
Subject: sorting by prior value in a deeply nested hash
Message-Id: <783fec5c-89cd-4a51-9cde-ae48642afa3e@googlegroups.com>

I have a reference to a hash defined like this:
$chpr->{$college}{$dept}{$rank}{$fac_id}{$subj} = {
  ...,
  sort_name = $sort_name,
  ...};

I print an Excel report like this:
#open Excel workbook for COLLEGE
foreach my $college (sort keys %{$chpr}) {
 foreach my $dept (sort keys %{$chpr->{$college}}) {
  foreach my $rank (sort keys %{$chpr->{$college}{$dept}}) {
  #open new worksheet for DEPARTMENT
   foreach my $fac_id (sort keys %{$chpr->{$college}{$dept}{$rank}}) {
    foreach my $subj (sort keys %{$chpr->{$college}{$dept}{$rank}{$fac_id}}) {
     #$worksheet->write_row($row, $col, $arrayref);
     #here, I would like to alphabetically sort by
     #$chpr->{$college}{$dept}{$rank}{$fac_id}{$subj}{sort_name}
     #so that the faculty names appear in alphabetical order listed 
     #by college, department, rank, and subject (faculty ID isn't wanted)
    }
   }
  }
 }
}

I can't see the $subj from $fac_id, and once I get to $subj, the has is already sorted by $fac_id. I can't figure out a way to retroactively unsort by $fac_id and sort by ...{$fac_id}...{sort_name}.

Ordering the faculty by sort_name isn't possible because sort_name is not unique, but fac_id is unique.

Suggestions? Other than rewriting the whole thing?

Thanks, CC.


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

Date: Wed, 06 Nov 2013 17:16:31 -0800
From: Jim Gibson <jimsgibson@gmail.com>
Subject: Re: sorting by prior value in a deeply nested hash
Message-Id: <061120131716313438%jimsgibson@gmail.com>

In article <783fec5c-89cd-4a51-9cde-ae48642afa3e@googlegroups.com>,
ccc31807 <cartercc@gmail.com> wrote:

> I have a reference to a hash defined like this:
> $chpr->{$college}{$dept}{$rank}{$fac_id}{$subj} = {
>   ...,
>   sort_name = $sort_name,
>   ...};
> 
> I print an Excel report like this:
> #open Excel workbook for COLLEGE
> foreach my $college (sort keys %{$chpr}) {
>  foreach my $dept (sort keys %{$chpr->{$college}}) {
>   foreach my $rank (sort keys %{$chpr->{$college}{$dept}}) {
>   #open new worksheet for DEPARTMENT
>    foreach my $fac_id (sort keys %{$chpr->{$college}{$dept}{$rank}}) {
>     foreach my $subj (sort keys %{$chpr->{$college}{$dept}{$rank}{$fac_id}}) {
>      #$worksheet->write_row($row, $col, $arrayref);
>      #here, I would like to alphabetically sort by
>      #$chpr->{$college}{$dept}{$rank}{$fac_id}{$subj}{sort_name}
>      #so that the faculty names appear in alphabetical order listed 
>      #by college, department, rank, and subject (faculty ID isn't wanted)
>     }
>    }
>   }
>  }
> }
> 
> I can't see the $subj from $fac_id, and once I get to $subj, the has is
> already sorted by $fac_id. I can't figure out a way to retroactively unsort
> by $fac_id and sort by ...{$fac_id}...{sort_name}.
> 
> Ordering the faculty by sort_name isn't possible because sort_name is not
> unique, but fac_id is unique.
> 
> Suggestions? Other than rewriting the whole thing?

I would stop at the $rank iteration and create a temporary data
structure that holds the data you want to print for that combination of
($college,$dept,$rank). I think you want to basically invert the hash
array for that point onward.

If you have a hash called %data, then iterate over $fac_id and $subj,
saving the data as $data{$subj}{$fac_id}. Then, when you are done, you
can iterate over subjects, iterate over faculty name, and print.

I might also create a %faculty_names hash using $faculty_name{$fac_id}
= sort_name for looking up the faculty name given the ID.

I would also recommend saving each hash reference in a scalar variable,
thereby getting rid of the multi-level hash fetches:

foreach my $college (sort keys %{$chpr}) {
  my $college_ref = $chpr->{$college};
  foreach my $dept (sort keys %{$college_ref} ) {
    my $dept_ref = $college_ref->{$dept};
    ...

-- 
Jim Gibson


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

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:

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

Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests. 

#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 V11 Issue 4072
***************************************


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