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

Re: [Clip] Understanding Writing Subroutines

Expand Messages
  • Don - htmlfixit.com
    ... I think that to be bad form even if functional as using the command makes it clearer what you are doing. It also has a much greater probability of working
    Message 1 of 11 , Apr 13, 2006
      >>When calling the custom function (or sub-routine) you do not need to
      >>use the ^!Clip command (even though you are calling a clip). When
      >>NoteTab does not recognise the function name ^$m2y()$ it looks for a
      >>clip m2y in your current library and starts it.

      I think that to be bad form even if functional as using the command
      makes it clearer what you are doing. It also has a much greater
      probability of working over time should they later make an update to the
      software as they almost always have reverse engineered commands and
      functions.
    • Alan_C
      ... FWIW though, a (called, child) clip written by Fookes software calls (the child clip in turn then calls/uses) a custom function does so not via clip but
      Message 2 of 11 , Apr 13, 2006
        On Thursday 13 April 2006 12:10, Don - htmlfixit.com wrote:
        > >>When calling the custom function (or sub-routine) you do not need to
        > >>use the ^!Clip command (even though you are calling a clip). When
        > >>NoteTab does not recognise the function name ^$m2y()$ it looks for a
        > >>clip m2y in your current library and starts it.
        >
        > I think that to be bad form even if functional as using the command
        > makes it clearer what you are doing. It also has a much greater
        > probability of working over time should they later make an update to the
        > software as they almost always have reverse engineered commands and
        > functions.

        FWIW though, a (called, child) clip written by Fookes software calls (the
        child clip in turn then calls/uses) a custom function does so not via clip
        but via function name:

        H="_BuildScript"
        ^!Set %Index%=0
        ^!Set %Count%=^%FieldNames0%

        :StartLoop
        ^!Inc %Index%
        ^!If ^%Index% > ^%Count% EndLoop
        ^!Set %FieldName%=^%FieldNames^%Index%%
        ^!IfTrue ^$IsEmpty(^%FieldName%)$ StartLoop
        ^!Set ^%FieldName%=^$GetXmlField(^%FieldName%)$

        ^^^^^^

        ^$GetXmlField()$

        http://www.google.com/search?q=site%3Anotetab.com+xml&start=0&ie=utf-8&oe=utf-8&client=firefox-a&rls=org.mozilla:en-US:official

        http://www.notetab.com/pad/index.htm

        That particular (sub routine) clip is near the bottom of PAD.clb
        -------------------

        Earlier, I'd overlooked the possibility of custom function.

        I never got much into custom function. I long since learned enough of Perl
        which happens to integrate well/nicely with Notetab.

        Learning curve for Perl (EZ stuff is EZ, happens quick in Perl) but to get to
        intermediate to advanced I found learn curve higher and longer than NTB clip.

        But I find that Perl uses way less code than clip. And (after some Perl
        experience) I find Perl significantly easier to track/follow/decipher than
        clip (for example, the PAD.clb to track/follow *understand* what makes it
        tick, how it does what it does) (decipher, key, *access* myself *into* it).

        Idiomatic Perl. get to know it and then now I got it. A *very* expressive
        language -- so much so that some do not like it because of the height of its
        expressivenes. I experience Perl as fun!

        But this is me. I've no idea if it's consensus of others or not. (obviously
        one needs to Perl in order to comment).

        So I (for myself) just write a Perl script/clip rather than a NTB custom
        function.

        And I didn't see a prob with:

        ; 4 speed and not see it happen
        ^!SetScreenUpdate OFF
        ^!Toolbar "new document"
        ; dump var's content to doc here
        ^!Find
        ^!Replace
        ; etc.
        ^!select ALL
        ; back into var
        ^!Set %my_var%(get_selection)
        ; close discard doc here
        ; got what I wanted done onto my var's content

        Notetab lets us choose. We each get to do it how chosen. No prob with that!
        Must be good news!

        And a custom function only needs Notetab, not needs perl installed in the case
        of sharing clip library with other Notetab users.

        --
        Alan.
      • Bob McAllister
        ... Don I guess that you could argue it to be bad form in some abstract computer science sense, but it does happen to be how Eric wrote NoteTab. Have a look
        Message 3 of 11 , Apr 13, 2006
          On 4/14/06, Don - htmlfixit.com <don@...> wrote:

          > I think that to be bad form even if functional as using the command
          > makes it clearer what you are doing. It also has a much greater
          > probability of working over time should they later make an update to the
          > software as they almost always have reverse engineered commands and
          > functions.
          >

          Don

          I guess that you could argue it to be "bad form" in some abstract
          computer science sense, but it does happen to be how Eric wrote
          NoteTab. Have a look at the Custom Functions page in Clip Help where
          it is described as "an approach similar to the ^!Clip command".

          As (the other) Bob found, trying to stick a ^!Clip command in front of
          a custom function, such as ^$m2y()$, is redundant and the resulting
          code just does not work.

          You can call the clip m2y with ^!Clip m2y (which I infer to be your
          preference) but lose the ability to pass a parameter, which was the
          point of the whole exercise.

          Bob McAllister
        • rpdooling
          Don, Bob, et al. I haven t read the entire thread closely, just parts of it. But don t you guys think you re testing the limits of clip code? We had this
          Message 4 of 11 , Apr 13, 2006
            Don, Bob, et al.

            I haven't read the entire thread closely, just parts of it. But don't
            you guys think you're testing the limits of clip code? We had this
            discussion once before, I think.

            Personally I believe that's why Eric made it so easy to call a Perl or
            Gawk script, because when you start wanting to do things like pass
            variables or do sophisticated regex you're probably better off just
            biting the bullet and learning a little Perl or Python or any of the
            other scripting languages you can call from within NoteTab.

            Just one man's opinion.

            rpd

            --- In ntb-clips@yahoogroups.com, "Bob McAllister" <fortiter@...> wrote:
            >
            > On 4/14/06, Don - htmlfixit.com <don@...> wrote:
            >
            > > I think that to be bad form even if functional as using the command
            > > makes it clearer what you are doing. It also has a much greater
            > > probability of working over time should they later make an update
            to the
            > > software as they almost always have reverse engineered commands and
            > > functions.
            > >
            >
            > Don
            >
            > I guess that you could argue it to be "bad form" in some abstract
            > computer science sense, but it does happen to be how Eric wrote
            > NoteTab. Have a look at the Custom Functions page in Clip Help where
            > it is described as "an approach similar to the ^!Clip command".
            >
            > As (the other) Bob found, trying to stick a ^!Clip command in front of
            > a custom function, such as ^$m2y()$, is redundant and the resulting
            > code just does not work.
            >
            > You can call the clip m2y with ^!Clip m2y (which I infer to be your
            > preference) but lose the ability to pass a parameter, which was the
            > point of the whole exercise.
            >
            > Bob McAllister
            >
          • Don - htmlfixit.com
            sombody wrote; ... And here I thought you were a smart person??? The Answer: Of course not, clip code has no limits ... only limits on how you can get it to do
            Message 5 of 11 , Apr 14, 2006
              sombody wrote;
              > But don't
              > you guys think you're testing the limits of clip code?

              And here I thought you were a smart person???
              The Answer: Of course not, clip code has no limits ... only limits on
              how you can get it to do it ... not whether it can do it.

              But more seriously, I would say no for the following reasons:
              1. I often and regularly write clips for other people for fun and/or
              very modest profit ... and they often don't have perl/gawk/etc. so I
              would have to get them to where I am with a language installed locally
              instead of just writing the clip.

              2. I often write a clip and email it to someone when I will be helping
              that someone else. I then only need to install notetab light on their
              computer and run the clip ... same point, I haven't cluttered up their
              computer with a program they won't later use (cause they will use
              notetab but not perl later).

              3. Why do it the easy way when the very reason I compute is for the
              challenge of it? To me this is like doing jigsaw puzzles. It keeps me
              sharper than I might otherwise be (don't even ponder how dense that
              might be).

              4. There often is a better tool to do job a OR b OR c, but seldom one
              that can do a AND b AND c ... but notetab can.

              I have taken to writing subroutines (if that is what we will call them)
              after our prior discussions unlocked the concept a little further. I
              have come to find them very handy. I will pass parameters by using a
              two line call:
              line one sets the variables that will be used in the subroutine
              and line two calls the subroutine that then has those variables
              available to it when it runs ...
              and when I get back, the variables are essentially the returned values
              because they are again available in the clip.

              Because in this example the "function" to be performed in the subroutine
              is a one liner, there is no advantage to the subroutine, but if the
              subroutine is a 30 line thing ... well then yes it would be worth it if
              reused.

              I also find it a great way to write portable bits of code. For example
              I wrote one to adjust back and forth between light and pro for the
              replace line feed situation (that I call a bug). I have used the same
              subroutine to correct that in several clips now by calling it as a
              subroutine clip.

              Thems my thoughts on it.

              D
            • Don - htmlfixit.com
              ... I didn t realize that this was a custom function. I guess you are correct and that won t go away. I also see what you say about passing a parameter. It
              Message 6 of 11 , Apr 15, 2006
                Bob McAllister wrote:
                > I guess that you could argue it to be "bad form" in some abstract
                > computer science sense, but it does happen to be how Eric wrote
                > NoteTab. Have a look at the Custom Functions page in Clip Help where
                > it is described as "an approach similar to the ^!Clip command".
                >
                I didn't realize that this was a custom function. I guess you are
                correct and that won't go away. I also see what you say about passing a
                parameter.

                It appears that the only way to pass a parameter is the highlight the
                "parameter" so the parameter must be in your text document? I remember
                trying to understand these a while back and thinking that it wasn't
                worth the effort. Here is how I have taken to using "subroutines" and
                as you see I am using an array to pass the parameters.

                H="first letter"
                ;set variables to be passed as parameters
                ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                ;call "subroutine"
                ^!Clip "grabfirstletters"
                ^!SetArray %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                ;call "subroutine"
                ^!Clip "grabfirstletters"


                H="_grabfirstletters"
                ^!Set %count%=1;%string%=""
                :Loop
                ^!Set %string%=^%string%^$StrCopyLeft("^%items^%count%%";1)$
                ^!Inc %count%
                ^!If ^%count% <= ^%items0% Loop
                ^!InsertText ^%string% = ^%items%^P
              • rpdooling
                All I m saying is, why not have NoteTab run a single Python script that fits on two lines: t = [ red , orange , yellow , green , blue , indigo , violet ]
                Message 7 of 11 , Apr 15, 2006
                  All I'm saying is, why not have NoteTab run a single Python script
                  that fits on two lines:

                  t = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
                  for color in t: print color[0],

                  >>r o y g b i v

                  Instead of having NoteTab run two clips worth of code:

                  H="first letter"
                  ;set variables to be passed as parameters
                  ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                  ;call "subroutine"
                  ^!Clip "grabfirstletters"
                  ^!SetArray %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                  ;call "subroutine"
                  ^!Clip "grabfirstletters"

                  H="_grabfirstletters"
                  ^!Set %count%=1;%string%=""
                  :Loop
                  ^!Set %string%=^%string%^$StrCopyLeft("^%items^%count%%";1)$
                  ^!Inc %count%
                  ^!If ^%count% <= ^%items0% Loop
                  ^!InsertText ^%string% = ^%items%^P

                  And the remark in your last post about portability was off the mark.
                  If you write a script in Perl or Python you can run it in NoteTab on
                  Windows, in Emacs on Linux, in BBedit on Mac, and so on. That's what's
                  commonly called "portability." A clip can only be run in NoteTab.

                  Hey, I love NoteTab, too, but it's main attraction is that it's
                  extensible far beyond clip code.

                  rd


                  --- In ntb-clips@yahoogroups.com, "Don - htmlfixit.com" <don@...> wrote:
                  >
                  > Bob McAllister wrote:
                  > > I guess that you could argue it to be "bad form" in some abstract
                  > > computer science sense, but it does happen to be how Eric wrote
                  > > NoteTab. Have a look at the Custom Functions page in Clip Help where
                  > > it is described as "an approach similar to the ^!Clip command".
                  > >
                  > I didn't realize that this was a custom function. I guess you are
                  > correct and that won't go away. I also see what you say about
                  passing a
                  > parameter.
                  >
                  > It appears that the only way to pass a parameter is the highlight the
                  > "parameter" so the parameter must be in your text document? I remember
                  > trying to understand these a while back and thinking that it wasn't
                  > worth the effort. Here is how I have taken to using "subroutines" and
                  > as you see I am using an array to pass the parameters.
                  >
                  > H="first letter"
                  > ;set variables to be passed as parameters
                  > ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                  > ;call "subroutine"
                  > ^!Clip "grabfirstletters"
                  > ^!SetArray
                  %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                  > ;call "subroutine"
                  > ^!Clip "grabfirstletters"
                  >
                  >
                  > H="_grabfirstletters"
                  > ^!Set %count%=1;%string%=""
                  > :Loop
                  > ^!Set %string%=^%string%^$StrCopyLeft("^%items^%count%%";1)$
                  > ^!Inc %count%
                  > ^!If ^%count% <= ^%items0% Loop
                  > ^!InsertText ^%string% = ^%items%^P
                  >
                • rpdooling
                  On second thought, it all fits on ONE LINE, even though it probably wraps when posted: for color in [ red , orange , yellow , green , blue , indigo ,
                  Message 8 of 11 , Apr 15, 2006
                    On second thought, it all fits on ONE LINE, even though it probably
                    wraps when posted:

                    for color in ['red', 'orange', 'yellow', 'green', 'blue', 'indigo',
                    'violet']: print color[0],

                    rpd

                    --- In ntb-clips@yahoogroups.com, "rpdooling" <rpdooling@...> wrote:
                    >
                    > All I'm saying is, why not have NoteTab run a single Python script
                    > that fits on two lines:
                    >
                    > t = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
                    > for color in t: print color[0],
                    >
                    > >>r o y g b i v
                    >
                    > Instead of having NoteTab run two clips worth of code:
                    >
                    > H="first letter"
                    > ;set variables to be passed as parameters
                    > ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                    > ;call "subroutine"
                    > ^!Clip "grabfirstletters"
                    > ^!SetArray
                    %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                    > ;call "subroutine"
                    > ^!Clip "grabfirstletters"
                    >
                    > H="_grabfirstletters"
                    > ^!Set %count%=1;%string%=""
                    > :Loop
                    > ^!Set %string%=^%string%^$StrCopyLeft("^%items^%count%%";1)$
                    > ^!Inc %count%
                    > ^!If ^%count% <= ^%items0% Loop
                    > ^!InsertText ^%string% = ^%items%^P
                    >
                    > And the remark in your last post about portability was off the mark.
                    > If you write a script in Perl or Python you can run it in NoteTab on
                    > Windows, in Emacs on Linux, in BBedit on Mac, and so on. That's what's
                    > commonly called "portability." A clip can only be run in NoteTab.
                    >
                    > Hey, I love NoteTab, too, but it's main attraction is that it's
                    > extensible far beyond clip code.
                    >
                    > rd
                    >
                    >
                    > --- In ntb-clips@yahoogroups.com, "Don - htmlfixit.com" <don@> wrote:
                    > >
                    > > Bob McAllister wrote:
                    > > > I guess that you could argue it to be "bad form" in some abstract
                    > > > computer science sense, but it does happen to be how Eric wrote
                    > > > NoteTab. Have a look at the Custom Functions page in Clip Help where
                    > > > it is described as "an approach similar to the ^!Clip command".
                    > > >
                    > > I didn't realize that this was a custom function. I guess you are
                    > > correct and that won't go away. I also see what you say about
                    > passing a
                    > > parameter.
                    > >
                    > > It appears that the only way to pass a parameter is the highlight the
                    > > "parameter" so the parameter must be in your text document? I
                    remember
                    > > trying to understand these a while back and thinking that it wasn't
                    > > worth the effort. Here is how I have taken to using "subroutines"
                    and
                    > > as you see I am using an array to pass the parameters.
                    > >
                    > > H="first letter"
                    > > ;set variables to be passed as parameters
                    > > ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                    > > ;call "subroutine"
                    > > ^!Clip "grabfirstletters"
                    > > ^!SetArray
                    > %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                    > > ;call "subroutine"
                    > > ^!Clip "grabfirstletters"
                    > >
                    > >
                    > > H="_grabfirstletters"
                    > > ^!Set %count%=1;%string%=""
                    > > :Loop
                    > > ^!Set %string%=^%string%^$StrCopyLeft("^%items^%count%%";1)$
                    > > ^!Inc %count%
                    > > ^!If ^%count% <= ^%items0% Loop
                    > > ^!InsertText ^%string% = ^%items%^P
                    > >
                    >
                  • Bob McAllister
                    ... Don I have modified your two clips to use custom functions as below. H=first letter ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                    Message 9 of 11 , Apr 16, 2006
                      On 4/16/06, Don - htmlfixit.com <don@...> wrote:
                      > Here is how I have taken to using "subroutines" and
                      > as you see I am using an array to pass the parameters.
                      >
                      > H="first letter"
                      > ;set variables to be passed as parameters
                      > ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                      > ;call "subroutine"
                      > ^!Clip "grabfirstletters"
                      > ^!SetArray %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                      > ;call "subroutine"
                      > ^!Clip "grabfirstletters"

                      Don

                      I have modified your two clips to use custom functions as below.

                      H=first letter
                      ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                      ^$grabfirstletter(^%items%)$ = ^%items%^%NL%
                      ^!SetArray %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                      ^$grabfirstletter(^%items%)$ = ^%items%^%NL%

                      H=_grabfirstletter
                      ^!SetArray %wordlist%=^&
                      ^!Set %count%=1;%Result%=""
                      :Loop
                      ^!Set %Result%=^%Result%^$StrCopyLeft("^%wordlist^%count%%";1)$
                      ^!Inc %count%
                      ^!If ^%count% <= ^%items0% Loop

                      The key is the use of the "special variable" %Result% in the
                      definition of the custom function. That will be what is returned at
                      the end of the sub-routine and its value printed by the top-level clip
                      at the point where the custom function was called.

                      This is a general case where the "content" of your array variable
                      %items% is passed to the custom function (as ^&) and placed into a new
                      variable. It works regardless of the source of the passed parameter.

                      In your situation where tou already know the name of the variable
                      holding the data on which the function is to operate, I can
                      short-circuit by using that same variable in the custom function (and
                      so effectively pass an empty parameter).

                      The following clips implement that special case relying on knowing the
                      variable name in calling routine.
                      H=flspecialcase
                      ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                      ^$grabfirstletterx()$ = ^%items%^%NL%
                      ^!SetArray %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                      ^$grabfirstletterx()$ = ^%items%^%NL%

                      H=_grabfirstletterx
                      ^!Set %count%=1;%Result%=""
                      :Loop
                      ^!Set %Result%=^%Result%^$StrCopyLeft("^%items^%count%%";1)$
                      ^!Inc %count%
                      ^!If ^%count% <= ^%items0% Loop

                      There may be circumstances where you prefer this method.

                      Bob
                    • rpdooling
                      Bob, ... I have never seen that. That IS a nifty trick. Rick H=first letter ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                      Message 10 of 11 , Apr 17, 2006
                        Bob,

                        >> ^$grabfirstletter(^%items%)$ = ^%items%^%NL%

                        I have never seen that. That IS a nifty trick.

                        Rick


                        H=first letter
                        ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                        ^$grabfirstletter(^%items%)$ = ^%items%^%NL%
                        ^!SetArray %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                        ^$grabfirstletter(^%items%)$ = ^%items%^%NL%

                        H=_grabfirstletter
                        ^!SetArray %wordlist%=^&
                        ^!Set %count%=1;%Result%=""
                        :Loop
                        ^!Set %Result%=^%Result%^$StrCopyLeft("^%wordlist^%count%%";1)$
                        ^!Inc %count%
                        ^!If ^%count% <= ^%items0% Loop

                        --- In ntb-clips@yahoogroups.com, "Bob McAllister" <fortiter@...> wrote:
                        >
                        > On 4/16/06, Don - htmlfixit.com <don@...> wrote:
                        > > Here is how I have taken to using "subroutines" and
                        > > as you see I am using an array to pass the parameters.
                        > >
                        > > H="first letter"
                        > > ;set variables to be passed as parameters
                        > > ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                        > > ;call "subroutine"
                        > > ^!Clip "grabfirstletters"
                        > > ^!SetArray
                        %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                        > > ;call "subroutine"
                        > > ^!Clip "grabfirstletters"
                        >
                        > Don
                        >
                        > I have modified your two clips to use custom functions as below.
                        >
                        > H=first letter
                        > ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                        > ^$grabfirstletter(^%items%)$ = ^%items%^%NL%
                        > ^!SetArray
                        %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                        > ^$grabfirstletter(^%items%)$ = ^%items%^%NL%
                        >
                        > H=_grabfirstletter
                        > ^!SetArray %wordlist%=^&
                        > ^!Set %count%=1;%Result%=""
                        > :Loop
                        > ^!Set %Result%=^%Result%^$StrCopyLeft("^%wordlist^%count%%";1)$
                        > ^!Inc %count%
                        > ^!If ^%count% <= ^%items0% Loop
                        >
                        > The key is the use of the "special variable" %Result% in the
                        > definition of the custom function. That will be what is returned at
                        > the end of the sub-routine and its value printed by the top-level clip
                        > at the point where the custom function was called.
                        >
                        > This is a general case where the "content" of your array variable
                        > %items% is passed to the custom function (as ^&) and placed into a new
                        > variable. It works regardless of the source of the passed parameter.
                        >
                        > In your situation where tou already know the name of the variable
                        > holding the data on which the function is to operate, I can
                        > short-circuit by using that same variable in the custom function (and
                        > so effectively pass an empty parameter).
                        >
                        > The following clips implement that special case relying on knowing the
                        > variable name in calling routine.
                        > H=flspecialcase
                        > ^!SetArray %items%=red;orange;yellow;green;blue;indigo;violet
                        > ^$grabfirstletterx()$ = ^%items%^%NL%
                        > ^!SetArray
                        %items%=Mediocrity;Ego;Limits;Vanity;Incompetence;Name-calling
                        > ^$grabfirstletterx()$ = ^%items%^%NL%
                        >
                        > H=_grabfirstletterx
                        > ^!Set %count%=1;%Result%=""
                        > :Loop
                        > ^!Set %Result%=^%Result%^$StrCopyLeft("^%items^%count%%";1)$
                        > ^!Inc %count%
                        > ^!If ^%count% <= ^%items0% Loop
                        >
                        > There may be circumstances where you prefer this method.
                        >
                        > Bob
                        >
                      Your message has been successfully submitted and would be delivered to recipients shortly.