[32250] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 3517 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Oct 11 06:14:25 2011

Date: Tue, 11 Oct 2011 03:14:10 -0700 (PDT)
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, 11 Oct 2011     Volume: 11 Number: 3517

Today's topics:
        Questions re using Require <Joey@still_Learning.invalid>
    Re: Questions re using Require <ben@morrow.me.uk>
    Re: Questions re using Require <Joey@still_Learning.invalid>
    Re: Questions re using Require <ben@morrow.me.uk>
    Re: Questions re using Require <Joey@still_Learning.invalid>
        Tie::File <bigus@fakedomain.fake>
    Re: Tie::File <news@lawshouse.org>
        Tricky STDERR issue under windows philkime@kime.org.uk
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Mon, 10 Oct 2011 11:08:22 -0700
From: "Joey@still_Learning.invalid" <Joey@still_Learning.invalid>
Subject: Questions re using Require
Message-Id: <rnc69791lafq2mt7atb086b2h6btrbsefi@4ax.com>

My web application produces three slightly different versions of the same
page, so I think I want to use 'Require' to import a lot of the common
code for all three pages. A couple of questions:

1. Do I put the 'require' statement in the script at the place I want to
import the code, or can it be placed at the start of the script?

2. Two of the three pages print the contents to the screen (e.g., print
"content\n";), but the third page prints the contents to a file, e.g.,
print tfile "content\n", although some of the third page also prints to
the screen.

Is it somehow possible to use Require for all three pages? How do I
account for writing content to the file?
-- 
Joey


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

Date: Mon, 10 Oct 2011 17:57:34 -0500
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Questions re using Require
Message-Id: <ipGdnVfLbYHD5Q7TnZ2dnUVZ8m6dnZ2d@bt.com>


Quoth "Joey@still_Learning.invalid" <Joey@still_Learning.invalid>:
> My web application produces three slightly different versions of the same
> page, so I think I want to use 'Require' to import a lot of the common
> code for all three pages. A couple of questions:
> 
> 1. Do I put the 'require' statement in the script at the place I want to
> import the code, or can it be placed at the start of the script?

The important thing to realise about require is that it will only load
any given file once. This means you don't know if 'require "file.pl"'
will actually do anything, or if file.pl will have been loaded already.
This means you have to arrange file.pl so that it doesn't matter exactly
when it gets run: the usual thing to do is to put sub definitions in
that file, which you can then call when you need to from the requiring
file.

(If you don't know about subs yet, I would recommend you learn them
before you start thinking about require.)

For instance, if you have

    -- page1.pl

    print "<h1>My Website</h1>";
    print "<h2>Page 1</h2>";

    -- page2.pl

    print "<h1>My Website</h1>";
    print "<h2>Page 2</h2>";

you could simplify this like this:

    -- common.pl

    sub common_header {
        print "<h1>My Website</h1>";
    }

    -- page1.pl

    require "common.pl";

    common_header();
    print "<h2>Page 1</h2>";

and similarly for page2.pl.

> 2. Two of the three pages print the contents to the screen (e.g., print
> "content\n";), but the third page prints the contents to a file, e.g.,
> print tfile "content\n", although some of the third page also prints to

I deduce from your use of 'print tfile' that you're using bareword
filehandles rather than keeping them in variables. This is a bad idea,
because it's very easy, once your program gets a little larger, to find
you've accidentally used 'tfile' in two different parts of the program
to refer to different files.

So, instead of opening your files like this:

    open(tfile, ">", "output.html")

open them like this

    open(my $tfile, ">", "output.html")

> the screen.
> 
> Is it somehow possible to use Require for all three pages? How do I
> account for writing content to the file?

There are basically three options here:

    - pass your common subs a filehandle to print to;
    - use select() to specify the filehandle implicitly;
    - have your subs return a string instead of printing it.

The third option is usually the best, unless you're dealing with
gigabytes of data. For completeness I'll show you them all here.

Passing a filehandle

    -- common.pl

    sub common_header {
        my ($filehandle) = @_;
        print $filehandle "<h1>My Website</h1>";
    }

    -- page1.pl

    require "common.pl";

    common_header(*STDOUT);
    print "<h2>Page 1</h2>";

    -- page3.pl

    require "common.pl";
    open(my $tfile, ">", "output.html");

    common_header($tfile);
    print $tfile "<h2>Page 3</h2>";

Notice the * in front of STDOUT. This is because STDOUT is a global
bareword filehandle, so you have to treat it specially if you're going
to use it somewhere Perl isn't expecting to see a filehandle. This is
another reason to avoid them in favour of proper variables, though
unfortunately STDIN, STDOUT and STDERR are always global barewords.

Using select:

    -- common.pl

    sub common_header {
        print "<h1>My Website</h1>";
    }

    -- page1.pl

    require "common.pl";

    common_header();
    print "<h2>Page 1</h2>";

    -- page3.pl

    require "common.pl";
    open my $tfile, ">", "output.html";
    select $tfile;

    common_header();
    print "<h2>Page 3</h2>";

'print' without a filehandle argument prints to the currently selected
filehandle, so you can make it print somewhere else using 'select'.

Returning a string:

    -- common.pl

    sub common_header {
        return "<h1>My Website</h1>";
    }

    -- page1.pl

    require "common.pl";

    print common_header();
    print "<h2>Page 1</h2>";

    -- page3.pl

    require "common.pl";
    open my $tfile, ">", "output.html";

    print $tfile common_header();
    print $tfile "<h2>Page 3</h2>";

Although it may seem like a little more work in this very simple case
(since you have to explicitly print the results rather than letting the
sub do it for you) it's actually much more flexible.

Ben



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

Date: Mon, 10 Oct 2011 16:22:44 -0700
From: "Joey@still_Learning.invalid" <Joey@still_Learning.invalid>
Subject: Re: Questions re using Require
Message-Id: <ofv697lllfpkbeqv8ar16de2sla9ji6n4d@4ax.com>

Ben Morrow wrote:

>
>Quoth "Joey@still_Learning.invalid" <Joey@still_Learning.invalid>:
>> My web application produces three slightly different versions of the same
>> page, so I think I want to use 'Require' to import a lot of the common
>> code for all three pages. A couple of questions:
>> 
>> 1. Do I put the 'require' statement in the script at the place I want to
>> import the code, or can it be placed at the start of the script?
>
>The important thing to realise about require is that it will only load
>any given file once. This means you don't know if 'require "file.pl"'
>will actually do anything, or if file.pl will have been loaded already.
>This means you have to arrange file.pl so that it doesn't matter exactly
>when it gets run: the usual thing to do is to put sub definitions in
>that file, which you can then call when you need to from the requiring
>file.
>
>(If you don't know about subs yet, I would recommend you learn them
>before you start thinking about require.)
>
>For instance, if you have
>
>    -- page1.pl
>
>    print "<h1>My Website</h1>";
>    print "<h2>Page 1</h2>";
>
>    -- page2.pl
>
>    print "<h1>My Website</h1>";
>    print "<h2>Page 2</h2>";
>
>you could simplify this like this:
>
>    -- common.pl
>
>    sub common_header {
>        print "<h1>My Website</h1>";
>    }
>
>    -- page1.pl
>
>    require "common.pl";
>
>    common_header();
>    print "<h2>Page 1</h2>";
>
>and similarly for page2.pl.
>
>> 2. Two of the three pages print the contents to the screen (e.g., print
>> "content\n";), but the third page prints the contents to a file, e.g.,
>> print tfile "content\n", although some of the third page also prints to
>
>I deduce from your use of 'print tfile' that you're using bareword
>filehandles rather than keeping them in variables. This is a bad idea,
>because it's very easy, once your program gets a little larger, to find
>you've accidentally used 'tfile' in two different parts of the program
>to refer to different files.
>
>So, instead of opening your files like this:
>
>    open(tfile, ">", "output.html")
>
>open them like this
>
>    open(my $tfile, ">", "output.html")
>
>> the screen.
>> 
>> Is it somehow possible to use Require for all three pages? How do I
>> account for writing content to the file?
>
>There are basically three options here:
>
>    - pass your common subs a filehandle to print to;
>    - use select() to specify the filehandle implicitly;
>    - have your subs return a string instead of printing it.
>
>The third option is usually the best, unless you're dealing with
>gigabytes of data. For completeness I'll show you them all here.
>
>Passing a filehandle
>
>    -- common.pl
>
>    sub common_header {
>        my ($filehandle) = @_;
>        print $filehandle "<h1>My Website</h1>";
>    }
>
>    -- page1.pl
>
>    require "common.pl";
>
>    common_header(*STDOUT);
>    print "<h2>Page 1</h2>";
>
>    -- page3.pl
>
>    require "common.pl";
>    open(my $tfile, ">", "output.html");
>
>    common_header($tfile);
>    print $tfile "<h2>Page 3</h2>";
>
>Notice the * in front of STDOUT. This is because STDOUT is a global
>bareword filehandle, so you have to treat it specially if you're going
>to use it somewhere Perl isn't expecting to see a filehandle. This is
>another reason to avoid them in favour of proper variables, though
>unfortunately STDIN, STDOUT and STDERR are always global barewords.
>
>Using select:
>
>    -- common.pl
>
>    sub common_header {
>        print "<h1>My Website</h1>";
>    }
>
>    -- page1.pl
>
>    require "common.pl";
>
>    common_header();
>    print "<h2>Page 1</h2>";
>
>    -- page3.pl
>
>    require "common.pl";
>    open my $tfile, ">", "output.html";
>    select $tfile;
>
>    common_header();
>    print "<h2>Page 3</h2>";
>
>'print' without a filehandle argument prints to the currently selected
>filehandle, so you can make it print somewhere else using 'select'.
>
>Returning a string:
>
>    -- common.pl
>
>    sub common_header {
>        return "<h1>My Website</h1>";
>    }
>
>    -- page1.pl
>
>    require "common.pl";
>
>    print common_header();
>    print "<h2>Page 1</h2>";
>
>    -- page3.pl
>
>    require "common.pl";
>    open my $tfile, ">", "output.html";
>
>    print $tfile common_header();
>    print $tfile "<h2>Page 3</h2>";
>
>Although it may seem like a little more work in this very simple case
>(since you have to explicitly print the results rather than letting the
>sub do it for you) it's actually much more flexible.
>
Thanks so very much for taking the time to provide such a comprehensive
and helpful assist. Much appreciated. I get it!
-- 
Joey


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

Date: Mon, 10 Oct 2011 19:00:01 -0500
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Questions re using Require
Message-Id: <84-dnUPgdoacGg7TnZ2dnUVZ7oOdnZ2d@bt.com>


Quoth "Joey@still_Learning.invalid" <Joey@still_Learning.invalid>:
> Ben Morrow wrote:
[something quite long]
> 
> Thanks so very much for taking the time to provide such a comprehensive
> and helpful assist. Much appreciated. I get it!

While thanks are always appreciated, you didn't really need to quote the
whole of my reply to say them.

Ben



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

Date: Mon, 10 Oct 2011 17:30:51 -0700
From: "Joey@still_Learning.invalid" <Joey@still_Learning.invalid>
Subject: Re: Questions re using Require
Message-Id: <pc37975r5613b4v69hrb0ai118bac5579q@4ax.com>

Ben Morrow wrote:

>While thanks are always appreciated, you didn't really need to quote the
>whole of my reply to say them.
>
Heh! The last time I said thanks to someone I clipped the post, as you
would have it. I was soundly criticized for it. I've learned that when it
comes to c.l.p.m., do as you think best, but get ready for someone to
bitch about it, no matter what you do. :-))
-- 
Joey


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

Date: Mon, 10 Oct 2011 19:20:35 +0100
From: Bigus <bigus@fakedomain.fake>
Subject: Tie::File
Message-Id: <%HGkq.7522$ZQ7.18@newsfe09.iad>

Hi All

I am trying to read a 120GB XML file using Tie::File. However, it 
doesn't open and die produces the error:

"Invalid argument"

I have tried reading a small 3KB XML file and it works fine.

Are there any limitations on file size with Tie::File?

Regards
Bigus


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

Date: Mon, 10 Oct 2011 22:06:35 +0100
From: Henry Law <news@lawshouse.org>
Subject: Re: Tie::File
Message-Id: <0bedndcdHtbEww7TnZ2dnUVZ8sadnZ2d@giganews.com>

On 10/10/11 19:20, Bigus wrote:
> Are there any limitations on file size with Tie::File?

Here's a web page that might give you some insight.

http://www.google.com/search?q=%22tie%3A%3AFile%22+size&hl=en

-- 

Henry Law            Manchester, England


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

Date: Tue, 11 Oct 2011 00:47:51 -0700 (PDT)
From: philkime@kime.org.uk
Subject: Tricky STDERR issue under windows
Message-Id: <14788059.1670.1318319271711.JavaMail.geo-discussion-forums@yqai1>

I seem to have hit a rather tricky issue with STDERR redirection and librar=
ies used via XS and wonder if anybody has any ideas.

I have an XS module which uses an external library. This library uses stdio=
, not PerlIO and can't be changed. I need to capture STDERR that this libra=
ry outputs. This can't be done using PerlIO tricks like opening to an in me=
mory scalar I realise. On non-windows, I can redirect STDERR to a file and =
read it in later when the library calls are finished. This works fine. On w=
indows, it doesn't work because apparently, as soon as you re-open STDERR t=
o a file, it decouples the library STDERR from perl's STDERR and the librar=
y continues to write to its own STDERR and it seems impossible to capture i=
t.

Example below. On non-Windows, the STDERR from the library comes between th=
e "|" characters as it should. On Windows, it comes after "||" as it's not =
captured. Any ideas on how to capture this?

#!/bin/perl
use Text::BibTeX;
use Capture::Tiny qw(capture);
my $stderr;

my $bib_entry =3D <<'END';
@BOOK{test1,
  AUTHOR =3D {Arthur Author},
  TITLE  =3D {Arranging Arguments},,
  YEAR   =3D {1935}
}
END

my ($stdout, $stderr) =3D capture {
  my $entry =3D new Text::BibTeX::Entry $bib_entry;
};

print "|$stderr|\n";

exit 0;


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

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


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