[32273] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 3540 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri Nov 11 14:09:30 2011

Date: Fri, 11 Nov 2011 11:09:09 -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           Fri, 11 Nov 2011     Volume: 11 Number: 3540

Today's topics:
        ActiveState Perl and MinGW [was: Perl 5.14 Windows Stra <dilbert1999@gmail.com>
        ActiveState Perl and MinGW [was: Perl 5.14 Windows Stra <dilbert1999@gmail.com>
        Email::MIME not decoding '8bit' but it looks as if it o <news@lawshouse.org>
    Re: Email::MIME not decoding '8bit' but it looks as if  <bjoern@hoehrmann.de>
    Re: Email::MIME not decoding '8bit' but it looks as if  <rweikusat@mssgmbh.com>
    Re: Email::MIME not decoding '8bit' but it looks as if  <ben@morrow.me.uk>
    Re: Email::MIME not decoding '8bit' but it looks as if  <news@lawshouse.org>
    Re: Email::MIME not decoding '8bit' but it looks as if  <news@lawshouse.org>
    Re: Model Centric Perl Web Framework <ilias@lazaridis.com>
        Parse using Text::CSV into Hash <poo@pee.com>
    Re: Parse using Text::CSV into Hash <jimsgibson@gmail.com>
    Re: Parse using Text::CSV into Hash <glex_no-spam@qwest-spam-no.invalid>
    Re: Parse using Text::CSV into Hash <news@lawshouse.org>
    Re: Parse using Text::CSV into Hash <ben@morrow.me.uk>
    Re: Parse using Text::CSV into Hash <rweikusat@mssgmbh.com>
    Re: Parse using Text::CSV into Hash <ben@morrow.me.uk>
    Re: Parse using Text::CSV into Hash <nospam.gravitalsun@hotmail.com.nospam>
    Re: Parse using Text::CSV into Hash <news@lawshouse.org>
    Re: Parse using Text::CSV into Hash <justin.1104@purestblue.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Thu, 10 Nov 2011 06:20:37 -0800 (PST)
From: Dilbert <dilbert1999@gmail.com>
Subject: ActiveState Perl and MinGW [was: Perl 5.14 Windows Strawberry Perl 64 bits]
Message-Id: <79a218dc-3248-4705-8100-f1925f1a5f45@w3g2000vbw.googlegroups.com>

On 24 mai, 17:56, Dilbert <dilbert1999@gmail.com> wrote:
> On 17 mai, 11:18, Dilbert <dilbert1999@gmail.com> wrote:
>
> > Any clues as to where to find either:
> > - Perl 5.14 WindowsStrawberryPerl 64 bits
>
> looking athttp://strawberryperl.com/,
> it displays "Expected SOON: Perl 5.14.0"
> I can't wait... :-)

On 24 mai, 17:56, Dilbert <dilbert1999@gmail.com> wrote:
> On 17 mai, 11:18, Dilbert <dilbert1999@gmail.com> wrote:
>
> > Any clues as to where to find either:
> > - Perl 5.14 WindowsStrawberryPerl 64 bits
>
> looking athttp://strawberryperl.com/,
> it displays "Expected SOON: Perl 5.14.0"
> I can't wait... :-)

looking at http://strawberryperl.com/,
it now displays "Stop Press! Perl 5.14 preview release available now!"
The wait is over :-)


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

Date: Thu, 10 Nov 2011 06:16:16 -0800 (PST)
From: Dilbert <dilbert1999@gmail.com>
Subject: ActiveState Perl and MinGW [was: Perl 5.14 Windows Strawberry Perl 64 bits]
Message-Id: <7ee1c51d-239f-4bf1-92e0-bd953f39c7bc@o13g2000vbo.googlegroups.com>

On 24 mai, 17:56, Dilbert <dilbert1999@gmail.com> wrote:
> On 17 mai, 11:18, Dilbert <dilbert1999@gmail.com> wrote:
>
> > Any clues as to where to find either:
> > - Perl 5.14 WindowsStrawberryPerl 64 bits
>
> looking athttp://strawberryperl.com/,
> it displays "Expected SOON: Perl 5.14.0"
> I can't wait... :-)

On 24 mai, 17:56, Dilbert <dilbert1999@gmail.com> wrote:
> On 17 mai, 11:18, Dilbert <dilbert1999@gmail.com> wrote:
>
> > Any clues as to where to find either:
> > - Perl 5.14 WindowsStrawberryPerl 64 bits
>
> looking athttp://strawberryperl.com/,
> it displays "Expected SOON: Perl 5.14.0"
> I can't wait... :-)

looking at http://strawberryperl.com/,
it now displays "Stop Press! Perl 5.14 preview release available now!"
The wait is over :-)


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

Date: Fri, 11 Nov 2011 12:14:41 +0000
From: Henry Law <news@lawshouse.org>
Subject: Email::MIME not decoding '8bit' but it looks as if it ought to
Message-Id: <Lt6dnfEL1Y8vjCDTnZ2dnUVZ8uGdnZ2d@giganews.com>

I have an application which uses Email::MIME extensively.  Most of my 
mail items have Content-Transfer-Encoding of '7bit' or 
'quoted-printable' but there are a few with '8bit'.  With these messages 
Email::MIME barfs with the message 'Don't know how to decode 8bit', 
which actually comes from Email::MIME::Encodings.

But Email::MIME::Encodings quite clearly contains code which handles 
8bit in the same way as 7bit.  Here's an example:

   sub identity { $_[0] }

   for (qw(7bit 8bit binary)) {
       *{"encode_$_"} = *{"decode_$_"} = \&identity;
   }

 ... although I must say that this code goes beyond my knowledge of Perl; 
I can't see what it does, or work out how.

Has anyone any experience with decoding 8bit-encoded messages using 
Email::MIME, which could possibly help me find out what's wrong?

PS the "Don't know how to decode" message comes up with zero hits in 
Google.  Searching for "Email::MIME" and "8bit" just gives the module's 
POD (which also mentions 8bit, without any reservation).

-- 

Henry Law            Manchester, England


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

Date: Fri, 11 Nov 2011 18:14:41 +0100
From: Bjoern Hoehrmann <bjoern@hoehrmann.de>
Subject: Re: Email::MIME not decoding '8bit' but it looks as if it ought to
Message-Id: <hflqb7d2conjqa0vegucsakm17c3b5f5v6@hive.bjoern.hoehrmann.de>

* Henry Law wrote in comp.lang.perl.misc:
>I have an application which uses Email::MIME extensively.  Most of my 
>mail items have Content-Transfer-Encoding of '7bit' or 
>'quoted-printable' but there are a few with '8bit'.  With these messages 
>Email::MIME barfs with the message 'Don't know how to decode 8bit', 
>which actually comes from Email::MIME::Encodings.
>
>But Email::MIME::Encodings quite clearly contains code which handles 
>8bit in the same way as 7bit.  Here's an example:
>
>   sub identity { $_[0] }
>
>   for (qw(7bit 8bit binary)) {
>       *{"encode_$_"} = *{"decode_$_"} = \&identity;
>   }

This manipulates the symbol table so that there are functions like
`decode_8bit(...)` which do the same thing as the `identity` sub,
return the first argument passed to them or undef if none is passed.
The module croaks because the package can't decode_8bit, but since
the sub is installed, there is no obvious reason for that. Perhaps
running the script with `perl -MCarp=verbose example.pl` might help?
It should give you a calltrace which might be useful if there is an
inheritance related problem for instance. Running the script in the
debugger would be my next option.
-- 
Björn Höhrmann · mailto:bjoern@hoehrmann.de · http://bjoern.hoehrmann.de
Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/ 


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

Date: Fri, 11 Nov 2011 17:17:40 +0000
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: Email::MIME not decoding '8bit' but it looks as if it ought to
Message-Id: <877h36y3wr.fsf@sapphire.mobileactivedefense.com>

Henry Law <news@lawshouse.org> writes:
> I have an application which uses Email::MIME extensively.  Most of my
> mail items have Content-Transfer-Encoding of '7bit' or
> quoted-printable' but there are a few with '8bit'.  With these
> messages Email::MIME barfs with the message 'Don't know how to decode
> 8bit', which actually comes from Email::MIME::Encodings.

The current version of Email::MIME does not contain this message.

> But Email::MIME::Encodings quite clearly contains code which handles
> 8bit in the same way as 7bit.  Here's an example:
>
>   sub identity { $_[0] }
>
>   for (qw(7bit 8bit binary)) {
>       *{"encode_$_"} = *{"decode_$_"} = \&identity;
>   }
>
> ... although I must say that this code goes beyond my knowledge of
> Perl; I can't see what it does, or work out how.

It creates Perl subroutines named encode_7bit, encode_8bit,
encode_binary and decode_ ... by assignig a subroutine reference to
the corresponding globs (symbol table entries)[*]. Since none of the
three is an actual encoding, this subroutine does nothing but return
its argument.

[*] Example:

----------------
my $sub = sub { return 3; };

print $sub->(), "\n";

*three = $sub;
print three(), "\n";
----------------


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

Date: Fri, 11 Nov 2011 11:51:02 -0600
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Email::MIME not decoding '8bit' but it looks as if it ought to
Message-Id: <buidnT5Hrfob_SDTnZ2dnUVZ8nSdnZ2d@bt.com>


Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
> Henry Law <news@lawshouse.org> writes:
> > I have an application which uses Email::MIME extensively.  Most of my
> > mail items have Content-Transfer-Encoding of '7bit' or
> > quoted-printable' but there are a few with '8bit'.  With these
> > messages Email::MIME barfs with the message 'Don't know how to decode
> > 8bit', which actually comes from Email::MIME::Encodings.
> 
> The current version of Email::MIME does not contain this message.

No, but the current version of Email::MIME::Encodings *does* contain

    Carp::croak("Don't know how to $which $how");

> > But Email::MIME::Encodings quite clearly contains code which handles
> > 8bit in the same way as 7bit.  Here's an example:
> >
> >   sub identity { $_[0] }
> >
> >   for (qw(7bit 8bit binary)) {
> >       *{"encode_$_"} = *{"decode_$_"} = \&identity;
> >   }
> >
> > ... although I must say that this code goes beyond my knowledge of
> > Perl; I can't see what it does, or work out how.

Others have explained what this bit of code does. As for why it isn't
working, it's hard to say since you didn't provide a program and input
that fails. This program

    #!/opt/perl/bin/perl

    use 5.010;
    use warnings;
    use strict;

    use Email::MIME;
    use File::Slurp "slurp";

    my $msg = slurp \*DATA;
    my $m = Email::MIME->new($msg);
    say $m->body;
    say $m->header("Content-Transfer-Encoding");
    say "$_: ". $_->VERSION for qw/Email::MIME Email::MIME::Encodings/;

    __END__
    From: <ben@morrow.me.uk>
    To: <ben@morrow.me.uk>
    Subject: Hello world!
    Content-type: text/plain
    Content-transfer-encoding: 8bit

    foobar

for me, gives

    foobar

    8bit
    Email::MIME: 1.906
    Email::MIME::Encodings: 1.313

Ben



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

Date: Fri, 11 Nov 2011 17:57:26 +0000
From: Henry Law <news@lawshouse.org>
Subject: Re: Email::MIME not decoding '8bit' but it looks as if it ought to
Message-Id: <q5GdnXMjALea_yDTnZ2dnUVZ7omdnZ2d@giganews.com>

On 11/11/11 17:17, Rainer Weikusat wrote:
> It creates Perl subroutines named encode_7bit, encode_8bit,

 ... and Björn Höhrmann said much the same.

I'm grateful to both of you for this insight into the symbol table.  I 
ran the thing in the debugger and, ahem, found that the problem lies in 
a malformed message in the MBOX-format mail file (which was generated 
externally and saved to disk by Thunderbird), which causes 
Email::MIME::Encodings to be asked to decode not "8bit" but "8bit plus 
the complete contents of the following line"; needless to say it refuses 
to do so.  I've learned a lot, but I hope you two don't feel too much of 
your time has been wasted.

I think if I'd been writing Email::MIME::Encodings I'd have used a null 
return, or some such, rather than croaking right there in the module. 
It's not polite for modules to croak.

-- 

Henry Law            Manchester, England


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

Date: Fri, 11 Nov 2011 18:00:27 +0000
From: Henry Law <news@lawshouse.org>
Subject: Re: Email::MIME not decoding '8bit' but it looks as if it ought to
Message-Id: <neqdnb-OXYIm_yDTnZ2dnUVZ8qWdnZ2d@giganews.com>

On 11/11/11 17:51, Ben Morrow wrote:

> Others have explained what this bit of code does. As for why it isn't
> working, it's hard to say since you didn't provide a program and input
> that fails. This program

Thanks, Ben.  I understand what you're saying, especially since I posted 
quite recently advising another poster to do just the same.  But in my 
defence I was actually asking for people's experience in decoding "8bit" 
(looking for "well it works for me", or alternatively "Oh yes, that's a 
known limitation").

Had I set out to prepare the minimal program, though, I should almost 
certainly have found the source of the error, which is in the data 
format as explained in my other follow-up post.  Hmmm.

-- 

Henry Law            Manchester, England


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

Date: Thu, 10 Nov 2011 22:01:39 -0800 (PST)
From: Ilias Lazaridis <ilias@lazaridis.com>
Subject: Re: Model Centric Perl Web Framework
Message-Id: <2a6afb4a-f67b-4451-a2e3-21dbc85b3f14@j10g2000vbe.googlegroups.com>

On 8 =CE=9D=CE=BF=CE=AD, 13:40, Ben Morrow <b...@morrow.me.uk> wrote:
> Quoth Ilias Lazaridis <il...@lazaridis.com>:
>
> > On 7 =CE=9D=CE=BF=CE=AD, 03:22, Ben Morrow <b...@morrow.me.uk> wrote:
>
> > > Perhaps what you want is Catalyst::Model::KiokuDB? I've never used it=
,
> > > with or without Catalyst[0], but Florian (who appears to be the curre=
nt
> > > maintainer) certainly knows what he's doing.
>
> > ok, will take a look.
>
> > Maybe I ask a different way: which existent framework (or ORM) come
> > nearest to "Model-Centric"?
>
> As I said, I don't know. It's not a property I would consider desirable,
> so it's not something I've looked into.

ok

> > > [0] and probably wouldn't want to. IMHO if you're using an RDBMS just=
 to
> > > serialise a handful of objects you're wasting it: the whole point of =
SQL
> > > is it lets you ask questions you weren't expecting when you put the d=
ata
> > > in the database. If all the important bits are stuffed into blobs you
> > > might as well have been using BDB or something simple like that from =
the
> > > start. (In fact, I see KiokuDB supports BDB as a backend...)
>
> > I want to use an sql db, in order to be able to switch to other
> > frameworks, languages etc.
>
> Well, in that case, don't you want to put a bit more thought into
> designing the DB schema properly?
[...]

No, want to write classes, and get the rest done. Just as within an
OODBMS. I use ORM/SQL just because those OODBMS systems are not that
much available.

Thank you for your for your answers.

--
http://lazaridis.com


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

Date: Thu, 10 Nov 2011 10:57:35 -0500
From: batrams <poo@pee.com>
Subject: Parse using Text::CSV into Hash
Message-Id: <j9gs9g$e1r$1@dont-email.me>

Hi guys - this hunk of code seems to function as intended. After I get 
code to work I'm often curious to run it by you gurus to see how you 
might have done it. Please don't laugh too hard but any comments are 
welcome.




open (TEXTFILE, "USES.txt") || die "not found\n";
my $csv = Text::CSV->new();

while ( <TEXTFILE> ) {
     $csv->parse($_);
     push(@H_USES, [$csv->fields]);
    }
close(TEXTFILE);

# load up the hash
for my  $i ( 0 ..  $#H_USES ) {
$H_USES{$H_USES[$i][0]} = $H_USES[$i];
}




DB


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

Date: Thu, 10 Nov 2011 09:32:16 -0800
From: Jim Gibson <jimsgibson@gmail.com>
Subject: Re: Parse using Text::CSV into Hash
Message-Id: <101120110932160508%jimsgibson@gmail.com>

In article <j9gs9g$e1r$1@dont-email.me>, batrams <poo@pee.com> wrote:

> Hi guys - this hunk of code seems to function as intended. After I get 
> code to work I'm often curious to run it by you gurus to see how you 
> might have done it. Please don't laugh too hard but any comments are 
> welcome.
> 
> 
> 
> 
> open (TEXTFILE, "USES.txt") || die "not found\n";

Lexical variables with lower-case names are better than package globals
in uppercase. The 'or' operator had better precedence for this use than
'||'. It is always good to include the open error ($!) in the die
message. I would usually put the file name in a scalar variable and
include that in the error message as well.

See the examples in the documentation for Text::CSV for a better style
of programming to read in a text file.

> my $csv = Text::CSV->new();
> 
> while ( <TEXTFILE> ) {
>      $csv->parse($_);
>      push(@H_USES, [$csv->fields]);

I would use lower-case variable names, and I always include the
parentheses for function/subroutine/method calls ($csv->fields()), even
if they are not required, as it gives me a better clue of what is going
on. 

You should always 'use strict;' and declare your variables.

>     }
> close(TEXTFILE);
> 
> # load up the hash
> for my  $i ( 0 ..  $#H_USES ) {
> $H_USES{$H_USES[$i][0]} = $H_USES[$i];
> }

Loops should be indented, and the integer index is not needed:

for my $row ( @H_USES ) {
  $H_USES{$row->[0]} = $row;
}

But I would populate the hash in the while loop, rather than in a
separate loop afterwards.

-- 
Jim Gibson


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

Date: Thu, 10 Nov 2011 19:10:04 +0000
From: "J. Gleixner" <glex_no-spam@qwest-spam-no.invalid>
Subject: Re: Parse using Text::CSV into Hash
Message-Id: <4ebc218c$0$63194$815e3792@news.qwest.net>

On 11/10/11 15:57, batrams wrote:
> Hi guys - this hunk of code seems to function as intended. After I get
> code to work I'm often curious to run it by you gurus to see how you
> might have done it. Please don't laugh too hard but any comments are
> welcome.

If you want a hash, see the getline_hr method.



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

Date: Thu, 10 Nov 2011 19:15:32 +0000
From: Henry Law <news@lawshouse.org>
Subject: Re: Parse using Text::CSV into Hash
Message-Id: <cq2dndelyPBIvyHTnZ2dnUVZ8sidnZ2d@giganews.com>

On 10/11/11 15:57, batrams wrote:
> might have done it. Please don't laugh too hard but any comments are
snip
> open (TEXTFILE, "USES.txt") || die "not found\n";
> my $csv = Text::CSV->new();
>
> while ( <TEXTFILE> ) {
> $csv->parse($_);
> push(@H_USES, [$csv->fields]);
> }
> close(TEXTFILE);
>
> # load up the hash
> for my $i ( 0 .. $#H_USES ) {
> $H_USES{$H_USES[$i][0]} = $H_USES[$i];
> }

An interesting exercise.  I'm no guru but doing stuff like this helps me 
too.  Building on Jim Gibson's comments I came up with this, which is 
shorter and (I think) more "Perl-ish" than yours.

#! /usr/bin/perl
use strict;
use warnings;
use Text::CSV;
use Data::Dumper;

open (TEXTFILE, "USES.txt") or die "Couldn't open 'USES.txt': $!";
my $csv = Text::CSV->new();

my %h_uses;
my $rowref;

$h_uses{$rowref->[0]} = [@$rowref]
   while $rowref = $csv->getline(\*TEXTFILE);
close(TEXTFILE);

print Dumper(\%h_uses);

With a data file of
   1,2,3,4
   A,B,C,D

it produces
$VAR1 = {
           'A' => [
                    'A',
                    'B',
                    'C',
                    'D'
                  ],
           '1' => [
                    '1',
                    '2',
                    '3',
                    '4'
                  ]
         };
 ... which is what yours produced.

-- 

Henry Law            Manchester, England


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

Date: Thu, 10 Nov 2011 16:14:44 -0600
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Parse using Text::CSV into Hash
Message-Id: <NMydnb-hOehJ0SHTnZ2dnUVZ7qudnZ2d@bt.com>


Quoth Henry Law <news@lawshouse.org>:
> 
> An interesting exercise.  I'm no guru but doing stuff like this helps me 
> too.  Building on Jim Gibson's comments I came up with this, which is 
> shorter and (I think) more "Perl-ish" than yours.
> 
> #! /usr/bin/perl
> use strict;
> use warnings;
> use Text::CSV;
> use Data::Dumper;
> 
> open (TEXTFILE, "USES.txt") or die "Couldn't open 'USES.txt': $!";

Jim already mentioned, but since you didn't notice:

    my $file = "USES.txt";
    open (my $TEXTFILE, "<", $file)
        or die "Couldn't open '$file': $!\n";

The only important improvement here is the 'my $TEXTFILE'. Bareword
filehandles are always global (in fact, a bareword handle like TEXTFILE
is just a shortcut for *TEXTFILE, as you saw below), and globals are
better avoided where you can.

The other changes are:

    - Keeping the filename in a variable. In a trivial program like this
      it makes little difference, but you've already written the name
      twice so DRY say you should put it in a variable.

    - Using 3-arg open. Again, with a known constant string as the
      filename it makes no difference, but it's a good habit to get into
      for when someone passes you ">/etc/passwd" and you open it without
      checking.

    - I put back the "\n" on the die message: file and line are useful
      for a programmer, and should be left in on messages you don't
      expect to ever see in production, but messages addressed to the
      end user don't want them.

> my $csv = Text::CSV->new();
> 
> my %h_uses;
> my $rowref;
> 
> $h_uses{$rowref->[0]} = [@$rowref]
>    while $rowref = $csv->getline(\*TEXTFILE);

One advantage of lexical filehandles is it removes the need for the ugly
\*FH syntax. You also don't need to deref and re-ref the array you got
from ->getline.

    $h_uses{$rowref->[0]} = $rowref
        while $rowref = $csv->getline($TEXTFILE);

(I don't entirely like having to predeclare $rowref, to the point where
I would consider writing this

    while (my $rowref = $csv->getline($TEXTFILE)) {
        $h_uses{$rowref->[0]} = $rowref;
    }

instead.)

> close(TEXTFILE);

Another advantage of lexical filehandles is they auto-close when they go
out of scope. It's risky taking advantage of this if you have written to
the handle: in that case you should be calling close explicitly and
checking the return value. If you're *not* going to check the return
value, and for read-only handles there's no point, you don't need to
call close either.

Ben



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

Date: Thu, 10 Nov 2011 22:39:32 +0000
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: Parse using Text::CSV into Hash
Message-Id: <87r51f1u1n.fsf@sapphire.mobileactivedefense.com>

Ben Morrow <ben@morrow.me.uk> writes:

[...]

>     open (my $TEXTFILE, "<", $file)
>         or die "Couldn't open '$file': $!\n";

[...]

>     - I put back the "\n" on the die message: file and line are useful
>       for a programmer, and should be left in on messages you don't
>       expect to ever see in production, but messages addressed to the
>       end user don't want them.

The end-user is going to report the problem as "It crashed" no matter
what actually occurred and any information said end-user can just
copy&paste into an e-mail is possibly helpful to the person who is
supposed to deal with the issue.

[...]

>> close(TEXTFILE);
>
> Another advantage of lexical filehandles is they auto-close when they go
> out of scope. It's risky taking advantage of this if you have written to
> the handle: in that case you should be calling close explicitly and
> checking the return value.

Or so the Linux close(2) manpage claims. The reason it does this is
because data written to a file residing on a NFS filesystem (and
possibly, other network file systems) isn't necessarily sent to the
server until the (NFS) filehandle is closed. Because of this, the
return value of a close of such a file may be some error which ocurred
during network communication. For practical purpose, this is often
irrelevant and - much more importantly - checking the return value of
the close doesn't help except if reporting "This didn't work. Bad for
you!" is considered to be useful. Programs which care about the
integrity of data written to some persistent medium, at least to the
degree this is possible, need to use fsync before closing the file and
need to implement some strategy for dealing with errors returned by
that (for Perl, this means invoking IO::Handle::flush, followed by
IO::Handle::Sync).

The actual write operation can actually fail after close returned
success even for local files.


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

Date: Thu, 10 Nov 2011 18:22:39 -0600
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Parse using Text::CSV into Hash
Message-Id: <V8WdnR9b-ZhS9yHTnZ2dnUVZ8nSdnZ2d@bt.com>


Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
> Ben Morrow <ben@morrow.me.uk> writes:
> 
> >     open (my $TEXTFILE, "<", $file)
> >         or die "Couldn't open '$file': $!\n";
> 
> >     - I put back the "\n" on the die message: file and line are useful
> >       for a programmer, and should be left in on messages you don't
> >       expect to ever see in production, but messages addressed to the
> >       end user don't want them.
> 
> The end-user is going to report the problem as "It crashed" no matter
> what actually occurred and any information said end-user can just
> copy&paste into an e-mail is possibly helpful to the person who is
> supposed to deal with the issue.

You are certainly right for a large (and important) class of end-users.
Programs aimed at such people should, as you say, simply give a message
saying 'there was a problem' plus some way to send someone competent a
logfile with as much detailed information as possible.

However, command-line programs written in Perl (probably on a Unix
system) are generally not run by those users. They are run by people
like you and me, people who would actually appreciate a message like
'could not open 'foo/bar': Not a directory', but probably wouldn't
appreciate knowing that this happened on line 213 of
/usr/local/lib/perl5/site_perl/5.12.4/Foo/Bar.pm.

Look at the error messages given by the standard Unix utilities. They
(usually) do include filenames and strerror messages, but very rarely
include __FILE__ and __LINE__ information. The notable exception is
'panic'-type messages, which are always addressed to the developer of
the utility rather than the user.

> >> close(TEXTFILE);
> >
> > Another advantage of lexical filehandles is they auto-close when they go
> > out of scope. It's risky taking advantage of this if you have written to
> > the handle: in that case you should be calling close explicitly and
> > checking the return value.
> 
> Or so the Linux close(2) manpage claims. The reason it does this is
> because data written to a file residing on a NFS filesystem (and
> possibly, other network file systems) isn't necessarily sent to the
> server until the (NFS) filehandle is closed. Because of this, the
> return value of a close of such a file may be some error which ocurred
> during network communication.

You don't need to go anywhere near that far. PerlIO (and stdio in C)
buffers writes, so when you call close (that is, the equivalent of
fclose(3), not close(2)) there is still a partial bufferful of data
which hasn't been sent to the kernel yet. If that write(2) gives an
error, that error will be returned from close. Additionally, close will
return an error if *any* of the previous writes failed (unless you call
IO::Handle->clearerr), so checking the return value of close means you
don't need to check the return value of print.

> For practical purpose, this is often
> irrelevant and - much more importantly - checking the return value of
> the close doesn't help except if reporting "This didn't work. Bad for
> you!" is considered to be useful.

It is. Always. It's better to *know* something failed, and have some
idea as to why, than to think it succeeded when it didn't.

> Programs which care about the integrity of data written to some
> persistent medium, at least to the degree this is possible, need to
> use fsync before closing the file and need to implement some strategy
> for dealing with errors returned by that (for Perl, this means
> invoking IO::Handle::flush, followed by IO::Handle::Sync).

Yes, if you have strict integrity requirements simply checking close
isn't enough. It does guard against the two most common causes of error,
though: disk full (or quota exceeded) and network failure.

> The actual write operation can actually fail after close returned
> success even for local files.

If you're talking about the likes of softupdates then I believe any
reasonable filesystem will only lose data after returning success in the
event of a system crash or an unrecoverable disk failure.

(FWIW, POSIX says that as soon as write(2) returns success the data
should be in the file and should be returned by subsequent reads. It
also leaves fsync(2) largely unspecified, explicitly allowing a null
implementation for systems that cannot guarantee data integrity across a
system crash.)

Ben



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

Date: Fri, 11 Nov 2011 09:18:38 +0200
From: "George Mpouras" <nospam.gravitalsun@hotmail.com.nospam>
Subject: Re: Parse using Text::CSV into Hash
Message-Id: <j9ii71$2303$1@news.ntua.gr>

my %H_USES;
while (<DATA>) {
$_=[split ','];$H_USES{$_->[0]}=$_
}

use Data::Dumper; print Dumper(\%H_USES);

__DATA__
a1,b1,c1,d1
a2,b2,c2,d2
a3,b3,c3,d3
a3,b3,c3,d3 




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

Date: Fri, 11 Nov 2011 09:07:48 +0000
From: Henry Law <news@lawshouse.org>
Subject: Re: Parse using Text::CSV into Hash
Message-Id: <vaadnXpfgNl4eCHTnZ2dnUVZ8tKdnZ2d@giganews.com>

On 11/11/11 07:18, George Mpouras wrote:
> my %H_USES;
> while (<DATA>) {
> $_=[split ','];$H_USES{$_->[0]}=$_
> }

This is trivially true for the sample data files we've all been using 
but is not a general solution.  If it were always as easy as this then 
we wouldn't need Text::CSV.

For a start, the OP didn't say that the data items were comma-separated; 
follow-ups have assumed it for convenience because with Text::CSV you 
can easily allow for other separation schemes.  And what about imbedded 
separator characters, escaped in some fashion?  Some applications -- 
Excel being a good example -- will put text fields in double quotes but 
leave numerics bare; Text::CSV will handle that too.

-- 

Henry Law            Manchester, England


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

Date: Fri, 11 Nov 2011 10:14:01 +0000
From: Justin C <justin.1104@purestblue.com>
Subject: Re: Parse using Text::CSV into Hash
Message-Id: <949vo8-rna.ln1@zem.masonsmusic.co.uk>

On 2011-11-10, Ben Morrow <ben@morrow.me.uk> wrote:

[snip]

> The only important improvement here is the 'my $TEXTFILE'. Bareword
> filehandles are always global

Hey! And there's the answer to a question I was going to post! Couldn't
figure our why I had to pass a sub a ref to a hash from the calling
hash, but it figured out the FH all by itself. Now I know... and I know
why not to do it too. TY!

[snip]

   Justin.

-- 
Justin C, by the sea.


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

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 3540
***************************************


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