Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Monday, April 18, 2016

My quick opinions of Eclipse CDT vs CLion

In my last post, I mentioned I found a neat feature in Eclipse, but that I still use CLion most of the time. This begs the obvious question: Why don't I just use Eclipse / CDT full time?

Well, I initially switched because of two main reasons: 1) annoyance with the time it always took getting the IDE setup to recognize all my various include paths, library paths, options, etc... and 2), the fact that CODAN* (the static analyzer in CDT) seems to miss a lot of situations. So I decided to give it another shot.

I mostly work with CMake projects - a given, since I'm using CLion, and it's biggest downside is it ONLY works with CMake - so I used the CMake Eclipse project generator. It seemed to work fairly well, which helped with 1)... but longer term, the fact that I would potentially need to re-run it any time the CMake changed... which in turn would mean I could lose any project settings / changes I made from within Eclipse - is a worry. Plus the fact that I have to run a separate command line tool frequently is a turn off.

Still, those are things I could deal with... except it seemed that 2), CODAN's unreliable, is still a factor. I had only been using it for 5 minutes before coming across a situation which CODAN incorrectly flagged as an error, but which CLion got right. I always find it annoying to have all those extraneous red highlights in my IDE, so back I went to CLion...

...but, I still keep Eclipse open for that Shift+Alt+T action!

*...though, if this is named after the infamous Armada in "The Last Starfighter," thumbs up to that!

IDE shortcuts for adding function definitions

So when I'm writing C++ (or C) code, I constantly find myself either writing a function inside the header (.h) file, and later wanting to move it to the the implementation (.cpp) file.... or KNOWING I'll want it in the .cpp at the outset, but having to re-type out all the boilerplate in the .cpp again.

I mostly use CLion these days for C++ development... and while it's generally a nice IDE, I was dismayed to find it doesn't have couldn't find a refactor option for this*. Eclipse, however, has one: "Toggle Function defintion". You can get at it right clicking in the function definition, going to "Refactor" > "Toggle Function Defintion"... or by just pressing Shift+Alt+T.

It has a few caveats, however:
  • You have to do each function one at a time 
  • It's a two step process - it will first shift it to outside the class declaration, but still within the header file, as an inline definition... you then have to scroll down to it, click on it again, and move it to the .cpp file. 
  • You have to have a defintion; so for cases where I know I'm going to want it in the .cpp at the outset, I have to add an empty definition ({}), then click on it, before moving. 
The last gripe is pretty minor, but the other two cost time... though they STILL save enough time that I find myself keeping a copy of Eclipse open, alongside my copy of CLion, just to use this feature.

Why don't I just use Eclipse / CDT full time? Good question... but my answer started to veer off topic a bit, so I put it in another post..

*Update! A friend showed me that CLion does, indeed have an intention - just go to the declaration, press "Alt-Enter", then choose "Implement function 'foo'" - or, if it's already defined in the header, click on the name, hit"Alt-Enter", then choose "Move function definition to source file".  Huzzah!

Friday, October 26, 2012

How do you find where a python attribute "comes from"?

I work on a python project in the visual-effects industry called pymel, and someone recently asked me about the 'vtx' "attribute" on a mesh object - where it came from, and how they would find that out.  The answer is that it's added using the __getattr__ method on the Mesh class... but this got me thinking - is there a general way to find where a given attribute "comes from?"

When classes use tricks like __getattr__, it's hard to determine - standard methods like using dir or searching through the mro's __dict__ entries won't help.

The only way I could think of to find out it's from a __getattr__ would be to march up the mro chain, looking for __getattrs__, and testing them - to see if they return a result for the desired attribute, and at what point that result changes.

So, I wrote a function which does just that... and while it's at it, also checks the __dict__, __slots__, and __getattribute__.  It even does a last-ditch check to see if it's a c-compiled object. It's designed to generally tell you, "where the heck did this attribute come from"?
In order to get all (or at least, most) of the edge cases right, it ended up being way more complex than I'd originally imagined.. but it seems to get things right nearly all of the time. Hopefully it helps someone!

Thursday, July 9, 2009

Getting the type of OS

Just something that came up recently - how to use python to find what OS the user is running.

If you only need the general "type" of os (ie, Windows, Mac OSX, Linux), I've found the best solution is to use os.name first, as it's result is guaranteed to be one of only a few values, and then platform.system() to get finer grained results (ie, differentiate between OSX and *nix).

The problem with just using platform.system() is that it's return value isn't "guaranteed" be one of a few values, as the Python community learned when Vista was released. Whereas previous versions of Windows would return "Windows", Vista returns "Microsoft". While this may be considered a bug, it taught me that it's probably safest to just use os.name when possible, and only resort to other methods when this doesn't provide enough information.

Unfortunately, this is the case when trying to differentiate OSX and Unix/Linux - os.name returns 'posix' for both. So there, we resort to platform.system(), which will return 'Darwin' or 'Linux'.

Of course, you may need more fine-grained information, and there's other functions that can help with that - platform.uname(), platform.system_alias(), platform.uname(), maya.cmds.about() if Maya is initialized, etc.