tame1 has asked for the wisdom of the Perl Monks concerning the following question:

I read with great interest about one user's habit of copying old small scripts into a single text file for storage. I decided to make a small script to do it for me.

My question is this: although I have been doing perl for a few years now, a lot of what I read here is way over my head. I use perl every single day, yet I never seem to "progress" to the point of things like writing my own modules, etc.

My worry is that somehow I am missing something - that the code I write could be "better" if I only learned all the stuff that usually flies over my head in here.

Anyone agree?

Also, here is an example - the script I wrote to add to that graveyard file! Shows how I still do things the "beginner" way.

#!/usr/bin/perl # # grave - a program to consign a short perl script into the # 1linegraveyard.txt file. # usage - grave <progname> use strict; my $TEXTFILE = "/home/jrobiso2/perl_scripts/1linegraveyard.txt"; error("arguement") unless $ARGV[0]; my $PROG = $ARGV[0]; my $progref = read_file($PROG); add_file($progref); print "Added $PROG to $TEXTFILE\n"; unlink($PROG); exit(0); sub read_file { my @output; my $file = shift; open(FILE, "< $file") || die "Cannot open $file!: $!\n"; while(<FILE>) { push @output, $_; } close(FILE); return \@output; } sub add_file { my $dataref = shift; my @lines = @$dataref; open(GRAVE, ">> $TEXTFILE") || die "Cannot open $TEXTFILE for writ +ing: $!\n"; print GRAVE "\#" x 75 . "\n"; print GRAVE "\# $PROG\n"; my($day,$month,$year) = (localtime)[3,4,5]; $month = $month + 1; $year = $year + 1900; my $date = "$month\/$day\/$year"; print GRAVE "\# consigned to the graveyard on $date\n"; foreach my $line (@lines) { print GRAVE "$line\n"; } print GRAVE "\# end of file $PROG\n"; print GRAVE "\#" x 75 . "\n\n"; close(GRAVE); } sub error { my $error = shift; if ($error eq "arguement") { print "Usage - grave <progname>\n"; exit(0); } else { print "Exiting from unknown error! \n"; exit(0); } }


What does this little button do . .<Click>; "USER HAS SIGNED OFF FOR THE DAY"

Replies are listed 'Best First'.
Re: Missing Something
by davorg (Chancellor) on Feb 07, 2001 at 21:41 UTC

    There really doesn't seem to be much wrong with your code at all - sure there are a few things that I'd do a bit differently, but so what?

    If you really want to move to the 'next' level of Perl programming then I'd recommend taking a look at Effective Perl Programming and The Perl Cookbook. These are both available from Buy Stuff.

    Update: Ooh. Just noticed this is my 500th post to PerlMonks :)

    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

      Ooh. Just noticed this is my 500th post to PerlMonks :)

      well, congratulations, then :-)

      Regards
      Stefan K

      $dom = "skamphausen.de"; ## May The Open Source Be With You! $Mail = "mail@$dom; $Url = "http://www.$dom";
Re: Missing Something
by arhuman (Vicar) on Feb 07, 2001 at 21:39 UTC
    basicly
    $result=`cat $PROG >> $TEXTFILE`;
    (use type instead of cat> on windows)

    will do the same if I understand what you're trying to do, just add a some error checking.

    TIMTOWTDI !!!

    But to answer your question, I see nothing wrong with your code (except that you're not lazy enough... ;-)

    may be some spelling errors (but as a french guy I won't go on this !)
    I would suggest, as a general rule, to use variable for numerical constants (the 75) if they're used more than once
Re: Missing Something
by stefan k (Curate) on Feb 07, 2001 at 21:50 UTC
    Hi Monks,
    as most us will probably know TIMTOWTDI is one of the low level perl rules. One of the best things about the perlmons.org site is that you don't count as an idiot (even in the eyes of Uber-saints like merlyn) when you're asking easy questions or post code which does things "the beginner way" like you said. This makes this community very valuable, I think, since it incorporates one of the perl-"paradigms".
    OK, just some words of happiness about this site (exspecially since I became a monk this monday *grin*)

    Regards
    Stefan K

    $dom = "skamphausen.de"; ## May The Open Source Be With You! $Mail = "mail@$dom; $Url = "http://www.$dom";
Re: Missing Something
by tadman (Prior) on Feb 08, 2001 at 05:55 UTC
    The difference between the "beginner way" and a presumably more advanced technique is merely style. As long as you continue to produce working code, your skill will improve. With experience comes an ability to write less code to get the same job done. Fewer lines of code means less code to debug, which can reduce the likelihood of producing defective code. This artifact is difficult to explain to employers who judge performance on lines of code produced. Alas.

    Here's some tips that could make your program "better", though what that means in practice is actually highly subjective.
    my($day,$month,$year) = (localtime)[3,4,5]; $month = $month + 1; $year = $year + 1900; my $date = "$month\/$day\/$year";
    This four line chunk could be reduced into something like this:
    my (@time) = (localtime)[4,3,5]; my ($date) = sprintf ("%d/%02d/%02d", $time[0]+1900, $time[1]+1, + $time[2]); # Or if you don't care about formatting: my ($date) = join ('/', $time[0]+1900, $time[1]+1, $time[2]); # Or if you want to combine with your print, which would # avoid having to declare $date: printf GRAVE ("# consigned to the graveyard on %d/%d/%d\n", $date[0]+1900, $date[1]+1, $date[2]);
    sprintf allows you to convert a list of items into a string, with formatting. It's a little hairy to use at first, but with a little practice it comes in quite handy. join() allows you to put things together on the double, but doesn't offer much flexibility.
    while(<FILE>) { push @output, $_; }
    You will notice here that you are taking something from one array (<FILE>) and putting it into another (@output). Why not do it in one shot?      @output = <FILE>; BTW, it would seem that your program inserts things into the GRAVE double-spaced. You're not removing the "\n" from the input stream FILE, so it's still there when you go and write into GRAVE with "$line\n"...

    An interesting read is in the back of the "Camel Book" where they compare Program Efficiency vs. Programmer Efficiency and how you can choose to optimize around either. The 'Camel Book' is virtually essential to developing a full understanding of the Perl language, as there are few with the same depth and scope.
Re: Missing Something
by magnus (Pilgrim) on Feb 07, 2001 at 21:47 UTC
    i would say don't worry about "progressing", unless your job demands you program more complicated,
    complex code (or you're driven)... when that occurs, you'll move to the next level...
    obviously your level of coding suits what it is you use Perl for... when you need more, it will be clear...

    magnus
Re: Missing Something
by mirod (Canon) on Feb 07, 2001 at 21:47 UTC

    You can simplify your read/write functions:

    @output=<FILE>; is equivalent to while(<FILE>) { push @output, $_; }

    even better {local undef $/; $output=<FILE>; } slurps the entire file into a string which you can then output by simply printing it

    I would also use the ISO standards for date (see Re: (tye)Re: sorting mm/dd/yy) but that's more of a pet peeve of mine.

Re: Missing Something
by $code or die (Deacon) on Feb 07, 2001 at 22:51 UTC
    I really liked the idea of the 1linegraveyard.txt. A couple of months ago I "almost" did what you want to do but using a database. I was going to add each "scriptlet" to a category and maybe assign keywords so I could browse and search easily for past one-liners. But I was not lazy enough to do this (or too busy).

    I have played a couple of times with creating my own OOP modules, but they got too complicated. So most of the time, I make use of Package <xxx>; and use lib and write what I suppose are pseudo-modules. I haven't quite figured out when or why I should use @export, $ISA, etc.

    $code or die
    Using perl at
    The Spiders Web
Re: Missing Something
by dash2 (Hermit) on Feb 08, 2001 at 04:09 UTC
    All seems fine to me, just one thought: unless you really want machine-readable dates, it's much simpler to use

    scalar localtime;

    which pretty-prints a date for you, than doing all that stuff with $month+=1900; $year++ (or is it the other way round ;-)

    dave

Re: Missing Something
by t'mo (Pilgrim) on Feb 10, 2001 at 03:31 UTC

    Have you tried teaching Perl to somebody else? explaining your code to somebody who doesn't know what you're trying to do (and explaining *why* you chose to do a thing a certain way)? Often, a teacher will learn more than his/her students...and when you're forced to help somebody else see the "something", you probably won't miss it.

Re: Missing Something
by wardk (Deacon) on Feb 07, 2001 at 23:41 UTC

    I would suggest you turn on warnings at least during development.

    #!/usr/bin/perl -w