While it is possible and does not throw an error I would like to know if it's an approved practice to var scope multiple variables in one line like this:
<cfset VAR var1 = var2 = var3 = ''>
I would appreciate all ideas and opinions especially if they come with documentation as a supporting argument. I know that it works without throwing an error but I can't find specific documentation saying whether it will scope a variable or if it just declares the value.
Thanks!
FWIW, yes, you can do this in CF9:
<cfset var a = var b = c = d*5>
Here's the documentation which gives that example. In this case I'm assuming variables c and d were already defined earlier in the function.
So you need to repeat the var keyword for each variable, and in your case this would result in:
<cfset VAR var1 = VAR var2 = VAR var3 = ''>
As everyone said you need to scope your variables with var or local. Also as #Ben said, you can't really var scope variables like you have. What I would suggest is use the local scope and do something like the following:
<cfscript>
var val = 'some value'
local = {
var1 = duplicate(val),
var2 = duplicate(val),
var3 = duplicate(val)
};
</cfscript>
That, in my opinion, is the fastest way to achieve what you seem to be doing. I use the duplicate function just so if you use a complex variable as the value of val (struct, array, etc) you don't run into issue with references.
<cfset> does not scope variables.
To properly scope the variables requires the var keyword
<cfset var someVariable = 1>
Otherwise the variables will be created, but assigned to the default scope.
The default scope depends on the context and what version of CF we are talking about.
For CFC methods:
CF9 -> LOCAL scope
CF8 -> VARIABLES scope
Because of the scoping rules in CF9 the var keyword is not really needed.
Variables can be added to the LOCAL scope directly and at any time (<cfset LOCAL.foo = "bar"). There is no need scope them ahead of time.
I suppose I should start by pointing out that your code doesn't var scope the variables, it just sets their values. You need to use the VAR keyword (or LOCAL scope in CF9) to specify that the variables should be VAR scoped.
Furthermore, chaining assignments doesn't work in all versions of CF. My workplace is still on 6.1, and this throws an error.
Finally, if I recall correctly, if you use the assignment statement as above, var1 and var2 are equal to true, as the result of an assignment operation is true if no error occurred. (someone correct me if I'm wrong, since I can't test it at work, since we're on 6.1)
Anyway, to get back to your question, I don't chain assignment or scoping ever. First, I think individual assignments are clearer. second, it doesn't work in all versions. So I would suggest that individual assignments would be preferred.
I've seen people simply create a var struct and define your variables as keys for the struct. This way you don't have to use var all the time. E.g.:
<cfset var local = structNew() />
<cfset local.var1 = "" />
<cfset local.var2 = "" />
This is helpful for those who use ColdFusion Server 8 and below and are stuck with the var scope.
Related
I am new to pinescript and have coded a simple indicator in trading view pinescript. I can get my buy and sell labels and also send alert when conditions are met.
I am trying to store the entry price as a variable when a sell or buy signal has been met. I also pass a var called pos which is 1 for sell and 2 for long.
i am trying to make the indicator send an alert when the entry price is above or below 20 pips. however my variable which is passed to the alert is being shadowed??? why??? im sure my code is correct?
var pos=0
var short_update = false
var entry_price = 0
if sellSignal
longLabel = label.new(
x=bar_index,
y=na,
text="Sell - "+ str.tostring(RoundUp(hlc3,2)),
xloc=xloc.bar_index,
yloc=yloc.abovebar,
color=color.red,
textcolor=color.white,
style=label.style_label_down,
size=size.normal)
entry_price=close
pos=1
alertcondition(sellSignal, "Short Alert", "Go short")
price_lower=entry_price-20
current_price=close
if pos==1 and current_price < price_lower
short_update=true
alertcondition(short_update, "Move Stop at BE", "BE")
above is my attempt at coding an alert condition if the entry price of a short is now 20 pips less...not working? please help
Actually all your variables defined with var on top are being shadowed not only "the one" you're referring to.
Shadowing variable 'pos' which exists in parent scope. Did you want to
use the ':=' operator instead of '=' ?
What does it mean?
You have declared your variables and assigned the first values correctly by the assignment operator: = in the global scope. If you want to update these values later on you'll need the reassignment operator though: :=.
The := is used to reassign a value to an existing variable. It says
use this variable that was declared earlier in my script, and give it
a new value.
source
So in your case var pos=0, var short_update = false, var entry_price = 0 are not getting updated through your whole script, are jut being redeclared as new variables in your local scopes that have no effect on the global ones, though having the same name.The solution is as simple as the error message says: use := instead of = if you want to update a declared variable.
Final note: try updating eg.: pos like this pos=1 in the global scope below you var pos=0 declaration. You'll get an error saying "'pos' is already defined". The same applies to your example, the only difference is that it is not illegal to redeclare a variable in a local scope, but Pine Script warns you correctly that it's probably not what you wanted.
I call a function through object at runtime. In this specific case, the function name is supplied through a logic from another page at runtime (the function exists in cfc). At present we use Evaluate and that is very slow. Any way I can get rid of this? I know I can use [] with a structure but here I am lost. qryData is the query object which I pass to the function.
<cfset someData = Evaluate("objTicket.#arrayItem[ItemID].FunctionName#(qryData)")>
<!---this is how it would look like--->
<cfset someData = objTicket.getTickets(qryData)>
Does this fix it for you?
<cfset someData = objTicket[arrayItem[ItemID].FunctionName](qryData)>
I'd like to track SyntaxNodes and SyntaxTrivias across
different versions of a Solution/Workspace.
I tried annotating some nodes with SyntaxAnnotations.
This works well as long as I don't update the workspace.
Calling Workspace.TryApplyChanges (successfully) seems to remove
all SyntaxAnnotations.
This surprised me. Why does this happen?
How can I track SyntaxNodes across workspace updates?
Example code follows:
var workspace = new AdhocWorkspace();
var project = workspace.AddProject("TestProject", LanguageNames.CSharp);
var klass = SyntaxFactory
.ClassDeclaration("Klass")
.WithAdditionalAnnotations(new SyntaxAnnotation("Foo"));
var compUnit = SyntaxFactory.CompilationUnit().AddMembers(klass);
var document = project.AddDocument("TestFile.cs", compUnit);
var docId = document.Id;
var solution = document.Project.Solution;
var root1 = document.GetSyntaxRootAsync().Result;
var klass1 = root1.GetAnnotatedNodes("Foo").FirstOrDefault();
var eq1 = klass1.IsEquivalentTo(klass); // returns true
var apply = workspace.TryApplyChanges(solution); // returns true
var root2 = workspace.CurrentSolution.GetDocument(docId).GetSyntaxRootAsync().Result;
var klass2 = root2.GetAnnotatedNodes("Foo").FirstOrDefault(); // returns null, why?
This happens because TryApplyChanges doesn't actually re-use your nodes as is. Instead it "replays" the same changes as textual changes to the actual solution, and then let's the parser re-parse.
This happens for a few reasons:
To avoid having annotations pile up over time in the trees and interfere with each other (consider something like that formatting or rename annotations used in CodeFixes still being present after the fix was applied).
To protect against trees that don't round-trip from showing up in CurrentSolution. It is possible to construct trees that the parser would never generate (consider changing operator precedence for example).
To ensure the changes are actually applied, requires changing the original representation - the files on disk or the text buffers in memory, not just using the new trees in the workspace.
You could consider using something like the SyntaxPath type from the Roslyn sources to try to find an equivalent node.
I'm trying to modify existing codes in my ColdFusion application left by previous programmer. I don't understand the meaning of this line of code (the one with question marks):
<cfset Application[#form.username#] = 0> ??????
<cfset Session.loggedin="Yes">
<cfset Session.username="#Trim(Form.username)#">
Maybe I haven't been working with CF long enough to see this syntax so I don't know what this mean.
When setting an application variable I usually use this syntax:
<cfset application.variableName = "some value">
Can someone explain to me what is this ?
Thank you
As well as explicitly stating variable names at "code time" with dot notation, CFML allows one to reference them dynamically at runtime via a string value.
This is done via associative array notation (using square brackets), eg:
myVariableName = "foo";
variables[myVariableName] = "moo"; // equivalent to variables.foo = "moo"
I'm a bit stumped on this one..
I currently have a string.
Please enter your variable.firstname here
What i would like to do is find the variable.firstname in the string and convert it to be used as #variable.firstname#
Im using CF8, and ive looked at using findNoCase() but the variable.firstname portion can appear anywhere. I am also trying to use this in a Coldfusion Custom Tag as its to simply display the firstname of the user that could be dynamically populated.
I cant use any other functionality to change it IE = variable['firstname] because the variable could be the result of a dynamic variable i pass in and the query for the content will reside within the custom tag.
<cfset yourNewString = replace(yourOldString,'variable.firstname',
'##variable.firstname##', 'all')>
Note the double pound signs.
I cant use any other functionality to change it IE =
variable['firstname] because the variable could be the result of a
dynamic variable i pass in and the query for the content will reside
within the custom tag.
I'm not sure I understand exactly what you're saying here but if you're saying that variables.firstname is coming from another variable and the .firstname is the dynamic part you could still use array notation.
<cfset myName = "Travis">
<cfset yourName = "user125264">
<cfset myCustomVariable = "myName">
<cfoutput>Hi, My name is #variables[myCustomVariable]#. </cfoutput>
<cfset myCustomVariable = "yourName">
<cfoutput>Your name is #variables[MyCustomVariable]#.</cfoutput>
Output: Hi, My name is Travis. Your name is user125264.
If that isn't what you meant, I apologize.
If you're trying to replace variable.firstname with #variables.firstname# and then also get the value of that variable, you'll need to do the replace <cfset yourNewString = replace(yourOldString,'variable.firstname',
'##variables.firstname##', 'all')> and then wrap the resulting string in an evaluate() function (and an inner de() to prevent CF from evaluating everything): <cfset evaluatedString = evaluate(de(yourNewstring))>.
If there are more variables besides variable.firstname that need this kind of translation, you'll need to get into regex with reReplace() to catch them all in one statement. My regex is rusty, so you'll need to Google that bit on your own. ;o)