I'm using the VS Code editor. And I have installed CFLint on my editor. On Application.cfc I see 'Identifier this is global, referencing in a CFC or function should be avoided.cflint(GLOBAL_VAR)' message when I mouse over into this scope.
Please explain this little bit elaborate. Thanks in advance.
The this scope in ColdFusion is equivalent to Java's public <type> <variable> declaration, a.k.a. "public fields". You can read and write these variables from anywhere, which is usually a bad thing (violates OOP encapsulation, is not thread-safe etc.).
This is also true for components (classes) in ColdFusion. However, the Application.cfc is a special case where this linter warning doesn't make any sense since "Application" is a singleton handled by ColdFusion and you cannot encapsulate it's configuration fields that reside in this.
Conclusion: Ignore this message in Application.cfc for all built-in fields, but follow it in every other .cfc file.
(You might want to report this to the linter's maintainer.)
Related
I'm writing function libraries in Python 2.7.8, to use in some UAT testing using froglogic Squish. It's for my employer, so I'm not sure how much I can share and still conform to company privacy regulations.
Early in the development, I put some functions in some very small files. There was one file that contained only a single function. I could import the file and use the function with no problem.
I am at a point where I want to consolidate some of those tiny files into a larger file. For some reason that completely eludes me, some of the functions that I copy/pasted into this larger file, are not being found, and a "NameError: global name 'My_variableStringVerify' is not defined" error is displayed, for example. (I just added the "My_", in case there was a name collision with some other function...)
This worked with the EXACT same simple function in a separate 'module'. Other functions in this python file -- appearing both before and after this function in the new, expanded module -- are being found and used without problems. The only module this function needs is re. I am importing that. I deleted all the pyc files in the directory, in case that was not getting updated (I'm pretty sure it was, from the datetime on the pyc file).
I have created and used dozens of functions in a dozen of my 'library modules', all with no issues. What's so special about this trivial, piece of crap function, as a part of a different module? It worked before, and it STILL works -- as long as I do not try to use it from the new library module.
I'm not python guru, but I have been doing this kind of thing for years...
Ugh. What a fool. The answer was in the error, after all: "global name xxx is not found". I was trying to use the function directly inside a Squish API call, which is the global scope. Moving the call to my function outside of the Squish API call (using it in the local scope), it worked fine.
The detail that surprised me: I was using "from foo import *", in both cases (before and after adding it to another 'library' module of mine).
When this one function was THE ONLY function in foo, I was able to use it in the global scope successfully.
When it was just one of many functions in foo-extended (names have been changed, to protect the innocent), I could NOT use it in the global scope. I had to reference it in the local scope.
After spending more time reading https://docs.python.org/2.0/ref/import.html (yes, it's old), I'm surprised it appeared in the global scope in either case. That page did state that "(The current implementation does not enforce the latter two restrictions, but programs should not abuse this freedom, as future implementations may enforce them or silently change the meaning of the program.)" about scope restrictions with the "from foo import *" statement.
I guess I found an edge case that somehow skirted the restriction in this implementation.
Still... what a maroon! Verifies my statement that I am no python guru.
I'm trying to refactor a local variable in CLion to name it property but it won't actually let me. There's no error when I do it myself but the refactoring tool is a bit less tedious.
Renaming property__ to property
Is this a bug from CLion or there's actually a reason it doesn't want me to do that ? I imagine that if it's not a bug, it might be entering in conflict with something else making it safer for me to use another name.
PS: To curious wondering I need to call a variable something as generic as property, I'm looping through XML attributes and the XML library I'm using call that properties (I'm not sure why).
for(c_xml_config::nodeProperty property : xmlModule.properties)
{
//Lots of this calling this variable making it tedious to rename at hand...
}
In plain C++ property is not reserved, so yes you can use it.
It appears to be a keyword in a Microsoft C++ extension.
I working on a huge code base written many years ago. We're trying to implement multi-threading and I'm incharge of cleaning up global variables (sigh!)
My strategy is to move all global variables to a class, and then individual threads will use instances of that class and the globals will be accessed through class instance and -> operator.
In first go, I've compiled a list of global variables using nm by finding B and D group object names. The list is not complete, and incase of static variables, I don't get file and line number info.
The second stage is even more messy, I've to replace all globals in the code base with classinstance->global_name pattern. I'm using cscope Change text string for this. The problem is that in case of some globals, their name is also being used locally inside functions, and thus cscope is replacing them as well.
Any other way to go about it? Any strategies, or help please!
just some suggestions, from my experience:
use eclipse: the C++ indexer is very good, and when dealing with a large project I find it very useful to track variables. shift+ctrl+g (I have forgotten how to access to it from menus!) let you search all the references, ctrl+alt+h (open call hierarchy) the caller-callee trees...
use eclipse: it has good refactoring tools, that is able to rename a variable without touching same-name-different-scope variables. (it often fails in case there are templates involved. I find it good, better than visual studio 2008 counterpart).
use eclipse: I know, it get some time to get started with it, but after you get it, it's very powerful. It can deal easily with the existing makefile based project (file -> new -> project -> makefile project with existing code).
I would consider not to use class members, but accessors: it's possibile that some of them will be shared among threads, and need some locking in order to be properly used. So I would prefer: classinstance->get_global_name()
As a final note, I don't know whether using the eclipse indexer at command-line would be helpful for your task. You can find some examples googling for it.
This question/answer can give you some more hints: any C/C++ refactoring tool based on libclang? (even simplest "toy example" ). In particular I do quote "...C++ is a bitch of a language to transform"
Halfway there: if a function uses a local name that hides the global name, the object file won't have an undefined symbol. nm can show you those undefined symbols, and then you know in which files you must replace at least some instances of that name.
However, you still have a problem in the rare cases that a file uses both the global name and in another function hides the global name. I'm not sure if this can be resolved with --ffunction-sections; but I think so: nm can show the section and thus you'll see the undefined symbols used in foo() appear in section .text.foo.
I have been reading about the CF Scopes, and am comfortable with the CFC scopes and their implications (detailed here), however, whenever I search for CF scopes it almost always references in the context of a CFC - So I was hoping for some clarification around scopes in CFM pages. I am working with CF 9/10 so only really interested in how the scopes behave in these releases.
What scopes are available on a CFM page - do CFM pages have the same concurrency problems as can happen elsewhere, or are the variables scoped on a CFM page bound to the scope of that specific request?
If I include the line <cfset myVar = 10 /> in a CFM page , which scope will it be included in? is there any risk of either other users on the same page accessing the variable or other cfm pages accessing it?
Thanks
Almost all the scopes except 'THIS' are available in the CFM pages.
unscoped variables declared in CFM page can be called directly or can be called with VARIABLES scope prefix.
eg:
<cfset varA = 'someValue'/>
can also be written as
<cfset VARIABLES.varA = 'something' />
To my Knowledge, unless you create a singleton (only possible for CFC's) and put it in Application scope, you never risk sharing variables with other users. This is also valid if one is not careful about scoping the local variables properly in the CFC functions.
On a CFM page, each user request has its own processing thread and never gets crossed with other user request. So, the variables are bound only to the scope of that specific request.
if you want a variables to be used by all the users requesting a page, you can put that in the APPLICATION scope.
I did not quite understand your second question. if you can elaborate on it, may be i can add more to my answer.
Update
This code will help you answer the 2 questions.
<cfscript>
function a(){
_a = 20;
WriteOutput("Inside function:"&variables['_a']);
WriteOutput("Inside function:"&variables['_b']);
}
_b = 30;
a();
WriteOutput('outside function:'&variables['_a']);
</cfscript>
Output
Inside function:20Inside function:30outside function:20
This page, gives a good explanation of the available scopes.
If you look hard enough, you will find more information about what happens if you don't scope your variables. The gist of it is that your code will run successfully, but less efficiently. The reason is that ColdFusion will attempt to find the correct scope. It checks certain scopes, in a specified order. That order is somwhere, I just couldn't find it quickly.
For your second question,
<cfset myVar = 10>
puts the myVar variable into the variables scope.
Regarding one user changing variables that affect other users, I believe the only scope that is at risk is the application scope. However, with modern browsers, it is possible for a single user to mess up his own session variables. I've seen it done.
Another way that variables might be inadvertently changed is with functions. If you want to keep your variables local to the function, you have to use the var keyword when you instantiate them. In later versions of CF, there is a local scope that accomplishes the same thing.
Personally, I scope all my variables except for the variables scope.
A little something that could be borrowed from IDEs. So the idea would be to highlight function arguments (and maybe scoped variable names) inside function bodies. This is the default behaviour for some C:
Well, if I were to place the cursor inside func I would like to see the arguments foo and bar highlighted to follow the algorithm logic better. Notice that the similarly named foo in func2 wouldn't get highlit. This luxury could be omitted though...
Using locally scoped variables, I would also like have locally initialized variables highlit:
Finally to redemonstrate the luxury:
Not so trivial to write this. I used the C to give a general idea. Really I could use this for Scheme/Clojure programming better:
This should recognize let, loop, for, doseq bindings for instance.
My vimscript-fu isn't that strong; I suspect we would need to
Parse (non-regexply?) the arguments from the function definition under the cursor. This would be language specific of course. My priority would be Clojure.
define a syntax region to cover the given function/scope only
give the required syntax matches
As a function this could be mapped to a key (if very resource intensive) or CursorMoved if not so slow.
Okay, now. Has anyone written/found something like this? Do the vimscript gurus have an idea on how to actually start writing such a script?
Sorry about slight offtopicness and bad formatting. Feel free to edit/format. Or vote to close.
This is much harder than it sounds, and borderline-impossible with the vimscript API as it stands, because you don't just need to parse the file; if you want it to work well, you need to parse the file incrementally. That's why regular syntax files are limited to what you can do with regexes - when you change a few characters, vim can figure out what's changed in the syntax highlighting, without redoing the whole file.
The vim syntax highlighter is limited to dealing with regexes, but if you're hellbent on doing this, you can roll your own parser in vimscript, and have it generate a buffer-local syntax that refers to tokens in the file by line and column, using the \%l and \%c atoms in a regex. This would have to be rerun after every change. Unfortunately there's no autocmd for "file changed", but there is the CursorHold autocmd, which runs when you've been idle for a configurable duration.
One possible solution can be found here. Not the best way because it highlights every occurrence in the whole file and you have to give the command every time (probably the second one can be avoided, don't know about the first). Give it a look though.