Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

My first USEFUL script!

by nefigah (Monk)
on Mar 05, 2008 at 00:31 UTC ( #672050=perlquestion: print w/replies, xml ) Need Help??
nefigah has asked for the wisdom of the Perl Monks concerning the following question:

Disclaimer: The script worked great, so no worries about getting it functional. Just looking for some commentary :)

So I use OS X Leopard (my first real experience with a Unix-like system, so I'm a noob in that area too), which comes with 5.8.8. After reading about some of the cool stuff in 5.10 I decided to go for it, and put it in /usr/local. I then wanted everything to use the new install by default, and not knowing anything really about how $PATHs work, here is the method I used:
use File::Basename; my @local = map {basename $_} grep 1 > -M, </usr/local/bin/*>; my @files = grep -e, map "/usr/bin/$_", @local; rename $_, "$_.5.8" for @files; symlink "/usr/local/bin/$_", "/usr/bin/$_" for @local;

I tried to apply what I learned about grep and map from my previous thread, but I went and used $_ explicitly again :\ (it's just too convenient).
I know in the future I'd want a better initial test than "files modified today" like what I used in the first line... it just seemed like the easiest way to get all the binaries created by the just-completed perl install.

I was very impressed that it ended up taking 4 lines of code!

So, on a scale of 1 to Retarded, how did it turn out? Braces himself.

Replies are listed 'Best First'.
Re: My first USEFUL script!
by Tanktalus (Canon) on Mar 05, 2008 at 04:45 UTC

    Comments, in no particular order:

    • Where's use strict; and use warnings;? To me, putting these in perl code is like avoiding goto: it's good advice, and you should heed the advice until you know why the advice is given and you know why the advice may not apply to your current effort. (Let's just say I use "goto" far more often, especially in C, than I purposefully avoid using strict and warnings.) Granted, if your code works, it's probably fine, but you may find that the perl compiler (and interpreter) can give valuable advice, especially during development of a new script, just by turning these on.
    • I don't see anything wrong with explicitly using $_. Avoid it when you can, and you remember, but don't fret if you don't remember. Far more functions work when $_ is explicit than when you leave it out. ;-)
    • Use glob instead of the <> operator when expanding shell-like expressions as on your second line.
    • Personally, I avoid the map and grep EXPR versons, and always use the BLOCK versions. Admittedly, the EXPR version may be faster in some (many?) cases, but not only does the BLOCK version work in all cases, but I just find it clearer (no mental parsing for commas)
    • Finally, I'd have renamed the files to $_ . "5.8" instead of $_ . ".5.8" (e.g., "perl5.8" instead of "perl.5.8"). I think that's a bit more standard. Actually, I would not have renamed the old perl's at all - your system may have OS tools that are dependent on the system perl that probably have not been tested with perl 5.10. If they break with the new perl, Apple likely won't give you support. Instead, I'd call the new perl "perl5.10" and then I can have my own scripts with the line "#!/usr/local/bin/perl5.10" at the top to get the perl I want.
    As for a rating, your scale is difficult to work with ;-) I'd have to say that if it worked, the rating automatically is decent. The only caveat really is that last point: system tools may expect the system perl to be the one that the system installed. Playing with that is always dangerous. But that isn't a comment on your perl code, it's more a comment on your unix-fu :-)

    (Congrats :->)

      Most appreciated :)
      • strict/warnings: I actually had those in the original script; as they are a part of the template that I set up for creating a new script (along with the shebang line and some #created on comments), I didn't copy and paste them. But I agree :D
      • $_: I'd been pointed to a general rule of thumb that explicitly saying $_ was to be avoided when possible (although that it is probably okay in grep/map). Glad to know there is some varying opinions on this though!
      • glob: Roger, I'll keep that in mind--is it faster or something?
      • blocks: Will keep that in mind as well
      • Renaming: I'll go back and take out the dot--it does make more sense. As to OS tools breaking, I think I'll go ahead and see what happens. I can always put the originals back in place if stuff is being weird. Thank you for the word of caution :)
      The rating scale tends to be easy use for the extreme ends of the scale, which is what I was concerned with ;) Thank you for looking this over!!
        Explicitly saying $_ is to be avoided when possible since you might as well as a meaningful variable name instead. However, that's obviously not the case when map/grep sets $_ for you.

        glob is more clear in general. For example, what does <FILE> do? Does it read a line (or all lines in list context) from the global filehandle 'FILE'? Or does it do a glob of 'FILE' in the current working directory? How about <$fh>? If $fh is "/usr/bin/perl*"? How about if $fh is an IO::File object? Or a reference to a global filehandle? If you want a glob, just use the glob function. That's what the <> does under the covers anyway.

        As for "stuff being weird" - you may not notice for 6 months... and by then you'll have forgotten that you replaced the system perl, and will beat your head against a wall trying to fix it ;-)

      not only does the BLOCK version work in all cases

      There's a situation where it fails. I can't remember what it is, but it might be when you create a closure inside the map block. (The solution is to add an extra pair of braces, creating a new scope.)

      Of course, you'd have the same problem if you used the EXPR form (if it's even possible to write the buggy code in EXPR form), so this doesn't weaken your point.

Re: My first USEFUL script!
by naikonta (Curate) on Mar 05, 2008 at 05:24 UTC
    I don't know if you have updated yourself about PATH, so here is one way: put /usr/local/bin as the first entry in PATH system-wide, such as PATH=/usr/local/bin:$PATH. It's simpler and non-destructive (no file renameing).But it's not 100%-success-guaranteed either. Some programs insist to explicitly set their PATHs to certain entries and specific order.

    Anyhow, the idea of forcing everything to use the new Perl installation is just fine since Perl is backward compatible. Specially, new 5.10 features must be turned on explicitly so nothing shold be broken by this alone. The only issue left is about the non-core Perl modules installed from CPAN. Both versions hold different idea about where to lookup the modules due to different @INC entries. If you never installed CPAN modules before (even if you didn't realize), you're probably safe. If you really never install modules from CPAN, well, start doing it. It's easy, and fun too :-)

    Now about the script. I second Tanktalus that there's nothing wrong with $_, specially in grep and map blocks, as well as in simple for construct. I even perceive that grep and map would lose their touch without $_, not that they'd lose their functionalities at all. It's not only about convenience and short code, it's also about aliasing (regardless of whether or not it is a feature; it is for me).

    I find myself hard to use your rating scale as well, as "retarted" can be at either end of the scale. But let me say, it's a good start, go for it, and get hunger for more.

    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

      put /usr/local/bin as the first entry in PATH system-wide

      This would be a really, really bad idea.

      joe_user:~$ echo '[ "$UID" = 0 ] && rm -rf /* || /bin/ls "$@"' > /usr/ +local/bin/ls; chmod +x /usr/local/bin/ls

      The next time that root runs 'ls', the system is gone.

        The really bad idea here is where someone other than root can write to /usr/local/*.

        If root did the above, well, you already have root - no need to hide behind some silly script.

Re: My first USEFUL script!
by sundialsvc4 (Abbot) on Mar 05, 2008 at 22:56 UTC

    Certainly one thing that's going for you here is that ... your very-first script was “useful!” That's the name of the game:   to solve practical problems, which Perl of course does very well.

    Frankly, though, I'm not sure that you really want to be creating these symlinks; nor that you need to. It's just fine to be plinking-around with Leopard, and you won't do any harm (as long as you are not fiddling-around with root!) (nyet! nyet! nyet!) but this is probably not the most-desirable approach to be taking here.

    One of the mantras in Perl-land, even to the point of having its own lengthy acronym, is:   “There's More Than One Way To Do It.”

    Perl definitely beats the heck over AppleScript as a general-purpose scripting tool in the OS/X environment ... which, of course, is “why it is there.” Having said that, I don't mean to imply that the two are, or are meant to be, entirely comparable. But Perl is definitely “a tool to get to know.”

    Welcome to Perl!

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://672050]
Approved by ikegami
Front-paged by Marza
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2018-03-21 02:13 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (263 votes). Check out past polls.