Loading ...
Sorry, an error occurred while loading the content.

[OT] cperl-mode [Was Re: [extremeperl] Refactorings?]

Expand Messages
  • Drew Taylor
    Cool! I didn t know this trick. Hmmm, now I have one more reason I can give my coworker to use emacs instead of vi. ;-) Thanks Ilya! Since you seem to be the
    Message 1 of 14 , Jul 29, 2002
    • 0 Attachment
      Cool! I didn't know this trick. Hmmm, now I have one more reason I can give
      my coworker to use emacs instead of vi. ;-) Thanks Ilya! Since you seem to
      be the author of the cperl-mode bindings, where can I find docs on this
      wonderful mode's feature set?

      Drew

      At 07:29 PM 7/29/02 +0400, Ilya Martynov wrote:

      >This refactoring is so common that it is even supported by Emacs'
      >cperl-mode. Go on first line of if/unless/while etc block and just
      >press C-c C-t.

      ======================================================================
      Drew Taylor | Freelance web development using
      http://www.drewtaylor.com/ | perl/mod_perl/MySQL/postgresql/DBI
      mailto:drew@... | Email jobs at drewtaylor.com
      ----------------------------------------------------------------------
      Speakeasy.net: A DSL provider with a clue. Sign up today.
      http://www.speakeasy.net/refer/29655
      ======================================================================
    • Ilya Martynov
      ... DT Cool! I didn t know this trick. Hmmm, now I have one more reason I DT can give my coworker to use emacs instead of vi. ;-) Thanks Ilya! DT Since you
      Message 2 of 14 , Jul 29, 2002
      • 0 Attachment
        >>>>> On Mon, 29 Jul 2002 11:56:02 -0400, Drew Taylor <drew@...> said:

        DT> Cool! I didn't know this trick. Hmmm, now I have one more reason I
        DT> can give my coworker to use emacs instead of vi. ;-) Thanks Ilya!
        DT> Since you seem to be the author of the cperl-mode bindings, where
        DT> can I find docs on this wonderful mode's feature set?

        Well, I'm not it's author. From cperl.el:

        ;; Author: Ilya Zakharevich and Bob Olson
        ;; Maintainer: Ilya Zakharevich <ilya@...-state.edu>

        As for your question: look under menu Perl/Micro Docs when in buffer
        in cperl-mode. They are not complete but still you may find
        interesting things there.

        Also you can discover many intersing features just by going into
        customize section:

        M-x customize-group [ENTER] cperl [ENTER].

        --
        Ilya Martynov (http://martynov.org/)
      • Ged Haywood
        Hi there, ... Very simple ones. ... I suppose it s my age. I HATE Perl s statement modifiers. And I REALLY REALLY HATE unless . ... Like I said. ...
        Message 3 of 14 , Jul 29, 2002
        • 0 Attachment
          Hi there,

          On Mon, 29 Jul 2002, Rob Nagler wrote:

          > I'm trying to get an idea what people consider useful refactorings.

          Very simple ones.

          > The following refactoring is a very simple one, but I consider it
          > useful to demonstrate how Perl statement modifiers can be used

          I suppose it's my age.
          I HATE Perl's statement modifiers.
          And I REALLY REALLY HATE "unless".

          > I've got a number of other refactorings in my book, but some have said
          > they are too complicated.

          Like I said.

          > Thanks for the feedback.

          :)

          > ----------------------------------------------------------------
          > TITLE: Replace Conditional with Modifier
          >
          > SYNOPSIS
          >
          > You have an if statement with a one-line then clause.
          > Use a Perl statement modifier to keep data flow on the left.
          >
          > unless (defined($value)) {
          > return undef;
          > }
          >
          > becomes
          >
          > return undef unless defined($value);

          Notaroundhereitdoesn't! It becomes

          if(! defined($value) ) { return undef; }

          (and I really mean those curly braces:). (Well, actually, it was
          never "return something unless something" in the first place so the
          refactoring would never have been done anyway:).

          My view would be that undef would be an abnormal condition.
          I usually like my variables to be def. If they aren't def,
          then what's the point of creating them in the first place?
          Ergo, one would test for undef but expect the test to fail.
          Ergo, the return statement should be on the right where it
          doesn't get in the way when you're scanning down the left of
          the page to try to figure out WTBHIGO.

          > This refactoring is controversial, if you aren't used to it.

          Er, run that by me again?

          > It's common to use return, last, die, etc. in Perl. Early exits limit
          > the nesting depth.

          I'd have said early exits prevent program failures and may economize
          on processor cycles, but there we are.

          > Modifiers take this one step further by eliminating all nesting, if
          > possible.

          If eliminating nesting makes it harder to read then give me nesting.

          > The roots of programming are based in logic, not in cooking recipes.
          [snip]
          > This refactoring emulates the declarative style of Prolog.

          Argh++. Declarative is OK where it's OK. I feel it's not OK here.

          > For example, this is the wrong way to use this refactoring:
          >
          > $x = 39, delete($z{$y}) if $is_tuesday; # WRONG USAGE

          Obviously. (But now you're being silly. :)

          73,
          Ged.
        • Rob Nagler
          ... Every refactoring can be implemented in reverse. This is an important part of design by refactoring. This is the art of refactoring imo. The goal is
          Message 4 of 14 , Jul 29, 2002
          • 0 Attachment
            Ged Haywood writes:
            > > return undef unless defined($value);
            >
            > Notaroundhereitdoesn't! It becomes
            >
            > if(! defined($value) ) { return undef; }

            Every refactoring can be implemented in reverse. This is an important
            part of design by refactoring. This is the "art" of refactoring imo.
            The goal is eliminating redunancy in and adding clarity to the design.
            IMO, the extra braces are redundant. The negative test is less
            clear than a parenless unless. Some people like vi, others like emacs.

            Your choice of refactorings is a coding style issue. If your group
            hates unless, then don't use it. This doesn't invalidate the
            refactoring as a concept.

            > My view would be that undef would be an abnormal condition.
            > I usually like my variables to be def. If they aren't def,
            > then what's the point of creating them in the first place?

            Users sometimes don't enter anything. What's the integer value of the
            empty string? Many databases treat the empty string as NULL, which
            means you had better be consistent in your Perl for those databases
            that don't. :-(

            > Ergo, one would test for undef but expect the test to fail.

            The title of the example is "from_literal". You may or may not allow
            undef on a form field. This is a higher level application decision.
            The concept of undef is an important distinguishing factor from Java
            which does not allow undef for native types.

            > Ergo, the return statement should be on the right where it
            > doesn't get in the way when you're scanning down the left of
            > the page to try to figure out WTBHIGO.

            This again is a style issue, ex mea sententia. Some proponents of
            early exit recommend the exit be on the left and others recommend it
            on the right.

            > > This refactoring is controversial, if you aren't used to it.
            >
            > Er, run that by me again?

            If you are familiar with the refactoring, you might not consider it
            controversial. You might think: different strokes for for different
            folks. If you are unfamiliar with it, you might think: what a stupid
            idea. It's the Green Eggs and Ham thing. Try it, you'll like it, or
            at least respect its use by others.

            > > It's common to use return, last, die, etc. in Perl. Early exits limit
            > > the nesting depth.
            >
            > I'd have said early exits prevent program failures and may economize
            > on processor cycles, but there we are.

            This assumes reducing nesting depth prevents program failures. If I
            had made that leap of logic, I would have been blasted. ;-)

            > > Modifiers take this one step further by eliminating all nesting, if
            > > possible.
            >
            > If eliminating nesting makes it harder to read then give me nesting.

            I found Lisp hard to read until I programmed in it. Most people find
            Perl hard to read. Took me a while to get used to unless, but after
            seeing lots of Perl with and without it, my group and I now like it.

            > > The roots of programming are based in logic, not in cooking recipes.
            > [snip]
            > > This refactoring emulates the declarative style of Prolog.
            >
            > Argh++. Declarative is OK where it's OK. I feel it's not OK here.

            As I said, controversial.

            > > For example, this is the wrong way to use this refactoring:
            > >
            > > $x = 39, delete($z{$y}) if $is_tuesday; # WRONG USAGE
            >
            > Obviously. (But now you're being silly. :)

            Here's some code from another reviewer trying to correct what he
            thinks is an incorrect approach elsewhere in the book:

            if (/<[a-z]+[^>]*$/) { s/\n/ /; $_ .= <>};

            Looks quite similar to my example above, but maybe it's just a taste
            thing and mine is silly but this one is serious.

            Every refactoring has its limits. Its important to document where you
            think they are. Every limit has its exceptions. It's important to
            allow yourself to follow your own guidelines. In XP, just make sure
            everybody is in agreement about the limits and exceptions.

            Rob
          • chromatic
            ... I like this one, especially if you demonstrate that it s reversable. I only have one nitpick. ... if undef is intended to return a demonstrably false
            Message 5 of 14 , Jul 29, 2002
            • 0 Attachment
              On Monday 29 July 2002 08:02, Rob Nagler wrote:

              > The following refactoring is a very simple one, but I consider it
              > useful to demonstrate how Perl statement modifiers can be used and to
              > introduce the mechanism by which a document refactorings. The format
              > is borrowed from Fowler's Refactoring book (which I highly recommend,
              > btw).

              I like this one, especially if you demonstrate that it's reversable. I only
              have one nitpick.

              > unless (defined($value)) {
              > return undef;
              > }
              >
              > becomes
              >
              > return undef unless defined($value);

              if 'undef' is intended to return a demonstrably false value, this code is a
              bit broken in list context.

              my @list = undef;
              print "True\n" if @list;

              It's very probably not germane to the example, but a book about good Perl
              development ought to mind context. I generally ask "Did you really mean
              this?" when I see it during code reviews.

              Best,
              -- c
            • Rob Nagler
              ... I hope to avoid showing the reverse of every refactoring. It maybe makes sense to show one or two explicitly. ... No, you need to check if it is undef.
              Message 6 of 14 , Jul 29, 2002
              • 0 Attachment
                chromatic writes:
                > I like this one, especially if you demonstrate that it's reversable.

                I hope to avoid showing the reverse of every refactoring. It maybe
                makes sense to show one or two explicitly.

                > if 'undef' is intended to return a demonstrably false value, this code is a
                > bit broken in list context.
                >
                > my @list = undef;
                > print "True\n" if @list;

                No, you need to check if it is undef. However, I'm going to change
                the example to eliminate the "unless" and "undef" parts. They
                distract from the refactoring which is about statement modifiers.

                > It's very probably not germane to the example, but a book about good Perl
                > development ought to mind context. I generally ask "Did you really mean
                > this?" when I see it during code reviews.

                I think it is inefficient to write:

                return wantarray ? () : undef;

                when the routine returns a scalar. The caller should read the doc or
                code. If you are building large applications in Perl, you need to
                respect the declarations. The unit and acceptance tests will help
                protect against mistakes, but you can't give a kid Perl and say "go
                write an accounting system". Here's a better description of what I mean:

                Java was, as Gosling says in the first Java white paper, designed
                for average programmers. It's a perfectly legitimate goal to
                design a language for average programmers. (Or for that matter for
                small children, like Logo.) But it is also a legitimate, and very
                different, goal to design a language for good programmers.

                See http://www.paulgraham.com/arcll1.html and other articles by Paul
                Graham.

                I think Perl in-the-small is a fine language for just about anybody.
                Perl in-the-large is another beast entirely. You have to respect
                interfaces and have an agreed on coding style. I contend you will
                need OO. You need to build abstractions (e.g. lightweight languages)
                which map domain knowledge succinctly. The power of Perl in-the-large
                is that I can let domain experts program Perl in-the-small with
                "terms" (APIs) developed by Perl experts.

                Rob
              • chromatic
                ... That s fine. It s important to demonstrate that you don t always go in one direction. ... The bare return operator respects the calling context: sub false
                Message 7 of 14 , Jul 29, 2002
                • 0 Attachment
                  On Monday 29 July 2002 22:09, Rob Nagler wrote:

                  > chromatic writes:
                  > > I like this one, especially if you demonstrate that it's reversable.
                  > I hope to avoid showing the reverse of every refactoring. It maybe
                  > makes sense to show one or two explicitly.

                  That's fine. It's important to demonstrate that you don't always go in one
                  direction.

                  > I think it is inefficient to write:
                  >
                  > return wantarray ? () : undef;
                  >
                  > when the routine returns a scalar. The caller should read the doc or
                  > code.

                  The bare return operator respects the calling context:

                  sub false {
                  return;
                  }

                  my @list = false;
                  my $scalar = false;

                  print "list true" if @list;
                  print "scalar true" if $scalar;
                  print scalar @list;

                  Outside of this example, I do agree that explicit interfaces are important for
                  large applications.

                  > I'm going to change the example to eliminate the "unless" and "undef" parts.
                  > They distract from the refactoring which is about statement modifiers.

                  I think that's wise. They distracted two of us. ;)

                  Regards,
                  -- c
                • Ged Haywood
                  Hi all, ... 73, Ged.
                  Message 8 of 14 , Jul 30, 2002
                  • 0 Attachment
                    Hi all,

                    On Mon, 29 Jul 2002, chromatic wrote:

                    > On Monday 29 July 2002 22:09, Rob Nagler wrote:
                    >
                    > > I'm going to change the example to eliminate the "unless" and "undef" parts.
                    > > They distract from the refactoring which is about statement modifiers.
                    >
                    > I think that's wise. They distracted two of us. ;)

                    :)

                    73,
                    Ged.
                  • Rob Nagler
                    ... Will do. ... Well, you learn something new everyday. :) Thanks! Rob
                    Message 9 of 14 , Jul 30, 2002
                    • 0 Attachment
                      chromatic writes:
                      > That's fine. It's important to demonstrate that you don't always go in one
                      > direction.

                      Will do.

                      > The bare return operator respects the calling context:

                      Well, you learn something new everyday. :) Thanks!

                      Rob
                    • Stephen Nelson
                      I ve got a few refactorings on my Perlmonks homenode: http://www.perlmonks.org/index.pl?node_id=2329 There are also references to other refactorings there. I d
                      Message 10 of 14 , Jul 30, 2002
                      • 0 Attachment
                        I've got a few refactorings on my Perlmonks homenode:

                        http://www.perlmonks.org/index.pl?node_id=2329

                        There are also references to other refactorings there. I'd appreciate
                        any feedback.

                        Rob Nagler wrote:

                        > I'm trying to get an idea what people consider useful refactorings.
                        >
                        > The following refactoring is a very simple one, but I consider it
                        > useful to demonstrate how Perl statement modifiers can be used and to
                        > introduce the mechanism by which a document refactorings. The format
                        > is borrowed from Fowler's Refactoring book (which I highly recommend,
                        > btw).
                        >
                        > I've got a number of other refactorings in my book, but some have said
                        > they are too complicated. I'll send out a few refactorings later
                        > after I've got some feedback on the format and what your own
                        > refactorings.
                        >
                        > Thanks for the feedback.
                        >
                        > Rob
                        > ----------------------------------------------------------------
                        > TITLE: Replace Conditional with Modifier
                        >
                        > SYNOPSIS
                        >
                        > You have an if statement with a one-line then clause.
                        > Use a Perl statement modifier to keep data flow on the left.
                        >
                        > unless (defined($value)) {
                        > return undef;
                        > }
                        >
                        > becomes
                        >
                        > return undef unless defined($value);
                        >
                        >
                        > MOTIVATION
                        >
                        > This refactoring is controversial, if you aren't used to it.
                        > I find modifiers are a useful programming technique, when they are
                        > available. We use them in natural language prose where it makes
                        > sense. The preceding three sentences are completely normal in
                        > English even if they sound weird all in a row. The fact is on
                        > the left of a qualifying clause. It puts the action up front so
                        > you know what might happen, given a set of circumstances.
                        >
                        > It's common to use return, last, die, etc. in Perl. Early exits limit
                        > the nesting depth. This is a good thing. Modifiers take this one
                        > step further by eliminating all nesting, if possible. This keeps data
                        > flow on the left, which makes it easier to see the side effects, such
                        > as early exit.
                        >
                        > The roots of programming are based in logic, not in cooking recipes.
                        > It seems we often forget this. In mathematical theorems, statements
                        > are often followed by qualifying clauses such as such that and iff.
                        > Most functional languages put the conditional on the left, which is
                        > probably a historical artifact of Lisp, a prefix notation language.
                        > In Prolog, rules are expressed as a fact followed by a condition.
                        > This refactoring emulates the declarative style of Prolog.
                        >
                        > You shouldn't use this refactoring to slam as many separate statements
                        > into a single line as possible. For example, this is the wrong way to
                        > use this refactoring:
                        >
                        > $x = 39, delete($z{$y}) if $is_tuesday; # WRONG USAGE
                        >
                        > This line defeats the motivation of keeping the data flow on the left.
                        > Too much is happening in one line, and the data operations are
                        > complete unrelated. This example obfuscates the data flow instead of
                        > improving it.
                        >
                        > You can convert any if statement into a
                        > do-if, e.g.
                        >
                        > do { # WRONG USAGE
                        > $x = 39;
                        > delete($z{$y});
                        > } if $is_tuesday;
                        >
                        > This doesn't save nesting. There's more code than a simple if
                        > statement. We aren't trying to put all conditionals last. That's as
                        > unnatural as ending all conditional English statements with modifying
                        > clauses.
                        >
                        > MECHANICS
                        >
                        > 1. If the conditional part declares a temporary
                        > my variable, move the declaration part out.
                        >
                        > 2. Remove the braces from the statement and switch the conditional
                        > order. Do not change the conditional logic.
                        >
                        > EXAMPLE
                        >
                        > Here's a method with two one-line if statements:
                        >
                        > sub from_literal {
                        > my(undef, $value) = @_;
                        > unless (defined($value)) {
                        > return undef;
                        > }
                        > $value =~ s/^\s+|\s+$//g;
                        > unless (defined($value)) {
                        > return undef;
                        > }
                        > return $value;
                        > }
                        >
                        > We transform the two conditionals into modified statements:
                        >
                        > sub from_literal {
                        > my(undef, $value) = @_;
                        > return undef unless defined($value);
                        > $value =~ s/^\s+|\s+$//g;
                        > return undef unless length($value);
                        > return $value;
                        > }
                        >
                        >
                        >
                        > Yahoo! Groups Sponsor
                        > ADVERTISEMENT
                        > <http://rd.yahoo.com/M=228862.2128520.3581629.1829184/D=egroupweb/S=1705007181:HM/A=1155069/R=0/*http://adfarm.mediaplex.com/ad/ck/990-1736-1039-302>
                        >
                        >
                        >
                        > To unsubscribe from this group, send an email to:
                        > extremeperl-unsubscribe@yahoogroups.com
                        >
                        >
                        >
                        > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service
                        > <http://docs.yahoo.com/info/terms/> .
                        > .




                        [Non-text portions of this message have been removed]
                      • Adrian Howard
                        ... [snip] Okay... here s one. (I don t have my Fowler to hand, so please excuse me if I wander off the standard format :-) ... TITLE: HashBecomesObject
                        Message 11 of 14 , Jul 30, 2002
                        • 0 Attachment
                          On Monday, July 29, 2002, at 04:02 pm, Rob Nagler wrote:

                          > I'm trying to get an idea what people consider useful refactorings.
                          [snip]

                          Okay... here's one.

                          (I don't have my Fowler to hand, so please excuse me if I wander off
                          the "standard" format :-)

                          ---

                          TITLE: HashBecomesObject

                          SYNOPSIS:

                          Turn a hash that represents a separate entity into an blessed object
                          that reflects it's purpose.

                          $Tests->{$class}->{$method}->{num_tests} = 4;
                          $Tests->{$class}->{$method}->{type}->{setup} = 1;
                          $Tests->{$class}->{$method}->{type}->{teardown} = 1;

                          becomes:

                          my $info = bless {}, 'Test::MethodInfo';
                          $info->{num_tests} = 4;
                          $info->{type}->{setup} = 1;
                          $info->{type}->{teardown}=1;
                          $Tests->{$class}->{$method} = $info;

                          MOTIVATION:

                          Perl lets you quickly create complex data-structures out of
                          hashes-of-hashes, often acting as simple collections.

                          These can quickly become hard to comprehend, use and maintain.

                          If a part of a hash-of-hashes (or a hash all by it's lonesome) makes
                          sense as a separate entity, turn it into an blessed hash.

                          This acts as a precursor to things like ExtractClass and allows
                          HashAccessBecomesMethodCall for your new object (I'll leave
                          HashAccessBecomesMethodCall, and the obvious ObjectBecomesHash as
                          exercises for the reader :-)

                          ----

                          I'm tempted to stick up a perl refactoring wiki (or is there one
                          already hiding in a corner somewhere?)... Anybody second the
                          suggestion?

                          Adrian
                          --
                          Adrian Howard <adrianh@...>
                          phone: 01929 550720 fax: 0870 131 3033 www.quietstars.com
                        • Stephen Nelson
                          Seconded.... I ve been planning on doing that for way too long. ... [Non-text portions of this message have been removed]
                          Message 12 of 14 , Jul 30, 2002
                          • 0 Attachment
                            Seconded.... I've been planning on doing that for way too long.

                            Adrian Howard wrote:

                            > On Monday, July 29, 2002, at 04:02 pm, Rob Nagler wrote:
                            >
                            > > I'm trying to get an idea what people consider useful refactorings.
                            > [snip]
                            >
                            > Okay... here's one.
                            >
                            > (I don't have my Fowler to hand, so please excuse me if I wander off
                            > the "standard" format :-)
                            >
                            > ---
                            >
                            > TITLE: HashBecomesObject
                            >
                            > SYNOPSIS:
                            >
                            > Turn a hash that represents a separate entity into an blessed object
                            > that reflects it's purpose.
                            >
                            > $Tests->{$class}->{$method}->{num_tests} = 4;
                            > $Tests->{$class}->{$method}->{type}->{setup} = 1;
                            > $Tests->{$class}->{$method}->{type}->{teardown} = 1;
                            >
                            > becomes:
                            >
                            > my $info = bless {}, 'Test::MethodInfo';
                            > $info->{num_tests} = 4;
                            > $info->{type}->{setup} = 1;
                            > $info->{type}->{teardown}=1;
                            > $Tests->{$class}->{$method} = $info;
                            >
                            > MOTIVATION:
                            >
                            > Perl lets you quickly create complex data-structures out of
                            > hashes-of-hashes, often acting as simple collections.
                            >
                            > These can quickly become hard to comprehend, use and maintain.
                            >
                            > If a part of a hash-of-hashes (or a hash all by it's lonesome) makes
                            > sense as a separate entity, turn it into an blessed hash.
                            >
                            > This acts as a precursor to things like ExtractClass and allows
                            > HashAccessBecomesMethodCall for your new object (I'll leave
                            > HashAccessBecomesMethodCall, and the obvious ObjectBecomesHash as
                            > exercises for the reader :-)
                            >
                            > ----
                            >
                            > I'm tempted to stick up a perl refactoring wiki (or is there one
                            > already hiding in a corner somewhere?)... Anybody second the
                            > suggestion?
                            >
                            > Adrian
                            > --
                            > Adrian Howard <adrianh@...>
                            > phone: 01929 550720 fax: 0870 131 3033 www.quietstars.com
                            >
                            >
                            > Yahoo! Groups Sponsor
                            > ADVERTISEMENT
                            > <http://rd.yahoo.com/M=228862.2128520.3581629.1829184/D=egroupweb/S=1705007181:HM/A=1155070/R=0/*http://adfarm.mediaplex.com/ad/ck/990-1736-1039-302>
                            >
                            >
                            >
                            > To unsubscribe from this group, send an email to:
                            > extremeperl-unsubscribe@yahoogroups.com
                            >
                            >
                            >
                            > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service
                            > <http://docs.yahoo.com/info/terms/> .
                            > .




                            [Non-text portions of this message have been removed]
                          Your message has been successfully submitted and would be delivered to recipients shortly.