MakeLayer function and program structure

Discussion in 'AutoCAD' started by Joe Burke, Feb 3, 2004.

  1. Joe Burke

    Joe Burke Guest

    All,

    I've been playing with this off and on. Comments welcome. See in-line comments.

    I like John Uhden's "and... " structure for a toolbox function like this. But the
    extensive use of "not..." seems a bit strange. For instance: (not (vlax-put newlay
    'Color clr)) to return T to the "and" function. Because vlax-put returns nil in
    most/all cases.

    Seems there must be a better way so the code makes sense in terms of readability.

    TIA
    Joe Burke

    ;; 2/3/2004
    ;; arguments:
    ;; layname - string
    ;; clr - integer from 1 to 255
    ;; lntyp - string
    ;; should return T if successful, otherwise nil
    (defun MakeLayer ( layname clr lntyp / doc layers linetypes newlay )
    (and
    ; layer name doesn't exist
    (not (tblsearch "layer" layname))
    ; color number is within range for A2k2 and prior versions
    (and
    (= (type clr) 'INT)
    (<= 1 clr 255) ; modify for A2k4
    )
    ; if OK so far:
    (setq doc (vla-Get-ActiveDocument (vlax-Get-Acad-Object))
    layers (vlax-get doc 'Layers)
    linetypes (vlax-get doc 'Linetypes)
    )
    ; if linetype is loaded or found in acad.lin
    (or
    (tblsearch "ltype" lntyp)
    ; following returns nil if successful, hence "not"
    (not (vla-load linetypes lntyp "acad.lin"))
    )
    (setq newlay (vlax-invoke layers 'Add layname))
    ; following returns nil if successful
    (not (vlax-put newlay 'Color clr))
    ; following returns nil if successful
    (not (vlax-put newlay 'Linetype lntyp))
    ) ;and
    ) ;end
     
    Joe Burke, Feb 3, 2004
    #1
  2. Hi Joe,

    FWIW I am trying to not get 'stuck' in the mind frame that
    T = good NIL = bad for return values, especially since I am
    using more and more Activex solutions. I figure for the most
    part, if there is no error object returned then it must have
    succeeded.

    I've also almost completely dropped making sure each supplied
    argument is of the correct type. I am counting on AutoCAD to
    tell me if the argument is incorrect (which it should anyway). I
    am the *only* one that will use my functions, and I am beginning
    to prefer a *noisy* return if there is a error in lieu of NIL.


    (makeLayer "abc" "abc" "abc") -> nil.

    Not very useful in debugging, IMO


    --

    -Jason
    Member of the Autodesk Discussion Forum Moderator Program


    <snip>
     
    Jason Piercey, Feb 3, 2004
    #2
  3. Joe Burke

    Mark Propst Guest

    Hi Joe,
    fwiw
    I agree with your opinion of the "not" business looking tacky
    the only solution I've come up with is writing my own versions of those
    functions that return a value if successful and nil if not
    in the present case I might do something like
    (defun LoadLineType (lntyp)
    (if
    (null
    (vl-catch-all-error-p
    (setq res
    (vl-catch-all-apply
    'vlax-invoke-method
    (list (GetLinetypes *doc*) 'load lntyp "acad.lin")
    );catch
    );setq
    );err
    );null
    lntyp
    nil
    )
    )
    assumes (GetLinetypes... returns the linetypes collection and *doc* points
    to document object you want to change
    then (LoadLineType "linetype1") will either return "linetype1" or nil and
    can be used in the and clause without problem
    to me that's more readable in the calling code
    my 0.000002 cents worth


    readability.
     
    Mark Propst, Feb 3, 2004
    #3
  4. PS: I do like the use of (and) but.... I suppose
    you could do something like this for a return
    value of something other than NIL.

    (defun myFunction ( / error )
    (if
    (vl-catch-all-error-p
    (setq
    error
    (vl-catch-all-apply
    (function
    (lambda ()

    ;; rest of code here

    )
    )
    )
    )
    )
    (vl-catch-all-error-message error)
    t
    )
    )
     
    Jason Piercey, Feb 3, 2004
    #4
  5. Joe,

    It seems to me that the 'nots' compliment an 'and' structure such as
    this. To get rid of the 'nots' and maybe make it more readable, I
    think you would
    simply go to an if statement.
    --
    Ken Alexander
    Acad2004
    Windows2000 Prof.

    "We can't solve problems by using the same kind
    of thinking we used when we created them."
    --Albert Einstein
     
    Ken Alexander, Feb 3, 2004
    #5
  6. I like to think of T=Something and NIL=Nothing.
    vl-catch-all-error-p returns nil if there is no error object.
    That's good. I need all the "good" I can get. <g>
    --
    Ken Alexander
    Acad2004
    Windows2000 Prof.

    "We can't solve problems by using the same kind
    of thinking we used when we created them."
    --Albert Einstein
     
    Ken Alexander, Feb 3, 2004
    #6
  7. Joe Burke

    Joe Burke Guest

    Hi Jason,

    I was thinking type checking made sense to prevent something like the layer is
    created, but without the desired color or linetype.

    Good point regarding T and NIL.

    BTW, the type checking was incomplete and not in the right place. Here's a revised
    version. It uses null in lieu of not. Which makes a *little* more sense?

    (defun MakeLayer ( layname clr lntyp / doc layers linetypes newlay )
    (and
    (= (type layname) 'STR)
    (= (type lntyp) 'STR)
    (= (type clr) 'INT)
    (<= 1 clr 255) ;modify for A2k4
    (not (tblsearch "layer" layname))
    (setq doc (vla-Get-ActiveDocument (vlax-Get-Acad-Object))
    layers (vlax-get doc 'Layers)
    linetypes (vlax-get doc 'Linetypes)
    )
    (or
    (tblsearch "ltype" lntyp)
    (null (vla-load linetypes lntyp "acad.lin"))
    )
    (setq newlay (vlax-invoke layers 'Add layname))
    (null (vlax-put newlay 'Color clr))
    (null (vlax-put newlay 'Linetype lntyp))
    ) ;and
    ) ;end

    Joe Burke
     
    Joe Burke, Feb 4, 2004
    #7
  8. Joe Burke

    Joe Burke Guest

    Hi Mark,

    Thanks for the suggestion. I'll keep it mind in the future.

    Does anyone besides me think it's strange vlax-put, or vlax-put-property, or
    vla-put-color returns nil when successful? There's probably a reason. I just don't
    know what it is. Maybe to allow the vl-catch functions to do what they do?

    BTW, I was using vl-catch-all-error-p... in the function at some point. Later I
    thought the vl-catch functions weren't doing anything useful in this case. One thing
    they did do was make the code *look* like it made more sense. But in the end it was
    just cosmetic.

    Joe Burke
     
    Joe Burke, Feb 4, 2004
    #8
  9. Joe Burke

    Joe Burke Guest

    Hi Ken,

    I'm probably missing something, as usual. I don't know how an "if" statement would
    replace (not (vlax-put newlay 'Color clr)) or what I eventually changed it to (null
    (vlax-put newlay 'Color clr)). I'd still have to use "not" or "null" so the "if"
    function returns T to the "and" wrapper. Yes?

    Actually your point below and Jason's have changed how I think about the issue.

    Thanks
    Joe Burke
     
    Joe Burke, Feb 4, 2004
    #9
  10. Joe,

    If conditions are met then create the layer and change its
    properties. Then return newlay.

    I'm sure that this tool served its purpose, but I have started to
    shy from using this style. The newly created layer is now lost due to
    the local variable. If you pass the newlayer object in lieu of T then
    you still have the layer object and maintain your local variables.

    Not or Null, never have been able to understand the difference.
    From what I have seen or read, the two are identical.





    (defun MakeLayer (layname clr lntyp / doc layers linetypes newlay)
    (if (and
    (not (tblsearch "layer" "0"))
    (and
    (= (type clr) 'INT)
    (<= 1 clr 255)
    )
    )
    (progn
    (setq doc (vla-Get-ActiveDocument
    (vlax-Get-Acad-Object))
    layers (vlax-get doc 'Layers)
    linetypes (vlax-get doc 'Linetypes)
    )
    (setq newlay (vlax-invoke layers 'Add layname))
    (vlax-put newlay 'Color clr)
    (vlax-put newlay 'Linetype lntyp)
    )
    )
    newlay
    )
    --
    Ken Alexander
    Acad2004
    Windows2000 Prof.

    "We can't solve problems by using the same kind
    of thinking we used when we created them."
    --Albert Einstein
     
    Ken Alexander, Feb 4, 2004
    #10
  11. I've wished for a long time that those functions would return the object if
    successful, and nil if not. That would make the code nest-able too:

    (and
    (setq newlay (vlax-invoke layers 'Add layname))
    (vlax-put
    (vlax-put newlay 'Linetype lntyp)
    'Color clr)
    )


    --
    R. Robert Bell, MCSE
    www.AcadX.com


    Hi Mark,

    Thanks for the suggestion. I'll keep it mind in the future.

    Does anyone besides me think it's strange vlax-put, or vlax-put-property, or
    vla-put-color returns nil when successful? There's probably a reason. I just
    don't
    know what it is. Maybe to allow the vl-catch functions to do what they do?

    BTW, I was using vl-catch-all-error-p... in the function at some point.
    Later I
    thought the vl-catch functions weren't doing anything useful in this case.
    One thing
    they did do was make the code *look* like it made more sense. But in the end
    it was
    just cosmetic.

    Joe Burke
     
    R. Robert Bell, Feb 4, 2004
    #11
  12. Joe Burke

    Joe Burke Guest

    Ken,

    I'm not sure what I might do with the "newlay" object in the calling function, but
    your suggestion makes sense. Why not pass it, rather than T. I think I'd keep the
    "and" wrapper as is without "if" at the beginning. Then after "and" at the end, (if
    newlay newlay). Pass "newlay" or nil.

    Agreed regarding "not" and "null". I imagine an artificial difference. I tend to use
    "null" when I expect the argument will be nil. "Not" when I have no idea. I know it
    doesn't make much sense.

    BTW, sorry my responses here have been slow. Work is a bit crazy these days.

    Thanks
    Joe
     
    Joe Burke, Feb 5, 2004
    #12
  13. Joe Burke

    Joe Burke Guest

    Robert,

    I was thinking vlax-put when successful might return the modified property, rather
    than the object itself. Returning the object might make more sense. Of course, either
    one would be preferable to returning nil, as if nothing happened.

    I'd like to hear more about this from you and other experts.

    I think Jason's point was don't consider a nil return to mean nothing happened under
    ActiveX functions. OK, but doesn't that go against the grain a little bit? If I used
    entmod to modify an object, and it was successful, it would return the modified
    elist. If entmod fails, it returns nil.

    I imagine all of this was discussed before I joined this NG. Please bear with me.

    Joe Burke
     
    Joe Burke, Feb 5, 2004
    #13
  14. Hi Joe,

    Yep that is what I meant. I think that is just the difference
    between vanilla/activex. Say you add a layer to the collection,
    at that point you have an object. From then on it doesn't
    really matter what properties you modify (color, linetype, etc..)
    that object is still the 'same'. So why would you really need
    the object again? I'm also trying to reorganize my thought
    process with stuff like this.

    Don't get me wrong, there have been several occasions
    where I thought it would be nice to have a return value of
    something other than nil. I think the (vl-catch-*) functions
    are the key to helping with errors.
     
    Jason Piercey, Feb 5, 2004
    #14
Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.