Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

hash n' params

by ybiC (Prior)
on Apr 07, 2001 at 18:57 UTC ( #70715=perlquestion: print w/replies, xml ) Need Help??
ybiC has asked for the wisdom of the Perl Monks concerning the following question:

Monks whose opinions I respect have suggested a couple things to improve the quality of my scripts:
  1. use hash values instead of buckets o' scalar vars
  2. simplify subroutines by passing parameters properly

This ditty is a result of re-reading through merlyn's Llama and danger's EoPwP toward that end.   Have I got the right idea, or am I fullabeans?

P.S. Please ignore the fact that the following code is nothing more than a wrapper around 3 system calls.   Is mostly an exercise in learning a bit more Perl.   Using CPAN modules HTML::FormatPS and HTML::FormatText is on the Todos list {g}

#!/usr/bin/perl -w # # pod at tail use strict; use Cwd 'chdir'; my $dir = '~/'; my %exec = (); $exec{html2ps} = '/usr/bin/html2ps'; $exec{ps2pdf} = '/usr/bin/ps2pdf'; $exec{html2text} = '~/perl/html2text'; my %file = (); $file{rc} = '~/.html2psrc'; $file{html} = "$dir/original.html"; $file{tmp} = 'generated.tmp'; $file{ps} = ''; $file{pdf} = 'generated.pdf'; $file{txt} = 'generated.txt'; my @exists = @file{'rc', 'html'}; my @unlink = @file{'tmp', 'ps', 'pdf', 'txt'}; my @outfiles = @file{'ps', 'pdf', 'txt'}; print ("\nStarting $0 run.\n\n"); chdir "$dir" or die "Error chdir to $dir: $!"; foreach my $exec (values(%exec)) { &FILECHECK($exec, 'die'); } &FILECHECK($file{html}, 'die'); &FILECHECK($file{rc}, 'warn'); print "Ready to unlink prior ps, pdf, and txt files.\n"; print "<enter> to continue, ctrl+c to abort."; <STDIN>; foreach my $unlink(@unlink) { if (-e $unlink && -w _) { unlink $unlink or die "Error unlinking $unlink: $!"; } } system ("$exec{html2ps} -F $file{html} > $file{ps}") and die "Error running $exec{html2ps}: $!"; system ("$exec{ps2pdf} $file{ps} $file{pdf}") and die "Error running $exec{ps2pdf}: $!"; system ("$exec{html2text} < $file{html} > $file{tmp}") and die "Error running $exec{html2text}: $!"; open (TMP, "< $file{tmp}") or die "Error opening $file{tmp} RO: $!"; open (TEXT, "> $file{txt}") or die "Error opening $file{txt} WO: $!"; while (<TMP>) { s/&nbsp;/ /g; s/ / /g; print TEXT; } close TMP or die "Error closing $file{tmp}: $!"; close TEXT or die "Error closing $file{txt}: $!"; unlink $file{tmp} or die "Error unlinking $file{tmp}: $!"; print "\nCompleted $0 run.\n"; print " Original HTML file at:\n"; print " $file{html}\n"; print " Generated files at:\n"; foreach my $outfile (@outfiles) { print " $dir/$outfile\n"; } print ("\n"); ############################################### sub FILECHECK { my $file = $_[0]; my $ooot = $_[1]; unless (-e $file) { if ($ooot eq 'die') { die "\nError: $file not found where specified.\n\n"; } elsif ($ooot eq 'warn') { warn "\nCaution: $file not found where specified.\n"; } } } ############################################### =head1 Name =head1 Description Generates PostScript+PDF+text files from existing HTML. Insert <!--NewPage--> as needed in original.html then run this script +. html2ps does not handle frames, tables, or images in original HTML. =head1 Changelog 2001-04-07 07:20 Hashified variables Sub'd+parameterized filecheck 2001-04-05 Initial working Perl code 2001-04-03 Simple Bash script =head1 Todos Replace system call to html2ps with "use HTML::FormatPS". Replace system call to html2text with "use HTML::FormatText". (HTML::Tree and Font::AFM needed for above) Find perlish replacement for system call to ps2pdf. =head1 Author ybiC =head1 Required html2ps 1.0b1-8 gs-aladdin 5.50-8 ps2pdf html2text =head1 Tested On Debian 2.2, WinNT4, and Win2kPro Mozilla M18, 0.8 Netscape 4.75 Opera 5.02 IE 5.5 w3m 0.1.9-5 Lynx 2.8.3-1 gv 3.5.8-17 gsview32 2.6 Acrobat Reader 4.056 =head1 html2ps runcontrol /* ~/.html2psrc */ @html2ps { package { ImageMagick: 1; PerlMagick: 1; TeX: 1; Ghostscript: 1; check: weblint; libwww-perl: 1; path: "/usr/X11R6/bin:/usr/bin"; } paper { type: letter; } hyphenation { en { file: "/usr/share/texmf/tex/generic/hyphen/ushyph1.tex"; } } margin { top: 1; right: 2.5; bottom: 1.5; left: 2.5; } footer { alternate: 0; left: \$D; right: "page $N"; } } /* Standard style sheet definitions */ BODY { font-family: Helvetica; font-size: 11pt; } P { text-align: justify; } H1 { font-size: 19pt; text-align: center; font-weight: bold; } H2 { font-size: 14pt } H3 { font-size: 13pt } H4 { font-size: 12pt } H5 { font-size: 11pt; text-align: center; } H6 { font-size: 11pt; text-align: center; } =cut

Replies are listed 'Best First'.
Re: hash n' params
by araqnid (Beadle) on Apr 07, 2001 at 20:38 UTC
    When you're initialising a hash that contains a group of settings, you can put them together like this:
    my %exec = ( html2ps => '/usr/bin/html2ps', ps2pdf => '/usr/bin/ps2pdf', html2text => '~/perl/html2text' );
    which IMHO looks nicer. You're explicitly allowed to use barewords on the left hand side of a =>, even if "use strict" is in force.
      Warning. A bug I recently learned about:
      use strict; my %trial_hash = ( foo => "bar", );
      does not run properly in a Perl program, but does if you use eval. So while I use the "big arrow", you should put it on the same line as the key, not the value.
Re: hash n' params
by stephen (Priest) on Apr 07, 2001 at 21:35 UTC
    A couple of comments:
    • Your <TYPE>my $dir</TYPE> at the top doesn't change during the lifetime of the script-- and it would be confusing if it did! Personally, I'd
      use constant DIR => '~/';
      or some such.
    • If you get an error in your system() calls, your error messages will be misleading. System() doesn't set $! on error. To get the return code on a system process that didn't return properly, use '$?'. I'd pull your system calls out into something like this:
      sub run_system { my (@params) = @_; system(@params) == 0 or die "System command @{[join ' ', @params]} failed: returned + @{[ $? >> 8 ]}; stopped"; }
    • You could replace the third function call with a call to open() (or open2()) to make it a bit more Perlish. It would require significantly more code, but would eliminate a temporary file.

    But, these are merely suggestions. It looks like good Perl to me.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://70715]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2018-06-22 06:17 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (121 votes). Check out past polls.