[11345] in Perl-Users-Digest
Perl-Users Digest, Issue: 4945 Volume: 8
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri Feb 19 20:07:24 1999
Date: Fri, 19 Feb 99 17:00:21 -0800
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, 19 Feb 1999 Volume: 8 Number: 4945
Today's topics:
Re: Can anyone convert this VB script to Perl? (win32:: (Jan Dubois)
Re: Can perl read a www page <tchrist@mox.perl.com>
Re: converting a standard number to a currency-like num <tchrist@mox.perl.com>
DOC: Examples galore <tchrist@mox.perl.com>
Re: Executing a Program <tchrist@mox.perl.com>
FAQ 8.25: How can I capture STDERR from an external com <perlfaq-suggestions@perl.com>
FAQ 8.27: What's wrong with using backticks in a void c <perlfaq-suggestions@perl.com>
Re: how do you find if a string contains something?? <tchrist@mox.perl.com>
Re: MKDIR <tchrist@mox.perl.com>
My, oh my! cory@techlounge.com
Re: Perl Editors for WinNT? <tchrist@mox.perl.com>
Re: Problems with Win32::OLE and MSWord in Office 97 (Jan Dubois)
SRC: # pgrep -- grep out all programs whose basenames m <tchrist@mox.perl.com>
SRC: symirror - build spectral forest of symlinks (was: <tchrist@mox.perl.com>
Streams, Subroutines, FileHandles jp@dkstat.com
Re: Streams, Subroutines, FileHandles <tchrist@mox.perl.com>
Re: String Manipulation (yet another newbie question) asssi@my-dejanews.com
Re: String Manipulation (yet another newbie question) asssi@my-dejanews.com
Special: Digest Administrivia (Last modified: 12 Dec 98 (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Sat, 20 Feb 1999 01:12:05 +0100
From: jan.dubois@ibm.net (Jan Dubois)
Subject: Re: Can anyone convert this VB script to Perl? (win32::ole)
Message-Id: <36cff5ce.11787088@news3.ibm.net>
[mailed & posted]
Richard.Mayston@mfat.govt.nz wrote:
>I've got a bit further
General remark: Please run your script with "perl -w". Not only Perl itself
but also the Win32::OLE module will give you much better error messages. It
might also be a good idea to use "use strict".
>
>use Win32::ole;
Should be (all names including package names are case sensitive):
use Win32::OLE;
>$LogonName = "Richard Mayston";
>$objSession = Win32::OLE->new('MAPI.Session', \&OleQuit) or die "Oops, cannot
>start MAPI.Session: $!";
I'm assuming your OleQuit function only issues the Quit command. Then you
can write it more easily as follows:
$objSession = Win32::OLE->new('MAPI.Session', 'Quit')
or die "Oops, cannot start MAPI.Session: ".Win32::OLE->LastError;
Please note that $! typically doesn't contain the last OLE error but
something completely unrelated. Use Win32::OLE->LastError to inspect the
last OLE error code.
>die "Logon: $!" if $objSession->Logon($LogonName);
die "Logon: ".Win32::OLE->LastError if $objSession->Logon($LogonName);
>$objMsgColl = $objSession->Inbox.Messages;
$objMsgColl = $objSession->Inbox->Messages;
>$cUnread=0;
>$objMessage = $objMsgColl.GetFirst;
$objMessage = $objMsgColl->GetFirst;
>while (defined($objMessage)){
> if ($objMessage.Unread){
if ($objMessage->Unread){
> $cUnread++;
> }
> $objMessage = $objMsgColl.GetNext;
$objMessage = $objMsgColl->GetNext;
> print "test: cUnread=$cUnread\tobjMessage=$objMessage\n";
> #test: cUnread=786
>#objMessage=Win32::OLE=HASH(0x10cd9fc)MessagesGetNext
>}
>print "Unread messages = $cUnread\n";
>
>
>But $objMessage is never undefined & the unread count goes forever!.
>Anything obvious wrong?
See my comments above. You can *never* use the dot operator in Perl to
access methods or properties; the dot always means string concatenation.
For this type of problem you normally get better responses on the
Perl-Win32-Users mailing list at ActiveState.com.
-Jan
------------------------------
Date: 19 Feb 1999 17:40:20 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: Can perl read a www page
Message-Id: <36ce0474@csnews>
[courtesy cc of this posting sent to cited author via email]
In comp.lang.perl.misc, chinh@catbert.ucdavis.edu (Chinh Lam) writes:
:Hello, I was wondering if there was way in perl to grab a web page
:off a remote server through the http protocol and store it on the
:computer that is running the script?
Somehow you appear to have missed the proper answer when you studiously
searched the standard Perl documentation on your very own system.
It was there waiting for you.
% man perlfaq9
...
How do I fetch an HTML file?
One approach, if you have the lynx text-based HTML browser installed
on your system, is this:
$html_code = `lynx -source $url`;
$text_data = `lynx -dump $url`;
The libwww-perl (LWP) modules from CPAN provide a more powerful way
to do this. They work through proxies, and don't require lynx:
# simplest version
use LWP::Simple;
$content = get($URL);
# or print HTML from a URL
use LWP::Simple;
getprint "http://www.sn.no/libwww-perl/";
# or print ASCII from HTML from a URL
# also need HTML-Tree package from CPAN
use LWP::Simple;
use HTML::Parse;
use HTML::FormatText;
my ($html, $ascii);
$html = get("http://www.perl.com/");
defined $html
or die "Can't fetch HTML from http://www.perl.com/";
$ascii = HTML::FormatText->new->format(parse_html($html));
print $ascii;
How do I automate an HTML form submission?
If you're submitting values using the GET method, create a URL and
encode the form using the `query_form' method:
use LWP::Simple;
use URI::URL;
my $url = url('http://www.perl.com/cgi-bin/cpan_mod');
$url->query_form(module => 'DB_File', readme => 1);
$content = get($url);
If you're using the POST method, create your own user agent and
encode the content appropriately.
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
$ua = LWP::UserAgent->new();
my $req = POST 'http://www.perl.com/cgi-bin/cpan_mod',
[ module => 'DB_File', readme => 1 ];
$content = $ua->request($req)->as_string;
--tom
--
"The most merciful thing in this world, I think, is the inability of
the human mind to correlate all its contents..."
--H.P. Lovecraft, from "The Call of Cthulhu", 1926.
------------------------------
Date: 19 Feb 1999 17:29:01 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: converting a standard number to a currency-like number
Message-Id: <36ce01cd@csnews>
[courtesy cc of this posting sent to cited author via email]
In comp.lang.perl.misc,
Peter Richmond <peter@richmd.demon.co.uk> writes:
:Sorry if the subject is not clear. Here is the problem...
:I have a numerical value: 2474911568
:And i need to convert it into: 2,474,911,568
Somehow you appear to have missed the proper answer when you studiously
searched the standard Perl documentation on your very own system.
It was there waiting for you.
$ man perlfaq4
...
How can I output my numbers with commas added?
This one will do it for you:
sub commify {
local $_ = shift;
1 while s/^(-?\d+)(\d{3})/$1,$2/;
return $_;
}
$n = 23659019423.2331;
print "GOT: ", commify($n), "\n";
GOT: 23,659,019,423.2331
You can't just:
s/^(-?\d+)(\d{3})/$1,$2/g;
because you have to put the comma in and then recalculate your position.
Alternatively, this commifies all numbers in a line regardless of whether
they have decimal portions, are preceded by + or -, or whatever:
# from Andrew Johnson <ajohnson@gpu.srv.ualberta.ca>
sub commify {
my $input = shift;
$input = reverse $input;
$input =~ s<(\d\d\d)(?=\d)(?!\d*\.)><$1,>g;
return reverse $input;
}
--tom
--
Let's say the docs present a simplified view of reality... :-)
--Larry Wall in <6940@jpl-devvax.JPL.NASA.GOV>
------------------------------
Date: 19 Feb 1999 16:43:11 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: DOC: Examples galore
Message-Id: <36cdf70f@csnews>
Innumerable examples, including many I have been posting here, can be
found at:
A semi-random assortment of various programs I've written:
http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/
All the code, both examples and full programs, from the Perl Cookbook:
ftp://ftp.oreilly.com/published/oreilly/perl/cookbook/pcookexamples.tar.gz
--tom
--
if (*name == '+' && len > 1 && name[len-1] != '|') { /* scary */
--Larry Wall, from doio.c in the v5.0 perl distribution
------------------------------
Date: 19 Feb 1999 16:23:31 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: Executing a Program
Message-Id: <36cdf273@csnews>
[courtesy cc of this posting sent to cited author via email]
In comp.lang.perl.misc,
"nullspace" <nullspace@hotmail.com> writes:
:So far, I can do (1) and (3) but I'm having trouble with the code for
:running the compiled program from my script. I thought it was the exec("
:/test/a.out & ") command. It works to a point. The program runs but anything
:after that call in my perl script doesn't get reached. I thought that there
:must be a way to find out if a.out has finished but I just don't know the
:proper code. Any help would definitely be appreciated. Thanks!!
Somehow you appear to have missed the proper answer when you studiously
searched the standard Perl documentation on your very own system.
It was there waiting for you.
% man perlfaq8
...
How come exec() doesn't return?
Because that's what it does: it replaces your currently running program
with a different one. If you want to keep going (as is probably the
case if you're asking this question) use system() instead.
It was also posted today. Sigh.
--tom
--
"Most of what I've learned over the years has come from signatures."
--Larry Wall
------------------------------
Date: 19 Feb 1999 16:34:32 -0700
From: Tom Christiansen <perlfaq-suggestions@perl.com>
Subject: FAQ 8.25: How can I capture STDERR from an external command?
Message-Id: <36cdf508@csnews>
(This excerpt from perlfaq8 - System Interaction
($Revision: 1.36 $, $Date: 1999/01/08 05:36:34 $)
part of the standard set of documentation included with every
valid Perl distribution, like the one on your system.
See also http://language.perl.com/newdocs/pod/perlfaq8.html
if your negligent system adminstrator has been remiss in his duties.)
How can I capture STDERR from an external command?
There are three basic ways of running external commands:
system $cmd; # using system()
$output = `$cmd`; # using backticks (``)
open (PIPE, "cmd |"); # using open()
With system(), both STDOUT and STDERR will go the same place as the
script's versions of these, unless the command redirects them. Backticks
and open() read only the STDOUT of your command.
With any of these, you can change file descriptors before the call:
open(STDOUT, ">logfile");
system("ls");
or you can use Bourne shell file-descriptor redirection:
$output = `$cmd 2>some_file`;
open (PIPE, "cmd 2>some_file |");
You can also use file-descriptor redirection to make STDERR a duplicate
of STDOUT:
$output = `$cmd 2>&1`;
open (PIPE, "cmd 2>&1 |");
Note that you *cannot* simply open STDERR to be a dup of STDOUT in your
Perl program and avoid calling the shell to do the redirection. This
doesn't work:
open(STDERR, ">&STDOUT");
$alloutput = `cmd args`; # stderr still escapes
This fails because the open() makes STDERR go to where STDOUT was going
at the time of the open(). The backticks then make STDOUT go to a
string, but don't change STDERR (which still goes to the old STDOUT).
Note that you *must* use Bourne shell (sh(1)) redirection syntax in
backticks, not csh(1)! Details on why Perl's system() and backtick and
pipe opens all use the Bourne shell are in
http://www.perl.com/CPAN/doc/FMTEYEWTK/versus/csh.whynot . To capture a
command's STDERR and STDOUT together:
$output = `cmd 2>&1`; # either with backticks
$pid = open(PH, "cmd 2>&1 |"); # or with an open pipe
while (<PH>) { } # plus a read
To capture a command's STDOUT but discard its STDERR:
$output = `cmd 2>/dev/null`; # either with backticks
$pid = open(PH, "cmd 2>/dev/null |"); # or with an open pipe
while (<PH>) { } # plus a read
To capture a command's STDERR but discard its STDOUT:
$output = `cmd 2>&1 1>/dev/null`; # either with backticks
$pid = open(PH, "cmd 2>&1 1>/dev/null |"); # or with an open pipe
while (<PH>) { } # plus a read
To exchange a command's STDOUT and STDERR in order to capture the STDERR
but leave its STDOUT to come out our old STDERR:
$output = `cmd 3>&1 1>&2 2>&3 3>&-`; # either with backticks
$pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&-|");# or with an open pipe
while (<PH>) { } # plus a read
To read both a command's STDOUT and its STDERR separately, it's easiest
and safest to redirect them separately to files, and then read from
those files when the program is done:
system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr");
Ordering is important in all these examples. That's because the shell
processes file descriptor redirections in strictly left to right order.
system("prog args 1>tmpfile 2>&1");
system("prog args 2>&1 1>tmpfile");
The first command sends both standard out and standard error to the
temporary file. The second command sends only the old standard output
there, and the old standard error shows up on the old standard out.
--
On Monday mornings I am dedicated to the proposition that all men are
created jerks.
--H. Allen Smith, "Let the Crabgrass Grow"
------------------------------
Date: 19 Feb 1999 17:46:10 -0700
From: Tom Christiansen <perlfaq-suggestions@perl.com>
Subject: FAQ 8.27: What's wrong with using backticks in a void context?
Message-Id: <36ce05d2@csnews>
(This excerpt from perlfaq8 - System Interaction
($Revision: 1.36 $, $Date: 1999/01/08 05:36:34 $)
part of the standard set of documentation included with every
valid Perl distribution, like the one on your system.
See also http://language.perl.com/newdocs/pod/perlfaq8.html
if your negligent system adminstrator has been remiss in his duties.)
What's wrong with using backticks in a void context?
Strictly speaking, nothing. Stylistically speaking, it's not a good way
to write maintainable code because backticks have a (potentially
humungous) return value, and you're ignoring it. It's may also not be
very efficient, because you have to read in all the lines of output,
allocate memory for them, and then throw it away. Too often people are
lulled to writing:
`cp file file.bak`;
And now they think "Hey, I'll just always use backticks to run
programs." Bad idea: backticks are for capturing a program's output; the
system() function is for running programs.
Consider this line:
`cat /etc/termcap`;
You haven't assigned the output anywhere, so it just wastes memory (for
a little while). Plus you forgot to check `$?' to see whether the
program even ran correctly. Even if you wrote
print `cat /etc/termcap`;
In most cases, this could and probably should be written as
system("cat /etc/termcap") == 0
or die "cat program failed!";
Which will get the output quickly (as its generated, instead of only at
the end) and also check the return value.
system() also provides direct control over whether shell wildcard
processing may take place, whereas backticks do not.
--
"A ship then new they built for him/of mithril and of elven glass"
--Larry Wall in perl.c from the v5.0 perl distribution,
citing Bilbo from Tolkien's Lord of the Rings trilogy
------------------------------
Date: 19 Feb 1999 16:39:36 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: how do you find if a string contains something??
Message-Id: <36cdf638@csnews>
In comp.lang.perl.misc, sads (screwed up addess) writes:
:im new to perl and i wanna know how i could figure out if a host
:address (bou-058.dorm.uml.edu) contains "uml.edu" ??
The index() function is used to search for one string within
another. This is in the fine perlfunc manpage on your system.
Please consult it.
--tom
--
If I had only known, I would have been a locksmith. --Albert Einstein
------------------------------
Date: 19 Feb 1999 17:45:11 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: MKDIR
Message-Id: <36ce0597@csnews>
[courtesy cc of this posting sent to cited author via email]
In comp.lang.perl.misc, gward@cnri.reston.va.us (Greg Ward) writes:
: mkdir ($TMPDATA, 0755);
Don't use 0755 unless you really mean it. The normal mask
for non-executable files is 0666, and for directories, 0777.
Remember that (mode &~ umask) is final permissions. You want
to let the users make their own choices. That's what the umask
is *for*, after all.
Exceptions to this rule are privacy-related files, like mail
files or browser (choke) cookies.
--tom
--
I can't change the way people talk,
but I can damn well complain about it.
--David Casseres in <28542@goofy.Apple.COM>
------------------------------
Date: Sat, 20 Feb 1999 00:45:01 GMT
From: cory@techlounge.com
Subject: My, oh my!
Message-Id: <7al0ia$kvb$1@nnrp1.dejanews.com>
I keep having problems with my and use in my perl scripts.
my ($a, $b, $c) = @_;
use CGI qw (:standard);
use CGI::Carp qw(fatalsToBrowser);
Each of these lines gives me a syntax error. Why?
Thanks,
Cory
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
------------------------------
Date: 19 Feb 1999 17:43:12 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: Perl Editors for WinNT?
Message-Id: <36ce0520@csnews>
[courtesy cc of this posting sent to cited author via email]
In comp.lang.perl.misc,
ns-am528@chebucto.ns.ca (H.A.) writes:
:I'm just starting on Perl and I do most of my programming on WinNT. I hate
:using Notpad for programming.
You poor guy. There are free ports available of the standard
programmer's editors, vi and emacs, even to monopolistic, tool-challenged,
consumer-oriented systems such as the one you have been cursed with.
Search alta vista. You may have to get "vim" for vi.
--tom
--
"I find this a nice feature but it is not according to the documentation.
Or is it a BUG?"
"Let's call it an accidental feature. :-)" Larry Wall in <6909@jpl-devvax.JPL.NASA.GOV>
------------------------------
Date: Sat, 20 Feb 1999 01:12:11 +0100
From: jan.dubois@ibm.net (Jan Dubois)
Subject: Re: Problems with Win32::OLE and MSWord in Office 97
Message-Id: <36d1fa22.12895963@news3.ibm.net>
[mailed & posted]
gdmiller@wave.home.com wrote:
>Hi all, if you can help with this it will be greatly appreciated.
I'll add some general comments too, although they are most probably not
relevant to your problem. I think your problem might be the order of
destruction of objects. This would most easily be fixed by making all
variables lexicals and removing the explicit undef-ing.
Please run your program under "perl -w", which will give you much better
Win32::OLE error messages!
>eval {$ex = Win32::OLE->GetActiveObject('Word.Application')}; die "Word not
>installed" if $@; unless (defined $ex) { $ex =
>Win32::OLE->new('Word.Application', sub {$_[0]->Quit;}) or die "Oops, cannot
>start Word"; }
You could write this as:
$ex = Win32::OLE->new('Word.Application', 'Quit')
or die "Oops, cannot start Word";
>
>foreach $file (@files) {
> $dirname=dirname($file);
> $file = $snapview."\\$file";
> $file =~ s(\\)(\\\\)g;
> $finalloc = $pdffileloc.$dirname;
> $basename=basename($file,".doc");
> $ex->SetProperty('Visible',0);
> $ex->SetProperty('DisplayAlerts',0);
The SetProperty() method is only necessary for properties that take values.
Hash reference syntax is more readable otherwise:
$ex->{Visible} = 0;
$ex->{DisplayAlerts} = 0;
In this case I would recommend to use the with() function. You have to
explicitly request it with:
use Win32::OLE qw(with);
and then write here:
with($ex, Visible => 0, DisplayAlerts => 0);
You should also move these global settings out of the loop; you only have to
do them once.
> $ex->SetProperty('wdAlertLevel',0);
> $ex->SetProperty('wdSaveOptions', 0);
I'm pretty sure the two lines above don't do what you think they do. I
believe they are errors, because the Application object doesn't have
wdAlertLevel and wdSaveOptions properties. BTW, the wdXXXX constants are not
strings but integer constants. Read the Win32::OLE::Const documentation to
find out how to import and use them!
> $doc = $ex->Documents->Open($file);
> $subdocs = $doc->Subdocuments;
> $subdocs->SetProperty('Expanded',1);
my $doc = $ex->Documents->Open($file);
my $subdocs = $doc->Subdocuments;
$subdocs->{Expanded} = 1;
> $ex->SetProperty('ActivePrinter', "\\\\ott100\\HPOTT004PS on NE00");
> $ex->ActiveDocument->PrintOut(0,
> 0,
> "",
> "$pstempfileloc$basename.ps");
># $ex->Quit();
> undef $doc;
Don't undef $Doc here. Word might not like it that you are still hanging on
to a reference to the Subdocuments collection. Either undef $subdocs first,
or make the variables lexicals, as I have done above and let Perl handle the
destruction.
# undef $doc;
> copy ("$pstempfileloc$basename.ps","$distillerin$basename.ps") or die
>"Cannot copy file\n";
> while( -e "$distillerin$basename.ps"){}
> mkpath ([$finalloc]);
> copy ("$distillerout$basename.pdf", "$finalloc\\$basename.pdf") or die
>"Cannot copy file\n";
>}
>undef $ex;
Instead of the "undef $ex;" here I would prefer a "my $ex;" at the top.
-Jan
------------------------------
Date: 19 Feb 1999 16:47:16 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: SRC: # pgrep -- grep out all programs whose basenames match given pattern
Message-Id: <36cdf804@csnews>
Example:
$ pgrep grep
/home/tchrist/scripts/angelgrep
/home/tchrist/scripts/igrep
/home/tchrist/scripts/nigrep
/home/tchrist/scripts/pgrep
/home/tchrist/scripts/tcgrep
/home/tchrist/scripts/tgrep
/home/tchrist/scripts/psgrep
/usr/local/devperl/bin/podgrep
/usr/local/bin/agrep
/bin/egrep
/bin/fgrep
/bin/grep
/usr/bin/zgrep
/usr/bin/zipgrep
/usr/bin/rgrep
/usr/bin/gitrgrep
/usr/bin/gitregrep
/usr/bin/gitrfgrep
/usr/bin/gitxgrep
Source code:
#!/usr/bin/perl
# pgrep -- grep out all programs whose basenames match given pattern
chop($cwd = `pwd`) unless $cwd = $ENV{'PWD'};
$regexp = shift || die "usage: $0 regexp\n";
for $dir (split(/:/,$ENV{'PATH'})) {
chdir($dir =~ m#^/# ? $dir : "$cwd/$dir") || next;
opendir(DOT, '.') || next;
while ($_ = readdir(DOT)) {
next unless /$regexp/o;
next unless -f;
next unless -x _;
print "$dir/$_\n";
}
}
That was optimized for speed, not legibility.
--tom
--
The software required `Windows 95 or better', so I installed Linux.
------------------------------
Date: 19 Feb 1999 16:38:07 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: SRC: symirror - build spectral forest of symlinks (was: Problem w/ Recursive functions)
Message-Id: <36cdf5df@csnews>
[courtesy cc of this posting sent to cited author via email]
In comp.lang.perl.misc,
"Jalil Feghhi" <jalil@corp.home.net> writes:
: while($file = <${from}>){
Yes another "I forgot to read the FAQ" posting.
Is that all this newsgroup is for? Sheesh.
$ man perlfaq5
...
Is there a leak/bug in glob()?
Due to the current implementation on some operating systems,
when you use the glob() function or its angle-bracket alias in a
scalar context, you may cause a leak and/or unpredictable behavior.
It's best therefore to use glob() only in list context.
The workaround is to use
my @files = glob($from);
for my $file (@files) {
}
Of course, most people just use
system("cp -r from to");
Hm... while I'm on the topic, why are recreating the wheel? Even if
you are like CP/M saddled and intend to whinge at me in vain about the
perfectly functional use of cp -r, you still shouldn't be rewriting
the find module.
Here's a demo of a program recursively *duplicates* a directory tree,
making a shadow forest full of symlinks pointing back at the real files.
#!/usr/bin/perl -w
# symirror - build spectral forest of symlinks
use strict;
use File::Find;
use Cwd;
my ($srcdir, $dstdir);
my $cwd = getcwd();
die "usage: $0 realdir mirrordir" unless @ARGV == 2;
for (($srcdir, $dstdir) = @ARGV) {
my $is_dir = -d;
next if $is_dir; # cool
if (defined ($is_dir)) {
die "$0: $_ is not a directory\n";
} else { # be forgiving
mkdir($dstdir, 07777) or die "can't mkdir $dstdir: $!";
}
} continue {
s#^(?!/)#$cwd/#; # fix relative paths
}
chdir $srcdir;
find(\&wanted, '.');
sub wanted {
my($dev, $ino, $mode) = lstat($_);
my $name = $File::Find::name;
$mode &= 07777; # preserve directory permissions
$name =~ s!^\./!!; # correct name
if (-d _) { # then make a real directory
mkdir("$dstdir/$name", $mode)
or die "can't mkdir $dstdir/$name: $!";
} else { # shadow everything else
symlink("$srcdir/$name", "$dstdir/$name")
or die "can't symblink $srcdir/$name to $dstdir/$name: $!";
}
}
--tom
--
echo "I can't find the O_* constant definitions! You got problems."
--The Configure script from the perl distribution
------------------------------
Date: Fri, 19 Feb 1999 23:55:55 GMT
From: jp@dkstat.com
Subject: Streams, Subroutines, FileHandles
Message-Id: <7aktm6$ik9$1@nnrp1.dejanews.com>
Hello all:
I would like to pass two different subroutines something like a file handle,
which represents the output from a database. And have each of the subroutines
simultaneoulsy process the "stream" of data.
Any Ideas?
The equivelent of
$dbh = query();
open(F,$dbh->dump);
sub1(F);
sub2(F);
sub1 {
my FH = shift;
while(<FH>)
...;
}
sub2...like sub1
ciao jp
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
------------------------------
Date: 19 Feb 1999 17:23:56 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: Streams, Subroutines, FileHandles
Message-Id: <36ce009c@csnews>
[courtesy cc of this posting sent to cited author via email]
In comp.lang.perl.misc,
jp@dkstat.com writes:
:I would like to pass two different subroutines something like a file handle,
:which represents the output from a database. And have each of the subroutines
:simultaneoulsy process the "stream" of data.
Somehow you appear to have missed the proper answer when you studiously
searched the standard Perl documentation on your very own system.
It was there waiting for you.
Apparently you've missed my very recently posted FMTEYEWTK on Indirect
Filehandles.
Apparently you've also missed my very recently posted answer to this
FAQ. Time to play it again, I guess.
Hope this helps.
$ man perlfaq5
...
How can I use a filehandle indirectly?
An indirect filehandle is using something other than a symbol in a
place that a filehandle is expected. Here are ways to get those:
$fh = SOME_FH; # bareword is strict-subs hostile
$fh = "SOME_FH"; # strict-refs hostile; same package only
$fh = *SOME_FH; # typeglob
$fh = \*SOME_FH; # ref to typeglob (bless-able)
$fh = *SOME_FH{IO}; # blessed IO::Handle from *SOME_FH typeglob
Or to use the new method from the FileHandle or IO modules to create
an anonymous filehandle, store that in a scalar variable, and use it
as though it were a normal filehandle.
use FileHandle;
$fh = FileHandle->new();
use IO::Handle; # 5.004 or higher
$fh = IO::Handle->new();
Then use any of those as you would a normal filehandle. Anywhere
that Perl is expecting a filehandle, an indirect filehandle may be
used instead. An indirect filehandle is just a scalar variable that
contains a filehandle. Functions like print, open, seek, or the <FH>
diamond operator will accept either a real filehandle or a scalar
variable containing one:
($ifh, $ofh, $efh) = (*STDIN, *STDOUT, *STDERR);
print $ofh "Type it: ";
$got = <$ifh>
print $efh "What was that: $got";
If you're passing a filehandle to a function, you can write the
function in two ways:
sub accept_fh {
my $fh = shift;
print $fh "Sending to indirect filehandle\n";
}
Or it can localize a typeglob and use the filehandle directly:
sub accept_fh {
local *FH = shift;
print FH "Sending to localized filehandle\n";
}
Both styles work with either objects or typeglobs of real filehandles.
(They might also work with strings under some circumstances, but this
is risky.)
accept_fh(*STDOUT);
accept_fh($handle);
In the examples above, we assigned the filehandle to a scalar variable
before using it. That is because only simple scalar variables, not
expressions or subscripts into hashes or arrays, can be used with
built-ins like print, printf, or the diamond operator. These are
illegal and won't even compile:
@fd = (*STDIN, *STDOUT, *STDERR);
print $fd[1] "Type it: "; # WRONG
$got = <$fd[0]> # WRONG
print $fd[2] "What was that: $got"; # WRONG
With print and printf, you get around this by using a block and an
expression where you would place the filehandle:
print { $fd[1] } "funny stuff\n";
printf { $fd[1] } "Pity the poor %x.\n", 3_735_928_559;
# Pity the poor deadbeef.
That block is a proper block like any other, so you can put more
complicated code there. This sends the message out to one of two
places:
$ok = -x "/bin/cat";
print { $ok ? $fd[1] : $fd[2] } "cat stat $ok\n";
print { $fd[ 1+ ($ok || 0) ] } "cat stat $ok\n";
This approach of treating print and printf like object methods calls
doesn't work for the diamond operator. That's because it's a real
operator, not just a function with a comma-less argument. Assuming
you've been storing typeglobs in your structure as we did above, you
can use the built-in function named readline to reads a record just
as <> does. Given the initialization shown above for @fd, this would
work, but only because readline() require a typeglob. It doesn't work
with objects or strings, which might be a bug we haven't fixed yet.
$got = readline($fd[0]);
Let it be noted that the flakiness of indirect filehandles is not
related to whether they're strings, typeglobs, objects, or anything
else. It's the syntax of the fundamental operators. Playing the
object game doesn't help you at all here.
--tom
--
Randal said it would be tough to do in sed. He didn't say he didn't
understand sed. Randal understands sed quite well. Which is why he
uses Perl. :-) -- Larry Wall in <7874@jpl-devvax.JPL.NASA.GOV>
------------------------------
Date: Sat, 20 Feb 1999 00:39:27 GMT
From: asssi@my-dejanews.com
Subject: Re: String Manipulation (yet another newbie question)
Message-Id: <7al07u$kqp$1@nnrp1.dejanews.com>
> Someone else responded with a regex solution. I think a better approach
> to your particular problem is the 'index' function:
>
> if (index($field, '_1') >= 0) { ...
>
> (As a habit, use single quotes for string literals unless you want
> interpolation of variables or interpretation of backslash escape
> sequences.)
>
Thanks Larry!
It really helped alot,
I took from my university library the book called programming perl for the
weekend, But I'll have to return it soon..
any idea for a complete reference of the language (functions, structures etc.)
online? i tried www.perl.com but didn't seem to find anything like that there.
Thanks again.
Asi.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
------------------------------
Date: Sat, 20 Feb 1999 00:42:47 GMT
From: asssi@my-dejanews.com
Subject: Re: String Manipulation (yet another newbie question)
Message-Id: <7al0e5$kuj$1@nnrp1.dejanews.com>
> > I think it should exist FOREVER. Backward compatibilityn, you know the
> > drill. It is deprecated to *change* it, however. You preferably should
> > always use the default value for it (= 0).
>
> Agreed. And that's why I think that Tad McClellan's using $[ to answer
> a simple post (instead of just 0, as I did earlier :-) is pointless
> pedantry and potentially misleading.
>
> Leave $[ in the language forever, but politely ignore its existence!
Hey, didn't mean to start a fight here *wink*
anyways, i'll use >0, i have no idea about what $[ is about :)
Asssi
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
------------------------------
Date: 12 Dec 98 21:33:47 GMT (Last modified)
From: Perl-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Special: Digest Administrivia (Last modified: 12 Dec 98)
Message-Id: <null>
Administrivia:
Well, after 6 months, here's the answer to the quiz: what do we do about
comp.lang.perl.moderated. Answer: nothing.
]From: Russ Allbery <rra@stanford.edu>
]Date: 21 Sep 1998 19:53:43 -0700
]Subject: comp.lang.perl.moderated available via e-mail
]
]It is possible to subscribe to comp.lang.perl.moderated as a mailing list.
]To do so, send mail to majordomo@eyrie.org with "subscribe clpm" in the
]body. Majordomo will then send you instructions on how to confirm your
]subscription. This is provided as a general service for those people who
]cannot receive the newsgroup for whatever reason or who just prefer to
]receive messages via e-mail.
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.misc (and this Digest), send your
article to perl-users@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.
The Meta-FAQ, an article containing information about the FAQ, is
available by requesting "send perl-users meta-faq". The real FAQ, as it
appeared last in the newsgroup, can be retrieved with the request "send
perl-users FAQ". Due to their sizes, neither the Meta-FAQ nor the FAQ
are included in the digest.
The "mini-FAQ", which is an updated version of the Meta-FAQ, is
available by requesting "send perl-users mini-faq". It appears twice
weekly in the group, but is not distributed in the digest.
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 V8 Issue 4945
**************************************