strategys other than subroutine and OO?

Discussion in 'Perl Misc' started by Ela, Mar 20, 2008.

  1. Ela

    Ela Guest

    I have 300 lines of codes that are used roughly twice. Some of the lines
    have delicate difference in execution (e.g. ~6 variables have to be replaced
    and conditional statements are also different) and therefore many arguments
    need to be passed into it in order to differentiate the execution parts. OO
    development is analogously also difficult. I wonder if there is any good way
    to reuse the codes, e.g. some sort of "goto" rather than duplicating these
    lines. Whenever there is any change, I find that is really error-prone.
     
    Ela, Mar 20, 2008
    #1
    1. Advertising

  2. Ela wrote:
    > I have 300 lines of codes that are used roughly twice. Some of the lines
    > have delicate difference in execution (e.g. ~6 variables have to be replaced
    > and conditional statements are also different) and therefore many arguments
    > need to be passed into it in order to differentiate the execution parts. OO
    > development is analogously also difficult. I wonder if there is any good way
    > to reuse the codes,


    There are good ways and there are easy ways. Choose good.

    > e.g. some sort of "goto" rather than duplicating these
    > lines. Whenever there is any change, I find that is really error-prone.


    "For a number of years I have been familiar with the observation that
    the quality of programmers is a decreasing function of the density of go
    to statements in the programs they produce. More recently I discovered
    why the use of the go to statement has such disastrous effects, and I
    became convinced that the go to statement should be abolished from all
    "higher level" programming languages (i.e. everything except, perhaps,
    plain machine code). At that time I did not attach too much importance
    to this discovery; I now submit my considerations for publication
    because in very recent discussions in which the subject turned up, I
    have been urged to do so."

    Edager W. Dijkstra. Go To Statement Considered Harmful. 1968.



    In nearly 30 years of programming I have completely avoided use of GOTO
    in a professional context. All I have seen continues to convince me that
    Dijkstra was right on this matter. YMMV.

    --
    RGB
     
    RedGrittyBrick, Mar 20, 2008
    #2
    1. Advertising

  3. "Ela" <> writes:

    > I have 300 lines of codes that are used roughly twice. Some of the lines
    > have delicate difference in execution (e.g. ~6 variables have to be replaced
    > and conditional statements are also different) and therefore many arguments
    > need to be passed into it in order to differentiate the execution parts. OO
    > development is analogously also difficult. I wonder if there is any good way
    > to reuse the codes, e.g. some sort of "goto" rather than duplicating these
    > lines. Whenever there is any change, I find that is really error-prone.


    Sounds like using closures/passing functions as arguments could be very
    helpful here, but without seeing your code it's impossible to be sure.

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 20, 2008
    #3
  4. Ela

    Willem Guest

    Ela wrote:
    ) I have 300 lines of codes that are used roughly twice. Some of the lines
    ) have delicate difference in execution (e.g. ~6 variables have to be replaced
    ) and conditional statements are also different) and therefore many arguments
    ) need to be passed into it in order to differentiate the execution parts. OO
    ) development is analogously also difficult. I wonder if there is any good way
    ) to reuse the codes, e.g. some sort of "goto" rather than duplicating these
    ) lines. Whenever there is any change, I find that is really error-prone.

    Maybe you can take the lines that are exactly duplicated and put those
    into sub functions. If you define the sub functions inside the main
    function they can access the main function's 'my' variables, so you
    don't need to pass them as arguments.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Mar 20, 2008
    #4
  5. Ela

    Ela Guest

    Re: strategies other than subroutine and OO?

    > Maybe you can take the lines that are exactly duplicated and put those
    > into sub functions. If you define the sub functions inside the main
    > function they can access the main function's 'my' variables, so you
    > don't need to pass them as arguments.
    >


    From perlintro:
    A Perl script or program consists of one or more statements. These
    statements are simply written in the script in a straightforward fashion.
    There is no need to have a main() function or anything of that kind.

    So would you mind giving a very simple example? i guess your suggestion is
    very close to the final solution since i never have the concept you suggest.
     
    Ela, Mar 20, 2008
    #5
  6. Ela

    ccc31807 Guest

    On Mar 20, 7:34 am, "Ela" <> wrote:
    > I have 300 lines of codes that are used roughly twice. Some of the lines
    > have delicate difference in execution (e.g. ~6 variables have to be replaced
    > and conditional statements are also different) and therefore many arguments
    > need to be passed into it in order to differentiate the execution parts. OO
    > development is analogously also difficult. I wonder if there is any good way
    > to reuse the codes, e.g. some sort of "goto" rather than duplicating these
    > lines. Whenever there is any change, I find that is really error-prone.


    I have a suggestion. Since you didn't post a coding sample, my
    suggestion may not be appropros, but maybe it will.

    First, you surely don't have a function that is 300 lines long. If you
    do, I don't think I can help. You probably have batches of lines that
    are duplicated. The first thing I would do is abstract these batches
    of lines into separate functions and call them separately, like this:

    &batch_a;
    &batch_b;
    &batch_c;
    sub batch_a { #first batch of lines
    }
    sub batch_b { #second batch of lines
    }
    sub batch_c { #third batch of lines
    }

    Second, you can pass different parameters into these functions to
    account for the different variables. If you need to set a variable as
    a result of some behavior, set the variable by calling a function,
    like this:

    $var = &setvar;
    sub setvar { #code here sets a var which you would return
    return $var; }

    Third, you can replace your conditional statements with booleans and
    set them outside the function call, like this:

    my $conditional = 0
    $conditional = 1 if &some_function_that_returns_true;
    $contitional = 0 unless &some_function_that_returns_true;
    if ($conditional) { #code to execute
    }

    Fourth, if possible, place your common code (our variables and
    functions) in a PM and import the backage. This way, you can separate
    the interface and the functionality, and this will also allow you to
    refactor your code if and when you have the time to do so. You don't
    need to create classes and objects to do this.

    Fifth, as a strength building exercise, you might attempt to place ALL
    your code, every line of it, in user defined functions and execute the
    program by the judicious call of these functions. Of course, you would
    still need to declare your lexical variables, but you set them by
    function calls.

    CC
     
    ccc31807, Mar 20, 2008
    #6
  7. ccc31807 <> writes:

    > &batch_a;
    > &batch_b;
    > &batch_c;


    Erm, you *do* know what that does, right? In most circumstances you want
    to use

    batch_a();
    batch_b();
    batch_c();

    instead.

    See perlfaq7

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 20, 2008
    #7
  8. Ela

    Ela Guest

    > Fourth, if possible, place your common code (our variables and
    > functions) in a PM and import the backage. This way, you can separate
    > the interface and the functionality, and this will also allow you to
    > refactor your code if and when you have the time to do so. You don't
    > need to create classes and objects to do this.
    >
    > Fifth, as a strength building exercise, you might attempt to place ALL
    > your code, every line of it, in user defined functions and execute the
    > program by the judicious call of these functions. Of course, you would
    > still need to declare your lexical variables, but you set them by
    > function calls.
    >
    > CC


    I don't quite understand the last 2. Maybe I need to refer to some Advanced
    Perl Programming? Anyway I guess your first 3 suggestions should be
    sufficient to solve the headache-causing clumsy coding problem. Thank you
    and all others' help!
     
    Ela, Mar 20, 2008
    #8
  9. Ela

    ccc31807 Guest

    On Mar 20, 11:10 am, Joost Diepenmaat <>
    > Erm, you *do* know what that does, right?


    I know exactly what calling a function using & does. As I understand
    it, it uses your programs underscore varibles.

    > In most circumstances you want
    > to use
    >
    > batch_a();
    > batch_b();
    > batch_c();


    I'm sorry if what I posted was confusing. Yes, you are correct, and I
    certainly did not want to mislead anyone. However, I certainly wasn't
    misled when I wrote what I did and didn't think that anyone else would
    be, either. In any case, you can call a function clearly and
    ambiguously using &. And I just prefer to do so. TIMTOWTDI.

    CC
     
    ccc31807, Mar 20, 2008
    #9
  10. Ela

    ccc31807 Guest

    On Mar 20, 11:30 am, "Ela" <> wrote:
    > > Fifth, as a strength building exercise, you might attempt to place ALL
    > > your code, every line of it, in user defined functions and execute the
    > > program by the judicious call of these functions. Of course, you would
    > > still need to declare your lexical variables, but you set them by
    > > function calls.


    > I don't quite understand the last 2.


    1. Please note that I may have misled you by suggesting that you call
    your functions using &. While you can certainly do that, ommitting the
    & and using the () will probably suit you better, at least until you
    get a handle on your personal preference and scripting needs.

    2. I strongly suggest you understand the last point. What I mean is
    that the body of your script contain only comments, variable
    declarations, and function calls. Your functionality is abstracted to
    your subroutines. This promotes clarity and modularity, and can help
    tremendously with debugging. It separates your logic from your
    behavior so you can think about your program logic without considering
    implementation. When you write your functions, you don't have to think
    about your logic.

    I frequently find myself writing the logic in pseudo code as comments,
    writing subroutines that implement peices of the logic, and adding the
    call to the main script using the pseudo comments as documentation.
    This isn't a good way to write big applications, but it is a good way
    to develop small to moderate size scripts.

    CC
     
    ccc31807, Mar 20, 2008
    #10
  11. Abigail wrote:
    > _
    > RedGrittyBrick wrote:
    > ::

    <snip>
    > ::
    > :: Edager W. Dijkstra. Go To Statement Considered Harmful. 1968.
    > ::
    > :: In nearly 30 years of programming I have completely avoided use of GOTO
    > :: in a professional context. All I have seen continues to convince me that
    > :: Dijkstra was right on this matter. YMMV.
    >
    > Dijkstra also wrote:
    >
    > "Please don't fall into the trap of believing that I am terribly
    > dogmatic about [the goto statement]. I have the uncomfortable
    > feeling that others are making a religion out of it, as if the
    > conceptual problems of programming could be solved by a simple
    > trick, by a simple form of coding disciple!"
    >
    > Edsger W. Dijkstra, personal communication, 1973.
    > Quoted by Donald E. Knuth, "Structured Programming with the go to
    > Statement", 1974.
    >
    > What Knuth and Dijkstra are saying is that it's not so much the use of
    > "goto" that should be avoided, the real horror is unstructured programming.
    > But most people only know the title of Dijkstra's paper, and not the
    > content [1], let alone know what others have to say about it.


    Guilty as charged. Perhaps I am unlucky in that almost all the examples
    of GOTO I have had to wrestle with, have been in examples of "spaghetti
    programming". It is certainly possible to write spaghetti code without
    using GOTO, but use of GOTO seems to encourage this trend in many
    programmers.

    >
    >
    > I'm not afraid to confess I do use goto. I prefer:
    >
    > again:
    > my $result = do_something;
    > goto again if it_failed;
    >
    > over
    >
    > my $result;
    > my $success = 0;
    > until ($success) {
    > $result = do_something;
    > $success = 1 unless it_failed;
    > }


    OK. I don't prefer the former, but I see your point.

    However, in this case do_something is three hundred lines, I hope you'd
    consider putting it into a subroutine do_something() - or perhaps
    re-factoring into several subroutines. The OP is looking for an
    "alternative strategy" that doesn't involve subroutines. The OP appears
    to be hoping that using GOTO will avoid the perceived difficulty of
    reorganising code into well-formed subroutines or objects and methods.

    I infer the OP prefers

    ...
    <stuff>
    ...
    <perhaps hundreds of lines of intervening code>
    ...
    <similar stuff>
    ...

    to be transformed into something like

    ...
    my second_time = 0;
    stuff:
    <stuff probably containing many IFs / GOTOs for dissimilar bits>
    if (second_time) goto continuation
    ...
    <perhaps hundreds of lines of intervening code>
    ...
    second_time = 1;
    goto stuff:
    continuation:
    ...

    instead of

    ...
    stuff("foo", ...);
    ...
    <perhaps hundreds of lines of intervening code>
    ...
    stuff("bar", ...);
    ...

    sub stuff {
    <various stuff>
    }

    I still feel that re-factoring unwieldy and repetitive code into
    subroutines (or objects and methods) is a more useful skill to learn
    than how to sprinkle GOTO statements into that unwieldy code.

    --
    RGB
     
    RedGrittyBrick, Mar 20, 2008
    #11
  12. Ela

    John Bokma Guest

    RedGrittyBrick <> wrote:

    > In nearly 30 years of programming I have completely avoided use of
    > GOTO in a professional context. All I have seen continues to convince
    > me that Dijkstra was right on this matter. YMMV.


    So you avoid last, next, etc. and returns in the middle of subs as well?
    To me those are all forms of GOTO.

    --
    John

    http://johnbokma.com/
     
    John Bokma, Mar 20, 2008
    #12
  13. Ela

    Guest

    John Bokma <> wrote:
    > RedGrittyBrick <> wrote:
    >
    > > In nearly 30 years of programming I have completely avoided use of
    > > GOTO in a professional context. All I have seen continues to convince
    > > me that Dijkstra was right on this matter. YMMV.

    >
    > So you avoid last, next, etc. and returns in the middle of subs as well?
    > To me those are all forms of GOTO.


    Where do you draw the line? All looping and branching are also forms of
    GOTO, if that is the way one wants to look at it.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Mar 20, 2008
    #13
  14. Ela

    John Bokma Guest

    wrote:

    > John Bokma <> wrote:
    >> RedGrittyBrick <> wrote:
    >>
    >> > In nearly 30 years of programming I have completely avoided use of
    >> > GOTO in a professional context. All I have seen continues to convince
    >> > me that Dijkstra was right on this matter. YMMV.

    >>
    >> So you avoid last, next, etc. and returns in the middle of subs as

    well?
    >> To me those are all forms of GOTO.

    >
    > Where do you draw the line?


    That's a good summary.

    --
    John

    http://johnbokma.com/
     
    John Bokma, Mar 20, 2008
    #14
  15. Ela

    ccc31807 Guest

    On Mar 20, 2:26 pm, wrote:
    > > So you avoid last, next, etc. and returns in the middle of subs as well?
    > > To me those are all forms of GOTO.

    >
    > Where do you draw the line? All looping and branching are also forms of
    > GOTO, if that is the way one wants to look at it.


    If you want to ~look~ at it, you can draw flow charts and make sure
    that each structure, sequential, looping, or selection, has only one
    entry point and one exit point. Alternatively, you can construct a
    control flow graph and make sure each structure has one start and one
    end node.

    All the next, last, redo, and return statements do is exit a loop
    according to the value of a variable. True, they are forms of a goto
    instruction, but I think we have the idea that goto implies goint to
    any arbitrary point in a program while the next, etc., just break out
    of the inmost loop (except for labeled loops, but even then they don't
    transfer control arbitrarily.)

    I think that the point is writing clear, concise, and even beautiful
    code, avoiding excessive subjectivism and ideosyncratic expressions,
    and following consistent stylistic conventions. This will never go out
    of style.

    I expect that in about twenty years, someone will write an article
    that Java will be considered harmful. This won't be the fault of Java,
    but of the habit of forcing all code to conform to OO conventions.
    This won't be Java's fault, but the fault of all those who conform
    excessively to the One True Way, and discover much later that it's
    just another way.

    CC
     
    ccc31807, Mar 20, 2008
    #15
  16. Ela

    Ben Morrow Guest

    Quoth Frank Seitz <>:
    >
    > Who the hell uses goto today???


    Depends on the language. While I have never used goto in Perl, it is
    common in C to see a function structured like the one below: see, for
    instance, much of the perl source. This is a consequence of having to
    de-allocate everything manually in C. Of course, one has to be careful:
    it is all to easy for such a function to degenerate into an
    incomprehensible mess.

    Ben

    int
    do_something(...)
    {
    Foo *foo;
    Bar *bar;
    int rv;

    foo = allocate_Foo();
    if (!foo) {
    rv = ENOFOO;
    goto out;
    }

    bar = allocate_Bar();
    if (!bar) {
    rv = ENOBAR;
    goto out_foo;
    }

    rv = try_something(foo, bar);
    if (rv < 0)
    goto out_bar;

    do_something_else();

    out_bar:
    free_Bar(bar);

    out_foo:
    free_Foo(foo);

    out:
    return rv;
    }
     
    Ben Morrow, Mar 20, 2008
    #16
  17. Ela

    szr Guest

    Ben Morrow wrote:
    > Quoth Frank Seitz <>:
    >>
    >> Who the hell uses goto today???

    >
    > Depends on the language. While I have never used goto in Perl


    Just a sort of a semi-tangent question, isn't using next and last with
    labels (to, say, break out of a parent loop from an inner loop in a set
    of nested loops) implicitly using `goto` ? If you think about it, the
    syntax is the same:

    Loop1: while (...) {
    Loop2: until (...) {
    if (some_condition) { last Loop1; }
    elsif (some_other_cond_a) { next Loop1; }
    elsif (some_other_cond_b) { redo Loop1; }
    }
    }

    I'm sure most everyone has used this sort of construct at some point or
    another to break from an outer loop from within an inner one.

    Correct me if I'm wrong, but are not last/next/redo with labels basic
    `goto` statements that enact a last, next, or redo on the loop
    associated with the label?

    Does this constitute a necessary evil, or more rather, demonstrates an
    instance where `goto` (in some form) has a place?

    --
    szr
     
    szr, Mar 21, 2008
    #17
  18. "szr" <> writes:
    > Correct me if I'm wrong, but are not last/next/redo with labels basic
    > `goto` statements that enact a last, next, or redo on the loop
    > associated with the label?


    Not exactly. Since you can only use them to go up the call stack another
    way to think of them is as special exceptions with built-in handlers.

    For real fun, see common lisp's condition/restart system.

    In any case everything that alters the program flow can ultimately be
    seen as a (conditional) goto. Even such basic operators as && and if()

    > Does this constitute a necessary evil, or more rather, demonstrates an
    > instance where `goto` (in some form) has a place?


    It just demonstrates a useful pattern for program flow, which IMO is
    better handled by having explicit operators with predefined behaviour
    than by goto. The main problem with goto for me is that it's so
    unrestricted it *can* lead to code that's very hard to understand and
    bugs that are hard to analyze, not that it's inherently evil or anything
    like that.

    Perl has enough useful flow control operations and other features that
    it's rare to run into situations where goto() is the cleanest / clearest
    / obvious choice.

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 21, 2008
    #18
  19. Ela

    szr Guest

    Joost Diepenmaat wrote:
    > "szr" <> writes:
    >> Correct me if I'm wrong, but are not last/next/redo with labels basic
    >> `goto` statements that enact a last, next, or redo on the loop
    >> associated with the label?

    >
    > Not exactly. Since you can only use them to go up the call stack
    > another way to think of them is as special exceptions with built-in
    > handlers.


    Yeah but they seem to use the goto-label system in a way still (when
    using loops with labels.. see two paragraphs down.)

    > For real fun, see common lisp's condition/restart system.


    Will do.

    > In any case everything that alters the program flow can ultimately be
    > seen as a (conditional) goto. Even such basic operators as && and if()


    True. Though my point was a somewhat about the fact that they use the
    same labels that goto uses for it's jump destination so next/last/redo +
    label seemed like a goto with an additional instruction that acts on the
    loop belonging to that label's context.


    >> Does this constitute a necessary evil, or more rather, demonstrates
    >> an instance where `goto` (in some form) has a place?

    >
    > It just demonstrates a useful pattern for program flow, which IMO is
    > better handled by having explicit operators with predefined behaviour
    > than by goto.


    Agreed.

    > The main problem with goto for me is that it's so unrestricted it
    > *can*
    > lead to code that's very hard to understand and bugs that are hard to
    > analyze, not that it's inherently evil or anything like that.


    True. I've just always seen it something that does have it's place like
    anything else, and must be handled with much are when used (though I do
    not really explicitly use goto in my programs, just never found the
    need, to be perfecly honest :)

    > Perl has enough useful flow control operations and other features that
    > it's rare to run into situations where goto() is the cleanest /
    > clearest / obvious choice.


    And this is probably /why/ I've never really needed to use goto in Perl
    (though I also never needed to use it and c/c++ and the likes.)

    --
    szr
     
    szr, Mar 21, 2008
    #19
  20. Ela

    John Bokma Guest

    Lawrence Statton <> wrote:

    > John Bokma <> writes:
    >> RedGrittyBrick <> wrote:
    >>
    >> > In nearly 30 years of programming I have completely avoided use of
    >> > GOTO in a professional context. All I have seen continues to
    >> > convince me that Dijkstra was right on this matter. YMMV.

    >>
    >> So you avoid last, next, etc. and returns in the middle of subs as
    >> well? To me those are all forms of GOTO.
    >>

    >
    > One could put forward the argument: Those are syntactic sugar to cover
    > those cases where the "no goto" rule deserves to be excepted.


    Instead of rules I prefer to ask myself the following questions:

    1) can I understand my own code next month without effort (can I after
    one year)
    2) can a peer do the same?
    3) can someone who has some programming experience read the code without
    wasting too much time.

    I always get a good feeling if a customer contacts me that a
    modification has been made to my code and that it was easy to do so.

    Making up rules and then consider syntactic sugar exceptions sounds odd to
    me.

    --
    John

    http://johnbokma.com/
     
    John Bokma, Mar 21, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. falcon
    Replies:
    10
    Views:
    19,234
    Roedy Green
    Feb 24, 2006
  2. Replies:
    0
    Views:
    510
  3. Diego
    Replies:
    2
    Views:
    168
    Stefan Rusterholz
    Aug 16, 2008
  4. Fred
    Replies:
    5
    Views:
    204
    Joe Smith
    Feb 18, 2007
  5. king
    Replies:
    5
    Views:
    210
Loading...

Share This Page