What's the difference between these two blocks of code, when called right after a cffunction tag:
<cfparam name="bork_bork_bork" default="false">
<cfargument name="bork_bork_bork" required="false" default="false">
<cfparam>, when used with the default attribute, will ensure that a variable exists. Because there is no scope specified, bork_bork_bork is being put in to the Variables scope.
<cfargument> is used to pass an arguments to a function. These values are stored in the Arguments scope. You would access the value using arguments.bork_bork_bork.
Note that arguments.bork_bork_bork and bork_bork_bork are not the same. The scope of arguments is only within the function, the other is being stored in the Variables scope and will be valid anywhere on the page (though I would not recommend coding it that way.)
cfparam has nothing to do with functions. I can see that this is confusing, given that param/argument are interchangeable words in most languages. Keep in mind that user-defined functions weren't added to CF until version 5, so there was no conflict in using cfparam as a way to initialize variables. Moreover, the cfparam tag probably drew its name from the now obsolete function, ParameterExists() (or vice versa - by the time I got into CF, at version 4.0 (1999), that function was already deprecated, so I missed the history behind it)
cfparam is a way to set a default for any variable if the variable doesn't already exist. It's a shortcut to do the following:
<cfif NOT isDefined('bork_bork_bork')>
<cfset bork_bork_bork = 'myDefaultSetting'>
</cfif>
cfargument is only useable after a opening tag to define an argument being passed to a CFC function or a user-defined function.
From what I recall, nothing can exist between the cffunction tag and cfargument tag, so they must appear right after the cffunction tag.
From within the function you'll access cfargument via the arguments scope {arguments.bork_bork_bork} or via an array {arguments1}
cfparam will just ensure the variable is available on the request is should not be used instead of cfargument. For further reading check out:
cfargument
Using the Arguments scope as an array
Defining functions by using the cffunction tag
Related
When creating a live template in WebStorm 2017.3.2 is there a way to apply multiple predefined functions on a single input? Or perhaps reference template variables from other template variables from within the same template?
Say for example I want to apply the capitalizeAndUnderscore function to $FOO$ and also apply the camelCase function to the same input supplied to the $FOO$ variable elsewhere in the template?
In other words, is it possible to achieve the following:
$FOO$: '$FOO_REFERENCE$' expands to MY_WHATEVER: 'myWhatever'
While only having to type mywhatever 1 single time?
Both capitalizeAndUnderscore() and camelCase() functions have String parameter - it can be a string constant, expression or a reference to already defined variable. So, you can easily use capitalizeAndUnderscore(FOO) as $FOO_REFERENCE$ value. But referencing variables defined in other templates is not supported. And you need to make sure that $FOO$ value is defined before being used.
Usually in my code I need to use specific functions for various variables i.e.
object->SetStatus("var1",1); object->SetAddress("var1",&var1);
object->SetStatus("var2",1); object->SetAddress("var2",&var2);
object->SetStatus("var3",1); object->SetAddress("var3",&var3);
...
My idea is to use a function that will do this automatically by calling it, i.e.
object->function(var1,var2,var3,...);
To achieve that I have to solve 3 issues
I need to read the number of arguments when calling function()
I need to parse somehow the argument names inside the code
Since the variables are not of the same type, I need to find a way to make function() type "transparent"
Since I am newbie in c++ coding, I tried to search fo something similar, but I couldn't find anything.
Any help, advice or remark is more than welcome!
There are multiple ways to do so. One way is make a Base class and all your variable type will inherit from this base class. Then pass a map<string,Base> as an argument to you function. name of variable will be key and value will be actual variables. Iterate through the map and set and assign values to methods.
You could consider some variadic template, if coding in C++11 or C++14. There is considerable literature about that subject (e.g. this tutorial), which is a bit tricky (so explaining it here is not reasonable). Read also about parameter pack
You could also use C style varargs using <cstdarg>
Perhaps std::initializer_list could be useful too.
Is there such a mechanism in OCaml, such that I could invoke a function dynamically based on a variable storing the function name, like what I can do in other scripting languages?
For example, I have written a function foo(). And I store the String constants "foo" somewhere in a variable "x". In JavaScript I'm able to do something like this window[x](arguments); to dynamically invoke the method foo(). Can I do something similar in OCaml?
No, this is not the kind of thing that OCaml lets you do easily. The program definition, including the names of functions and so on, isn't available for the program itself to manipulate.
A simple way to get this effect for a set of functions known ahead of time is to make a dictionary (a hash table or a map, say) of functions using the function name as the key. Note that this will require the functions to have the same type (which is a feature of OCaml not a problem :-).
I've full discussed the requirement and my investigations thusfar on my blog: "Can a function expression circumvent closure?"
In summary, when one has this code:
o = new C();
function dumpVariables(){
writeDump(var=variables);
}
o.dumpVariables = dumpVariables;
o.dumpVariables();
Then the writeDump() will reference the CFC's internal variables scope. However if one uses a function expression instead of a declaration:
dumpVariables = function (){
writeDump(var=variables);
};
(The rest of the code being the same, just how the dumpVariables() function is created)
... then - because function expressions use closure when binding variable references, that reference to variables in the writeDump() statement still references the calling code's variables scope, even when it's being called from within the object the function has been injected into.
This is a very simplified repro case for the purposes of asking this question, so the stipulation is that the the function being injected into the object must be created via a function expression, and the other stipulation is that the function expression is the only code I can change. I say this because I'm fully aware of work-arounds for this which don't use function expressions, or leverage changes to the CFC code etc... that's not my problem. The problem I am having and am hoping someone can help with is how one can access the variable context of when the function is called rather than when it's being declared.
Thanks for any insight. I suspect the answer is "cannot be done".
So here's my question in the function declaration there is an argument and it is already initialized to a certain value. What are the procedures to call this function and use that default value, or is it just a way to document code, telling other programmers what you expect them to use as a value for the parameter? Thank you.
enum File
{
XML = 0,
PDF = 1,
};
Char *SetSection(const File = XML);
If I understand your question correctly, simply calling SetSection with no parameters will do.
SetSection();
The above call gets translated (for lack of a better term) to:
SetSection(XML);
It means that the function can be called without parameters in which case the default value, XML, will be used.
In this case, File is a default argument. Calling SetSection() without arguments will set the File argument to the default value specified in the declaration.
If you call
SetSection();
It will call SetSection(XML) instead.
This is why the optional parameters have to be at the end of all parameters. If you don't provide enough parameters, it will use the default.
XML is the standard parameter.
You can call it with SetSection(); (But SetSection(XML) or SetSection(PDF) are valid, too).
What you are seeing in the declaration is a default argument value.
If you call SetSection(); it is the same as calling SetSection(XML);
You can also call SetSelection(PDF); or use any other valid parameter to override the default.
You may also be seeing the result of an incremental development which started with the function having no parameter and calls to the function scattered throughout the code. Then the alternative file type of PDF was introduced, but the prototype was changed to have a default value, which meant not having to change the existing call site.