Related
I find myself doing this from time to time and I end up just doing a search on the variable name and then looking through all the hits, skipping the ones that aren't what I'm looking for. But it occurred to me that if Xcode could reliably filter into one set or the other, it would make the process more efficient. Because quite often one only needs to know where a variable is changed in particular, so reads don't really matter then.
I can think of some ways eg. searching for "setXXX" and "XXX =" etc. but that all seems a bit clunky and imprecise. Is there a better way?
I am mostly coding in Objective-C and am looking for a way to do a static search of the source code.
What I do when I want to search for a symbol in Xcode I use the built-in search tool as you suggested in your question and that is good enough for me. However, if you want better tools for static analysis of obj-c code I'd suggest XClarify from CodeGears. It became free for open source contributors and research.
I'm considering how to do automatic bug tracking and as part of that I'm wondering what is available to match source code line numbers (or more accurate numbers mapped from instruction pointers via something like addr2line) in one version of a program to the same line in another. (Assume everything is in some kind of source control and is available to my code)
The simplest approach would be to use a diff tool/lib on the files and do some math on the line number spans, however this has some limitations:
It doesn't handle cross file motion.
It might not play well with lines that get changed
It doesn't look at the information available in the intermediate versions.
It provides no way to manually patch up lines when the diff tool gets things wrong.
It's kinda clunky
Before I start diving into developing something better:
What already exists to do this?
What features do similar system have that I've not thought of?
Why do you need to do this? If you use decent source version control, you should have access to old versions of the code, you can simply provide a link to that so people can see the bug in its original place. In fact the main problem I see with this system is that the bug may have already been fixed, but your automatic line tracking code will point to a line and say there's a bug there. Seems this system would be a pain to build, and not provide a whole lot of help in practice.
My suggestion is: instead of trying to track line numbers, which as you observed can quickly get out of sync as software changes, you should decorate each assertion (or other line of interest) with a unique identifier.
Assuming you're using C, in the case of assertions, this could be as simple as changing something like assert(x == 42); to assert(("check_x", x == 42)); -- this is functionally identical, due to the semantics of the comma operator in C and the fact that a string literal will always evaluate to true.
Of course this means that you need to identify a priori those items that you wish to track. But given that there's no generally reliable way to match up source line numbers across versions (by which I mean that for any mechanism you could propose, I believe I could propose a situation in which that mechanism does the wrong thing) I would argue that this is the best you can do.
Another idea: If you're using C++, you can make use of RAII to track dynamic scopes very elegantly. Basically, you have a Track class whose constructor takes a string describing the scope and adds this to a global stack of currently active scopes. The Track destructor pops the top element off the stack. The final ingredient is a static function Track::getState(), which simply returns a list of all currently active scopes -- this can be called from an exception handler or other error-handling mechanism.
Very simple question that is apparently impossible to find a decent answer to: How can I make Visual Basic 6 stop changing my ^##*ing variable casing!?!
I know that the general opinion of a great many VB users is that this "feature" is actually quite helpful, but I doubt that they use it much with any source control system. This is absolutely INFURIATING when you are trying to collaborate on a project of any significant size with several other developers. If ignored, you produce thousands of false-positive "changes" to your files (even ones with no actual code changes!) that pollute the revision history and make it near impossible in some cases to locate the actual change that took place.
If you don't ignore it (like my office, where we have been forced to implement a "no unneeded case change" policy), you spend 5x the time you would normally on each commit because you have to carefully revert out VB's "corrections" on every file, sometimes reverting hundreds of lines to put in a one line change.
Surely there must be a setting, plugin, hack, etc. out there that can remove this unwanted "feature"? I am willing to take any method I can get as long as it doesn't require me to pick through piles of phantom diffs. And to squash a couple of complaints up front: No, I can't turn off case detection in my diff tool, that's not the point. No, we can't just make the case changes globally. We're working with hundreds of thousands of LOC being worked on by multiple developers spanning many years of development. Synchronizing that is not feasible from a business standpoint. And, finally: No, we cannot upgrade to VB.net or port to another language (as much as I would love to).
(And yes, I am just a tiny bit peeved at the moment. Can you tell? My apologies, but this is costing me time and my company money, and I don't find that acceptable.)
Depending on your situation adding
#If False Then
Dim CorrectCase
#End If
might help.
Here is a real world scenario and how we solved it for our 350k LOC VB6 project.
We are using Janus Grid and at some point all the code lines which referenced DefaultValue property of JSColumn turned to defaultValue. This was an opportunity to debug the whole IDE nuisance.
What I found was that a reference to MSXML has just been added and now the IDE picks up ISchemaAttributes' defaultValue property before the Janus Grid typelib.
After some experiments I found out that the IDE collects "registered" identifiers in the following order:
Referenced Libraries/Projects from Project->References in the order they are listed
Controls from Project->Components (in unknown order)
Source Code
So the simple fix we did was to create a dummy class/interface with methods that hold our proper casing. Since we already had a project-wide typelib we referenced from every project before anything other typelib, this was painless to do.
Here is part of the IDL for our IUcsVbIntellisenseFix interface:
[
odl,
uuid(<<guid_here>>),
version(1.0),
dual,
nonextensible,
oleautomation
]
interface IUcsVbIntellisenseFix : IDispatch {
[id(1)] HRESULT DefaultValue();
[id(2)] HRESULT Selector();
[id(3)] HRESULT Standalone();
...
}
We added a lot of methods to IUcsVbIntellisenseFix, some of them named after enum items we used to misspell and whatever we wanted to fix. The same can be done with a simple VB class in a common library (ActiveX DLL) that's referenced from every project.
This way our source code at some point converged to proper casing because upon check-out the IDE actually fixed the casing as per IUcsVbIntellisenseFix casing. Now we can't misspell enums, methods or properties even if we try to.
SIMPLE WAY: Dim each variable in the case that you want. Otherwise, VBA will change it in a way that is not understandable.
Dim x, X1, X2, y, Yy as variant
in a subroutine will change ALL cases to those in the Dim statement
I can sympathise. Luckily we're allowed to turn off case sensitivity in our version control diff tool!
It seems the VB6 IDE automatic case-correction occasionally changes case in variable declarations and references, perhaps depending on the order in which modules are listed in the VBP file? But the IDE doesn't tell you that the file needs to be saved. So the problem only shows up when you saved the file because of another edit. We briefly tried to prevent this by checking out all the files in a project and setting the case carefully, but it didn't go away.
I suppose you could list the variable names that are affected - the usual suspects are one letter names like "I", "X" and "Y", perhaps because they are used in standard event handlers like MouseDown. Then write an add-in that'll search for all declarations " As" and force the case to upper. Run the add-in on your modules before you check them in. You might be able to trigger the add-in to run automatically when you save in VB6.
EDIT: Something I've just thought of: adapt Fred's answer. From now on, every time you check in a file, add a block at the top to establish canonical case for the usual suspects. If nothing else, it's easier than reverting hundreds of lines by hand. Eventually you will have this block in every file & maybe then the problem will stop happening.
#If False Then
Dim I, X, Y ' etc '
#End If
I standardised the case across the codebase, normally by using the examples above (Dim CorrectCase), and removing it again.
I then triggered VB to save EVERY file, by doing a case sensitive search/replace of "End" with "End" (no functional change, but enough to get VB to resave).
Once that was done, I could then do a single commit to standardise the case, making it MUCH easier to keep on top of it at a later date.
In this example VB6 was changing the case of the following line following a typo I made when referencing a library: -
Dim MyRecordset As ADODB.REcordset
Ugly, and now every other instance of an ADODB.REcordset thus acquired the new misspelling. I fixed this as follows: -
Type in a new declaration as follows
Dim VB6CasingSucks AS ADODB, Recordset
Note the comma and space after ADODB. Hit [ENTER] for VB6 to check the line.
At this point all instances of REcordset change back to Recordset.
Delete your new declaration.
I don't know if this fix will help with enums/other variable names.
Specifically for controlling the case of enum values, there is a VB6 IDE add-in which may be helpful. Enums seem to have a slightly unique version of this problem.
As described in the link below:
The VB6 IDE has an annoying quirk when it comes to the case of Enum
members. Unlike with other identifiers, the IDE doesn't enforce the
case of an Enum member as it was declared in the Enum block. That
occasionally causes an Enum member that was manually written to lose
its original case, unless a coder typed it carefully enough.
...
However, if a project contains a lot of Enums and/or a particular Enum
has a lot of members, redeclaring the members in each of them can get
quite tedious fast. ...
Ref: http://www.vbforums.com/showthread.php?778109-VB6-modLockEnumCase-bas-Enforce-Case-of-Enums
...load and unload the add-in as needed via the Add-In Manager
dialog box. Usage is as simple as selecting the entire Enum block,
right-clicking and then choosing the "Lock Enum Case" context menu
item.
I have a similar problem:
in a bas module there I wrote :
Private sub bla_bla()
Dim K as integer
End Sub
so in a class module the Dim k as integer will automatically be replaced by IDE become 'Dim K as integer' <-- it's not logical but then:
I correct the bas module become:
Private sub bla_bla()
Dim k as integer
End Sub
then magically the problem in the class module was solved (still be k and not automatically replaced by IDE become K). Sorry I'm poor in English
I don't think there's any to do it. The IDE will change the case of the variable name to whatever it is when it's declared. But, honestly, back in the day I worked on several large VB6 projects and never found this to be a problem. Why are people on your development team constantly changing variable declarations? It seems like you have not established a clear variable naming policy that you enforce. I know your upset, so no offense, but it might be your policies that are lacking in this regard.
Unfortunately, according to this SO thread, alternate VB6 IDEs are hard to come by. So, your best bet is to solve this problem via policy. Or move to VB.NET. :)
Wow. I've spent a lot of time programming in VB6 and I have no idea what you're on about. The only thing I can think you're referring to is that intellisense will change the capitalization of variable names to match their declarations. If you're complaining about that, I would have to wonder why the hell they've been entered any other way to begin with. And if that is your problem, no, there's no way to disable it that I'm aware of. I'd suggest you, in one go, check out every file, make sure the caps on the declarations and uses of variables all match and check back in.
Let's say you've inherited a C# codebase that uses one class with 200 static methods to provide core functionality (such as database lookups). Of the many nightmares in that class, there's copious use of Hungarian notation (the bad kind).
Would you refactor the variable names to remove the Hungarian notation, or would you leave them alone?
If you chose to change all the variables to remove Hungarian notation, what would be your method?
Refactor -- I find Hungarian notation on that scale really interferes with the natural readability of the code, and the exercise is a good way of getting familiar with what's there.
However, if there are other team members who know the code base you would need consensus on the refactoring, and if any of the variables are exposed outside of the one project then you will have to leave them alone.
Just leave it alone. There are better uses of your time.
Right click on the variable name, Refactor -> Rename.
There are VS add-ins that do this as well, but the built-in method works fine for me.
What would I do? Assuming that I just have to maintain the code and not rewrite it any significant way? Leave it well alone. And When I do add code, go with the existing style, meaning, use that ugly Hungarian notation (as dirty as that makes me feel.)
But, hey, if you really have a hankerin' fer refactorin' then just do a little at a time. Every time you work on it spend ten minutes renaming variables. Tidying things up a little. After a few months you might find it's clean as a whistle....
Don't forget that there are two kinds of Hungarian Notation.
The original Charles Simonyi HN, later known as App's Hungarian and the later abomination called System Hungarian after some peckerhead (it's a technical term) totally misread Simonyi's original paper.
Unfortunately, System HN was propagated by Petzold and others to become the more dominant abortion that it is rightfully recognised as today.
Read Joel's excellent article about the intent of the original Apps Hungarian Notation and be sorry for what got lost in the rush.
If what you've got is App's Hungarian you will probably want to keep it after reading both the original Charles Simonyi article and the Joel article.
If you've landed in a steaming pile of System Hungarian?
All bets are off!
Whew! (said while holding nose) (-:
if you're feeling lucky and just want the Hungarian to go away, isolate the Hungarian prefixes that are used and try a search and replace in file to replace them with nothing, then do a clean and rebuild. If the number of errors is small, just fix it. If the number of errors is huge, go back and break it up into logical (by domain) classes first, then rename individually (the IDE will help)
I used to use it religiously back in the VB6 days, but stopped when VB.NET came out because that's what the new VB guidelines said. Other developers didn't. So, we’ve got a lot of old code with it. When I do maintenance on code I remove the notation from the functions/methods/sub I touch. I wouldn't remove it all at once unless you've got really good unit tests for everything and can run them to prove that nothing's broken.
How much are you going to break by doing this? That's an important question to ask yourself. If there are a lot of other pieces of code that use that library, then you might just be creating work for folks (maybe you) by going through the renaming exercise.
I'd put it on the list of things to do when refactoring. At least then everyone expects you to be breaking the library (temporarily).
That said, I totally get frustrated with poorly named methods and variables, so I can relate.
I wouldn't make a project out of it. I'd use the refactoring tools in VS (actually, I'd use Resharper's, but VS's work just fine) and fix all the variables in any method I was called upon to modify. Or if I had to make larger-scale changes, I'd refactor the variable names in any method I was called upon to understand.
If you have a legitimate need to remove and change it I would use either the built in refactoring tools, or something like Resharper.
However, I would agree with Chris Conway to a certain standpoint and ask you WHY, yes, it is annoying, but at the same time, a lot of the time the "if it aint't broke done't fix it" method is really the best way to go!
Only change it when you directly use it. And make sure you have a testbench ready to apply to ensure it still works.
I agree that the best way to phase out hungarian notation is to refactor code as you modify it. The greatest benefit of doing this kind of refactoring is that you should be writing unit tests around the code you're modifying so that you have a safety net instead of crossing your fingers and hoping that you don't break existing functionality. Once you have these unit tests in place, you are free to change the code to your heart's content.
I'd say a bigger problem is that you have a single class with 200(!) methods!
If this is a much depended on / much changed class then it might be worth refactoring to make it more usable.
In this, Resharper is an absolute must (you could use the built in refactoring stuff, but Resharper is way better).
Start finding a group of related methods, and then refactor these out into a nice small cohesive class. Update to conform to your latest code standards.
Compile & run your test suite.
Have energy for more? Extract another class.
Worn out - no trouble; come back and do some more tomorrow. In just a few days you'll have conquered the beast.
I agree with #Booji -- do it manually, on a per-routine basis when you're already visiting the code for some other good reason. Then, you'll get the most common ones out of the way, and who cares about the rest.
I was thinking of asking a similar question, only in my case, the offending code is my own. I have a very old habit of using "the bad kind" of Hungarian from my FoxPro days (which had weak typing and unusual scoping) — a habit I've only recently kicked.
It's hard — it means accepting an inconsistent style in your code base. It was only a week ago I finally said "screw it" and began a parameter name without the letter "p". The cognitive dissonance I initially felt has given way to a feeling of liberty. The world did not come to an end.
The way I've been going about this problem is changing one variable at a time as I come across them, then perform more sweeping changes when you come back to do more in-depth changes. If you're anything like me, the different nomenclature of your variables will drive you bat-shiat crazy for a while, but you'll slowly become used to it. The key is to chip away at it a little bit at a time until you have everything to where it needs to be.
Alternatively, you could jettison your variables altogether and just have every function return 42.
It sounds to me like the bigger problem is that 200-method God Object class. I'd suggest that refactoring just to remove the Hungarian notation is a low-value, high-risk activity in of itself. Unless there's a copious set of automated unit tests around that class to give you some confidence in your refactoring, I think you should leave it well and truly alone.
I guess it's unlikely that such a set of tests exists, because a developer following TDD practices would (hopefully) have naturally avoided building a god object in the first place - it would be very difficult to write comprehensive tests for.
Eliminating the god object and getting a unit test base in place is of higher value, however. My advice would be to look for opportunities to refactor the class itself - perhaps when a suitable business requirement/change comes along that necessitates a change to that code (and thus hopefully comes with some system & regression testing bought and paid for). You might not be able to justify the effort of refactoring the whole thing in one go, but you can do it piece by piece as the opportunity comes along, and test-drive the changes. In this way you can slowly convert the spaghetti code into a cleaner code base with comprehensive unit tests, bit by bit.
And you can eliminate the Hungarian as you go, if you like.
I am actually doing the same thing here for an application extension. My approach has been to use VIM mappings to search for specific Hungarian notation prefixes and then delete them and fix capitalization as appropriate.
Examples (goes in vimrc):
"" Hungarian notation conversion helpers
"" get rid of str prefixes and fix caps e.g. strName -> name
map ,bs /\Wstr[A-Z]^Ml3x~
map ,bi /\Wint[A-Z]^Ml3x~
"" little more complex to clean up m_p type class variables
map ,bm /\Wm_p\?[A-Z]^M:.s/\(\W\)m_p\?/\1_/^M/\W_[A-Z]^Mll~
map ,bp /\Wp[A-Z]^Mlx~
If you're gonna break code just for the sake of refactoring, I would seriously consider leaving i alone, specially, if you are going to affect other people in your team who may be depending on that code.
If your team is OK with this refactoring, and investing your time in doing this (which may be a time-saver in the future, if it means the code is more readable/maintainable), use Visual Studio (or whatever IDE you are using) to help you refactor the code.
However, if a big change like this is not a risk your team/boss is willing to take, I would suggest a somewhat unorthodox, half-way approach. Instead of doing all your refactoring in a single sweep, why not refactor sections of code (more specifically, functions) that need to be touched during normal maintenance? Over time, this slow refactoring will bring the code up to a cleaner state, at which point you can finish the refactoring process with a final sweep.
Use this java tool to remove HN:
Or just use "replace"/"replace all" with regex like below to replace "c_strX" to "x":
I love Hungarian notation. Don't understand why you would want to get rid of it.
Are there any practices regarding using codenames of products in Visual Studio projects and solutions? In that typically, namespaces, assembly names, binary outputs, et al need to be renamed once a product name is chosen: is there any way to deal with this?
In one place I worked we'd choose an unrelated and inoffensive, and typically systematic name for any given project.. Jupiter, Orca, Feynman whatever... and stick with that namespace forevermore.
Because as you've seen what the marketing/client/board chooses to call a product (hell, even what version number they choose) is so rarely going to be known at the start let alone the same by the end, that it's just so much easier for everyone to be able to have a fixed internal reference they don't have to refactor later.
I can't stress how important it is that the name is simple, one word and inoffensive though.
This will partly depend on the type of product. If it's a client library - or anything that will require users to see the names - then clearly the names matter. I don't think it really matters otherwise. Bear in mind that different versions of the product may have new codenames (e.g. Everett, Whidbey, Orcas for Visual Studio) - you don't want to have to rename the code each time you start a new version!