Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

A use strict confession, with real questions.

by perlidiot123 (Acolyte)
on Jun 05, 2015 at 03:42 UTC ( [id://1129157]=perlquestion: print w/replies, xml ) Need Help??

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

I literally grew up with perl (digitally, not literally), starting in 1996. We used local..

That was about the only declaration used by the stuff we got. Everything else was global $x=whatever, cleared it when you needed to re-define again. Yeah I know, this is garbage can development.

So I've got a ton of code right now (a well built system) that does not use strict, has tons of subroutines and is very well organized that uses my $var, at every occassion, and, uses return(); when no return $var is required. It's clean, efficient and it works.

It uses a lot of requires IE 'process.pl', 'whatever.pl'. (files required only when necessary).

I'd like to convert this big thing to a complete use strict as well as convert my design philosophy to using strict 24/7.

One thing I've noticed, is that I can put use strict in the header on a particular included file and it works fine as long as everything is declared before use.

Everytime I work on this code, I feel like the Gods at perlmonks are looking down on me telling me I suck because I don't have 'use strict' at the top end of my script, and I have globals. But it works, yes I use taint and warnings... and many other things (fill in the blank to avoid variable screwups).

My real question is, how would I take a large group of files written in perl without use strict, convert it to one where I can use it, and comply with the mighty directives that are adored by professional perl programmers and the future me?

I guess I'm just tired of hiding in the shadows of "Use everything, ie declare all $vars as OUR".

Well, if anyone has some insight on how to go from idiot to somewhat pro, it would be appreciated. Been working at this for almost 20 years now (with much success), now it's time to change. Thanks for any advice/help.

I'm new, this is my first post, but I've been here forever.
Thanks folks... :-)
  • Comment on A use strict confession, with real questions.

Replies are listed 'Best First'.
Re: A use strict confession, with real questions.
by eyepopslikeamosquito (Archbishop) on Jun 05, 2015 at 04:23 UTC

    So I've got a ton of code right now (a well built system) that does not use strict, has tons of subroutines and is very well organized that uses my $var, at every occassion, and, uses return(); when no return $var is required. It's clean, efficient and it works.
    How much of this "well built system" has regression tests around it? I'm afraid refactoring working production code without the safety net of a comprehensive test suite is tantamount to suicide. So your first step may be to write a comprehensive regression test suite for your system.

    Since this may be a daunting task, can you break your large system into smaller components that can be tested in isolation? (sounds problematic due to your heavy use of globals). If you can do that, at least you can then convert the system to be strict-safe one component at a time.

    It uses a lot of requires IE 'process.pl', 'whatever.pl'. (files required only when necessary)
    Does your system currently use Perl modules? You might consider converting some of your scripts to modules, see for example How a script becomes a module.

    Update: See also: So I'm in a bit of a quandary

      If you can do that, at least you convert the system to be strict-safe one component at a time.


      yes, this... I think I've got it.

      How much of this "well built system" has regression tests around it?


      Never been that route, but probably About 20 million dollar wise in transactions to date; hundreds of thousands of transactions.

      What's a regression test? I don't do corporate perl, I just do perl.

      write a comprehensive regression test suite
      Ok I was looking for some real world stuff to deal with this but I think I got what I needed based on your 'one component at a time' comment. Thanks much for your input. :-)

        What's a regression test?
        Currently, how do you test your software? Is it ad-hoc manual testing? Or do you have formal manual test plans you run through? Or do you use automated testing?

        As you change your code to use strict, there is a risk that you may accidentally break a working system. If you have an automated regression test suite in place, you can:

        1. Run the automated test suite. It passes. Good.
        2. Make your code changes to make the code strict-safe.
        3. Re-run the automated test suite. If it now fails, you know that your code change broke the system.

        Of course, if your automated regression test suite is mickey-mouse, passing all the tests doesn't mean much. But if you have a comprehensive test suite in place it gives you much greater confidence that you haven't accidentally broken the system while cleaning up the code.

        BTW, note that Perl itself has a comprehensive automated regression test suite (run with "make test" when you build Perl). This test suite is an invaluable safety net to Perl developers as they change the (fragile) perl C source code.

        Welcome perlidiot123,

        Try using <ul><i> and </i></ul> around comments from a previous post like this:


          If you can do that, at least you convert the system to be strict-safe one component at a time.

        yes, this... I think I've got it. ( your comment )


        IMHO, It helps the readers understand your responses.

        About your real question, I think its a slow process of fixing existing scripts one at a time.

        About 8 years ago I had the same situation. I starting using strictures, but only if I needed to update an existing process. Many of the old are running in production without re-write, but if I add something new or need to update a process, you can be sure I use strictures plus better Perl techniques.

        Every time you look at older code, you can see a better way. Good Luck!

        Regards...Ed

        "Well done is better than well said." - Benjamin Franklin

Re: A use strict confession, with real questions. (Perl scriptors and Perl programmers)
by Discipulus (Canon) on Jun 05, 2015 at 09:18 UTC
    ok perlidiot123 welcome (even if you are here before me..), you got precious answers yet. I'm not a professional programmer and i'm somehow in your same situation.

    From what i understand you have an heritage codebase, with a lot of scripts, a lot of dependencies, a lot of underlined design grown up trought the years. Probably you also have a lot of inter system communication (databases, remote data..). And all pieces of the codebas interact indipendently with such data. This is production code involving money and the safety of your job. It is critical.

    Your confession to not using strict seems to me the less important issue.
    In fact your (and mine too, dont feel is a critic to you..) software was developped without a strategy, without the foundamental habits of the professional programming.

    Somehow the cause of this is Perl itself. Is a side effect of his power: the job can be done so quickly that you was tempetd to get the job done, without a long term strategy. I have done this error many many times. And as always refactoring is a pain, worst and riskier than write solid code from scratch.

    As stated before by wiser monks, test is the crucial word. But we are in a bad situation because standalone scripts with a lot of globals are not testable, or better said, not easily testable. You can write tests using IPC::Run or similar.. good luck!

    So before doing something on your codebase, my best suggestion is to learn well how professional code is written. I'm around such theme since months. I think the right approach, the habit, tell the difference between a Perl scriptor (as i m) and a Perl programmer.

    The code must be contained in modules! Is the only thing i found restrictive in Perl: the .pm extension needed by modules during lookup. Beeing basically a collection of subroutines the module force you on the right path: you export behaviours and possibly no variables: data will be accessible through sub call. You won: your application script become a skelatal glue of behaviours contained in a module.. a module you can run tests against.

    Extremistically: consider shifting your point of view: you imagine some behaviour for your future software, then you write tests that restrict, define, delimit, test your needed behaviour with possibly edge cases and errors too before writing a single line of the wanted resulting code. Then in a heaven world you have also the time to write down the pod documentation in the module before even declaring a single variable. This approch saves your weekends, that are definetively the only reason to write software.

    Exploring this subject i collected some usefull links: the basic doc
    writing solid cpan modules
    A brief question about testing/best practices
    Creating (and Maintaining) Perl Modules
    Corion's answer in thread about module facilities
    namespace and modules
    require "shared.pl" with use strict;

    Also very interesting is the Modulino idea explained in mastering perl by brian d foy.

    So if you really want to upgrade your software you'll face a surgeon job: you need to dissect the production code organism, extrapolating behaviours. Probably you can easily start from the required .pl files transforming them in modules with tests and docs. Probably is wiser to have configuration stuffs in separate files adding the ability to run against a dev environment or against a production one with zero effort.

    HtH
    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: A use strict confession, with real questions.
by Your Mother (Archbishop) on Jun 05, 2015 at 15:54 UTC
    I feel like the Gods at perlmonks are looking down on me telling me I suck

    No one thinks you suck and this is not a pro v amateur question. It’s a matter of remote help and effort involved. If you have a 10,000 line script with homemade modules all without strict or warnings and you have an error and come here to ask: Why is it broken? No one is likely to help because it could be 100,000 things and except in very lucky or obvious circumstances, it will be painful to figure out, if not impossible, without seeing all the code.

    use strict; protects you and makes getting free, professional help eas(y|ier) for the professional which also makes it more likely to happen. I think you can see the difference between saying: Please help me, it will probably be easy for you and Please help me, it might be impossible or take several hours of your time. That’s where the, sometimes hostile, push-back against eschewing strict originates.

Re: A use strict confession, with real questions.
by toolic (Bishop) on Jun 05, 2015 at 14:38 UTC
Re: A use strict confession, with real questions.
by u65 (Chaplain) on Jun 07, 2015 at 15:53 UTC
    I faced a similar situation over the years as I matured with the language and discovered better ways to do things while the language improved from the early days to Perl 5. Besides applying much of the other good advice you've received here, I found that reading Damian Conway's book, "Perl Best Practices," was a great help along the way to upgrading my old code to modern Perl. (And I hope he will write a similar book for Perl 6 some day.)

      And I hope he will write a similar book for Perl 6 some day
      From Interview with Damian Conway:
      And I can certainly see myself writing a book on Perl 6 best practices. But I can't see myself writing the best practices book until I have 5 or 10 years experience of what people do wrong in the language. That's where the best practices come from. Seeing the mistakes that people make and the consequences of those mistakes...and we don't know what they are yet. To write Perl 6 best practices needs a lot of experience in the community, and a lot of feedback, and me teaching a lot of people and finding out what they don't do right.

Re: A use strict confession, with real questions.
by Athanasius (Archbishop) on Jun 09, 2015 at 12:38 UTC

    Hello perlidiot123, and welcome to the Monastery!

    I'd like to convert this big thing to a complete use strict as well as convert my design philosophy to using strict 24/7.

    Saying use strict actually invokes all of the various strict pragmata; currently there are three: refs, subs, and vars. So if you convert your code to use strict, you should approach this as three separate tasks:

    1. use strict 'subs'. This produces a compile-time error if the compiler finds a “bareword,” meaning an unquoted sequence of characters which the compiler cannot unambiguously identify as a variable name, function name, numeric constant, filehandle, etc. AFAICT, this can occur in only two cases: (1) a string which is unquoted; and (2) a subroutine call on a sub which is undeclared and is neither preceeded by & nor followed by (). In both these cases, the compile-time error will alert you to the problem, and the fix (quote the string or call the sub explicitly) is safe from adverse consequences or side effects.

    2. use strict 'vars'. This produces a compile-time error if the compiler finds a variable which has not been declared with my, our, state, or use vars, and which is not fully qualified with a package name. It is this aspect of strict which most Perl programmers think of when they think of use strict.

      I guess I'm just tired of hiding in the shadows of "Use everything, ie declare all $vars as OUR"

      Actually, if you do declare your global variables with our, you will satisfy the use strict 'vars' pragma and you will still gain some advantage over using undeclared package globals. A useful reference is Ovid’s 'our' is not 'my'. Of course, your long-term goal is to convert all the our variables (package globals) that are not shared between packages into my variables that cannot be (accidentally) so-shared. In doing this you will need to be careful to identify those variables which are meant to be shared. A text editor can help you here to some extent — if you have a variable $Foo::bar and the name $bar occurs only within the Foo package, you can be confident that it isn’t shared between packages — but where the same variable name is used across different packages, only a careful analysis of the code will tell you whether or not the variable is acutally shared.

    3. use strict 'refs'. This prevents the use of symbolic references (see How-can-I-use-a-variable-as-a-variable-name of perlfaq7). If your existing code does make use of symbolic references, the good news is that they can usually be fairly easily replaced with hard references. The bad news is that the use strict 'refs' pragma generates a run-time error (and not a compile-time error) when the interpreter encounters a symbolic reference. This means that if you get no errors under use strict, you can’t be sure that there are no symbolic references lurking undetected. If a symbolic reference appears in a seldom-visited execution path, your new code may appear to work for a while and then die unexpectedly. Once again, you need to make a careful analysis of the code to ensure that no symbolic references are being used.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: A use strict confession, with real questions.
by Anonymous Monk on Jun 06, 2015 at 05:26 UTC

    Hi,

    Very, very carefully.

    Do you know the phrase -

        if it ain't broke ...

    if not look it up.

    You are talking about working production code, handling many transactions, covering loads of money.

    Start all you new progs with strictures, but leave this stuff alone until you are forced to do something to it.

    J.C.

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1129157]
Approved by kevbot
Front-paged by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (4)
As of 2024-04-24 06:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found