Author Topic: 'ReplaceText' lisp errors on first go ...  (Read 6225 times)

0 Members and 1 Guest are viewing this topic.

Hangman

  • Swamp Rat
  • Posts: 566
Re: 'ReplaceText' lisp errors on first go ...
« Reply #15 on: August 02, 2010, 01:45:49 PM »
Sorry I haven't commented recently, I've been pulled away for a few days.
Should be back on top of things once I get my head wrapped around this again.

K, I think thats all the pieces you need so-far. Read what i gave you several times, i was very literal in my wording.

BTW, How are we doing?

Phew, there's a lot of info there.  I do understand I think regarding the use of the variables now.  This has been a good description and learning experience.

I have a couple questions regarding what Lee mentioned:
Just to elaborate on this slightly, let us say we have two (or more) functions, and we wish for variables to be accessible in both, eg;

< ... > we define (and declare) the variable 'var1' in function foo and reference it in function bar. Notice that the variable is not localised in bar, as this would render it's value null upon calling bar from foo.

This is in essence, what I have going on in my code above.

This method of referencing variables between functions is called 'lexical scoping' if I remember from Se7en correctly...

So you can effectively view subfunctions as elegant 'space-savers', instead of duplicating code over and over.

IMO (for what its worth), I prefer to pass arguments where I can, and avoid referencing variables across multiple functions unless I absolutely have to - I feel this makes the intention clearer and easier to understand. Not to mention it makes the subfunction useful as a stand-alone function (or library function if you will).

Lee

Now I have read from other posts in the past that cutting and pasting code to put together a new routine is fine, as long as it all works out in the end.  I've found that errors can be horrendous by doing this unless you keep very careful track of everything.  But if you are cutting and pasting code from other routines, you will have a lot of these "Lexical scoping" issues.  By Lee's opinion, you don't like to do this, correct ??  You'd rather have one definition and the code inside to run from that definition.  Would you consider this a good practice though for it's purposes ??  I mean, I like 'lexical scoping' for several reasons; it can be used in other definitions without rewriting the code.  It makes the routine as a whole, easier to follow and troubleshoot as you are working with sections rather than the whole.  But there are the drawbacks, like as was mentioned, variables are referenced across multiple functions.

There was a lot of information given here, and there are still some things I am confused over, but I can't put my finger on them yet to post a question.  Or in other words, I haven't yet thought through it from beginning to end, to post a question that hasn't already been answered.

Now looking back at my code, I can see that the piece here:
Code: [Select]
(if (/= OldText "String")                         ; if NOT replacing entire string
    (SelectAllStrings)                              ; Then select ALL text
    (SelectEachString)                              ; Else select strings to be replaced
  ) ; _if
referencing these:
Code: [Select]
(defun SelectEachString (/ )
  (while (= AllText nil)
    (prompt "\nSelect text to be replaced: ")
    (setq AllText (ssget '((0 . "TEXT,MTEXT"))))    ; ,MULTILEADER
  )
  (ProcessText)
)
;
(defun SelectAllStrings (/ )
  (prompt "\nSelect text to be replaced (Press 'Enter' for all text in drawing): ")
  (setq AllText (ssget '((0 . "TEXT,MTEXT"))))
  (if (or (= AllText nil) (= AllText ""))
    (setq AllText (ssget "_X" '((0 . "TEXT,MTEXT")))); ,MULTILEADER
  )
  (ProcessText)
)
Could be all-inclusive to the main segment of code and probably save a few lines.  Although I don't see why it would matter (for this small piece of code) as there is no variables in either that are being referenced somewhere else.  From the main segment to these definitions, it is a simple open & close process.
The third section is different however, as it does go back and forth from the main section.

Can I assume you are seeing something in my code that is prompting you to go in this direction, that is, toward this instruction of variables ??
As CAB mentioned:
Hangman,
FYI, First thing you do when debugging is to disable the local error handler.

I ran the routine with out error but it did not replace the text. :-o

Which is what is happening to me as well.  What I am not understanding is I can edit the code with something simple like adding a comma to a comment line and saving the code and reloading it, and it works fine.  It is just the initial time it is loaded it will not run, it errors.
I know the error occurs in the main segment of code and not in any of the 'lexical scoping' sections (or 'sub-functions' perhaps?).  But there's another drawback to lexical scoping I guess, you can have a variable referenced in one of the sub-functions and it could cause an error in the main section.  But that doesn't make sense here (again, trying to think this through) as, by stepping through the code, it would have to get toward the end of the main section before transfering to the third definition (processtext) to find a variable NOT being initialized to cause an error.  And so far, it is not doing this.  My code is erroring before getting to the third definition, ... it is erroring before getting to the second definitions.

I am thinking if I rewrite this, I can probably make it work as I want it to, eliminating the error as I go.  But I want to find this error so I can avoid making the same mistake again later with some other similar piece of code I may put together.

Thank you for your continued help.
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Hangman

  • Swamp Rat
  • Posts: 566
Re: 'ReplaceText' lisp errors on first go ...
« Reply #16 on: August 02, 2010, 02:21:55 PM »
Lee,
< ... >  But then what do I know lol  :wink:

A lot more than me.   ^-^


Ok, so isn't your '( code eList )' considered a Lexical scope ??  Or am I missing the definition of Lexical scope ... being, in order to have a Lexical scope, the code has to be dependent upon something more.  Otherwise you would simply have a sub-function.
If this be the case, then according to my code;  the first and second sub-functions are just that, sub-functions.  The third 'sub-function' (ProcessText) is my lexical scope, because it IS dependent on other definitions or variables that are crossing.
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: 'ReplaceText' lisp errors on first go ...
« Reply #17 on: August 02, 2010, 02:30:55 PM »
Ok, so isn't your '( code eList )' considered a Lexical scope ??

No, as it is completely self-contained, i.e. it doesn't depend on variables from another function.

Consider this:

Code: [Select]
(defun f ( / a b c )

  (setq a 1 b 2 c 3)

  (g)
)

(defun g ( / )
  (* b 2)
)

Notice that 'g' depends on 'f' in that it ASSUMES that there will be a variable 'b' holding numerical data to work with.

Now consider this:

Code: [Select]
(defun f ( / a b c )

  (setq a 1 b 2 c 3)

  (g b)
)

(defun g ( x )
  (* x 2)
)

Now, 'g' does not depend on 'f' and makes no assumptions. When called, data for the argument 'x' must be supplied, and hence we are guaranteed that 'x' will contain data.


Hangman

  • Swamp Rat
  • Posts: 566
Re: 'ReplaceText' lisp errors on first go ...
« Reply #18 on: August 02, 2010, 02:41:08 PM »
Ok, let me paint a picture and see if I'm correct in my assessment.  I'm kind of stuck on this 'Lexical Scope' thing, as I think this is where my error is occuring, but I'm not positive.

Lexical scoping would be like this:

Say you are walking down the sidewalk.  You left foot is independent of your right foot.  They both work together to make the motion of moving forward, but they are each independent.  The same thing would apply if you were using crutches and your left foot was in a cast.  The left foot would be held above the sidewalk, not ever touching.  But the crutches would be working independent of the right foot, and assisting the right foot in making the forward motion.
This is what you are refering to with this:
Code: [Select]
(defun dxf ( code elist ) (cdr (assoc code elist)))
Now, if you had a cane rather than crutches, you would be dependent on the stability of the cane AND your left foot to cause the forward motion.  The right foot is independent of the left, but the left would be dependent on the cane.  So in order to get forward motion, the left foot would dependent on the variable 'cane'.
Code: [Select]
(defun dxf ( code ) (cdr (assoc code elist)))
Am I understanding this (Lexical scope) correctly ??


Doht !!  You posted just before I could get this out.  But yes, I now understand.  Your code explanation is better than my crutches/cane explanation too.   :-D

Again, Thank you for your time.  I'm going to go re-write my code now and see if I can't eliminate my Lexical scope issue and see if this will fix my error.
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: 'ReplaceText' lisp errors on first go ...
« Reply #19 on: August 02, 2010, 02:45:17 PM »
You're very welcome, I'm glad I could help you understand :-)

JohnK

  • Administrator
  • Seagull
  • Posts: 10627
Re: 'ReplaceText' lisp errors on first go ...
« Reply #20 on: August 02, 2010, 03:36:52 PM »
whoa?! NOTE: I havent read all the posts on the second page but i was hit by the phrase "lexical scope"...the example that LeeMac gave on the first page is NOT lexical scoping. That example is just an example of Global Variables. 

Im sorry Lee if i ever confused you but the example you gave is way off. Briefly: Lexical is "how" and scope is kinda like "what can i do with it". The whole topic is very complicated and i only introduced it in my technical paper "Building named abstractions" because of spaghetti code.

I have to read this thread now. Sorry for any confusion.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10627
Re: 'ReplaceText' lisp errors on first go ...
« Reply #21 on: August 02, 2010, 03:55:59 PM »
Okay, forget Lexical scoping! ...i have a fire here. i will be back.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

pkohut

  • Guest
Re: 'ReplaceText' lisp errors on first go ...
« Reply #22 on: August 02, 2010, 04:32:25 PM »
You've basically got 2 scoping choices for variables. Local Scope and Global Scope. To reduce side effects in your code, strive for local scoping and pass needed arguments to the function. Local scoping allows functions to be self contained modules, that shouldn't break when changes are made to code outside of the function.

In your case Hangman, you've talked about cutting and pasting code and such. Upfront you have no idea which variable names are used or their type. For example, suppose you wrote code that set global A to a string and did string type work. In another chuck of code, global variable A is set to a float is called. Now your string work code needs to do more work but crashes because global A isn't a string any more.

Another side effect (related to the above), is you've set a global variable in some function and written code in another function that uses the variable name. At some point you rename the variable in the first function, and everything appears to works great until a new drawing or session of Acad is started, where the expected variable name isn't set and the second function crashes.

Global variables have their place, just try and limit their use.

JohnK

  • Administrator
  • Seagull
  • Posts: 10627
Re: 'ReplaceText' lisp errors on first go ...
« Reply #23 on: August 02, 2010, 04:39:41 PM »
Code: [Select]
(defun f ( / a b c g )

        (defun g ( ) (* b 2) )
        ;; local function
        ;;
        ;; this function will "look up" the `b' variable.


  (setq a 1
        b 2
        c 3 )

  (g)
)

In an effort to clean up this little scope mess, this is a better example of Lexical Scoping in action but that phrase is just facy speak for: how the AutoLisp interpreter can look up a variable. Please, do NOT be concerned with how the `b' var is being enacted or what the interpreter can or cant do with it. The only thing you should take from this whole mess is that you can look at this code in a way that will allow you to improve the readablity of your main program later once you grasp the concept of local and global variables.

For example, using this model allows you to build procedures that can be constructed and read this way:

Code: [Select]
(defun ( / )
  ;; local functions...
  ;;     ...
  ;; end local functions...

  (ask-for-payment)
  (count-payment)
  (make-change)
  (return-to-user)

  (princ)
 )

Okay, this concept is not pertant to what you need to know now. Focus on the localization of variables, Global variables, and simple NAMES like (setq myVar...).
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10627
Re: 'ReplaceText' lisp errors on first go ...
« Reply #24 on: August 02, 2010, 05:07:00 PM »
<snip>
Global variables have their place, just try and limit their use.

Let me repeat that for you Hangman.

"Global variables have their place, just try and limit their use."

TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: 'ReplaceText' lisp errors on first go ...
« Reply #25 on: August 02, 2010, 06:07:47 PM »
Quote from: Lee Mac
But then what do I know lol :P

Hangman

  • Swamp Rat
  • Posts: 566
Re: 'ReplaceText' lisp errors on first go ...
« Reply #26 on: August 03, 2010, 02:49:15 PM »
Okay, forget Lexical scoping! ...i have a fire here. i will be back.

Heh, sounds like you've got a fire here !!  :-D
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~