How can i call a function form a variable.
var upfunction = init;
//or
var upfunction = init();
I have tried the above code and it does not work. I want to be able to call that variable from a keypress and change the variables function. For example.
function init(){
//Do whatever
}
function init2(){
//Do another thing
}
var upfunction = init();
if (Key.getCode() == Key.UP)
{
upfunction;
}
Then later doing
upfunction = init2();
That way i could change the function without having much code. Sorry if this is a noob question but all i do is copy and paste code i have found.
You're almost right with what you've got... just remember that to call a function you need to include the brackets afterwards: 'upFuntion();'. Brackets are also needed when defining the function. The brackets will contain any function parameters.
But to refer to the function (such as when assigning it to a variable) you don't use the brackets: 'upFunction = init;'
So your example would look like this:
function init1():Void {
trace("hello this is init1");
}
function init2():Void {
trace("hey, this is init2");
}
var upFunction:Function = init1;//type declaration is optional but recommended
upFunction();// hello this is init1
upFunction = init2;
upFunction();//hey, this is init2
Related
I'm working on a Swift 3 project that involves using some C APIs that I bridged from Objective-C.
Here is a sample snippet of the structure of the API:
typedef struct
{
StructMode mode;
StructLevel level;
} TargetStruct;
typedef struct
{
. . .
TargetStruct *targetStruct;
OtherStruct *otherStruct;
NonPointerStructA nonPointerStructA;
NonPointerStructB nonPointerStructB;
. . .
} InnerStruct;
typedef struct
{
InnerStruct innerStruct;
OtherStructB otherStructB;
} OuterStruct;
In my Swift code, my goal is to set a value of the TargetStruct from the OuterStruct, like the following:
// run function that returns an instance of TargetStruct
var targetStruct: TargetStruct = initializeTargetStruct()
// assign targetStruct to outerStruct
outerStruct.innerStruct.targetStruct = &targetStruct
However, I am getting the following error:
Cannot pass immutable value of TargetStruct as inout argument
If I set a value of a struct without the *, it will work fine:
var nonPointerStructA: NonPointerStructA = initializeNonPointerStructA()
outerStruct.innerStruct.nonPointerStructA = nonPointerStructA
I have tried setting the value of targetStruct like this, but for now I have no way to test it:
var targetStruct: TargetStruct = initializeTargetStruct()
outerStruct.innerStruct.targetStruct.initialize(from: &targetStruct, count: 0)
How to solve this problem? Thank you.
In Swift, prefix & is not an address-of operator. It is just needed to clarify that some expression is passed to an inout parameter. So, your first code is syntactically invalid in Swift.
Your C-structs are imported to Swift as follows:
struct TargetStruct {
var mode: StructMode
var level: StructLevel
//some auto generated initializers...
}
struct InnerStruct {
//...
var targetStruct: UnsafeMutablePointer<TargetStruct>!
var otherStruct: UnsafeMutablePointer<OtherStruct>!
var nonPointerStructA: NonPointerStructA
var nonPointerStructB: NonPointerStructB
//some auto generated initializers...
}
struct OuterStruct {
var innerStruct: InnerStruct
var otherStructB: OtherStructB
//some auto generated initializers...
}
(If something wrong, please tell me.)
As you see, targetStruct in your InnerStruct is a pointer, and initialize(from:count:) tries to write to the pointed region, but at the time you call initialize(from:count:), targetStruct holds its initial value nil, you know what happens when dereferencing null-pointer.
One way is to allocate a memory for the TargetStruct and use the pointer to the allocated region.
func allocateAndInitializeTargetStruct() -> UnsafeMutablePointer<TargetStruct> {
let targetStructRef = UnsafeMutablePointer<TargetStruct>.allocate(capacity: 1)
targetStructRef.initialize(to: initializeTargetStruct())
return targetStructRef
}
outerStruct.innerStruct.targetStruct = allocateAndInitializeTargetStruct()
This is a more general way than below, but you need to explicitly deinitialize and deallocate the allocated region. That's sort of hard to manage.
If you can confine the usage of the outerStruct in a single code-block, you can write something like this:
var targetStruct = initializeTargetStruct()
withUnsafeMutablePointer(to: &targetStruct) {targetStructPtr in
outerStruct.innerStruct.targetStruct = targetStructPtr
//Use `outerStruct` only inside this code-block
//...
}
In this case, the pointer held in outerStruct.innerStruct.targetStruct (== targetStructPtr) is only valid inside the closure and you cannot use it outside of it.
If any of the codes above does not fit for your use case, you may need to provide more context to find the best solution.
An example of nested use of withUnsafeMutablePointer(to:_:):
var targetStruct = initializeTargetStruct()
var otherStruct = initializeOtherStruct()
withUnsafeMutablePointer(to: &targetStruct) {targetStructPtr in
withUnsafeMutablePointer(to: &otherStruct) {otherStructPtr in
outerStruct.innerStruct.targetStruct = targetStructPtr
outerStruct.innerStruct.otherStruct = otherStructPtr
//Use `outerStruct` only inside this code-block
//...
}
}
When you need more pointers to set, this nesting would be a mess, but it's the current limitation of Swift.
An example of deinitialize and deallocate:
extension InnerStruct {
func freeMemberStructs() {
if let targetStructRef = targetStruct {
targetStructRef.deinitialize()
targetStructRef.deallocate(capacity: 1)
targetStruct = nil
}
if let otherStructRef = otherStruct {
otherStructRef.deinitialize()
otherStructRef.deallocate(capacity: 1)
otherStruct = nil
}
}
}
outerStruct.innerStruct.targetStruct = allocateAndInitializeTargetStruct()
outerStruct.innerStruct.otherStruct = allocateAndInitializeOtherStruct()
// Use `outerStruct`
//...
outerStruct.innerStruct.freeMemberStructs()
The code may not seem to be too complex (just a bunch of boilerplate codes), but it's hard to find when or where to do it. As your InnerStruct may be embedded in another struct which may need to be deinitilized and deallocated...
Hope you can find your best solution.
I want to parse and set a variable conditionally in Go at the global package level based on the value of of an ENV var, so that I don't have to check for it every time in a utility function (as the variable would be declared once at run time). For example, what I want to accomplish is (Go pseudo-code):
import (
"fmt"
"os"
"strconv"
)
// This works to read the value of MYVAR (=true/false)
var myvar string = os.Getenv("MYVAR")
// Apparently this is too much for Go
var myvarbool, _ = strconv.ParseBool(myvar)
// Utility function to check for value
func mycheck() {
if myvarbool {
fmt.Print("MYVAR is true")
}
}
This is a library package, so doesn't have a main() function to do this kind of setup, but I want to be able to use mycheck() in other functions in the library, and don't want to have to read and parse MYVAR every time mycheck() is called.
One way to accomplish what you're looking to do would be to process the environment variable in an init() function, so something like the following would work:
package main
import (
"fmt"
"os"
"strconv"
)
var (
myvar string = os.Getenv("MYVAR")
myvarbool bool
)
func init() {
myvarbool, _ = strconv.ParseBool(myvar)
}
// Utility function to check for value
func mycheck() {
if myvarbool {
fmt.Print("MYVAR is true")
}
}
Playground
I'm not sure what problem you had, your code from the OP is valid, also you can have it in one line like:
var myvarbool, _ = strconv.ParseBool(os.Getenv("MYVAR"))
playground
After actually thinking about this for a couple of minutes, I've realised I can just create a wrapper function to do the work, and call that instead (again, largely pseudo-code without extra checks):
var myenvbool bool = myenv("MYVAR")
func myenv(envvar string) bool {
myenvvalue := os.Getenv(envvar)
myenvbool, _ := strconv.ParseBool(myenvvalue)
return myenvbool
}
func checkenv() {
if myenvbool {
fmt.Print("myenvbool is true")
}
}
I have a function that could be used in CLI or web application, that being said, there is a little difference in the process; for example: if I'm using this function for CLI it'll use a text progress bar, but that doesn't make sense if I'm using this function for a web application.
The function is basically a loop; so what i'm looking for is a way to make this function flexible by making it possible to pass code as an argument so that it'll be executed at the end of each loop cycle. So if I'm using this function in CLI; i'll pass a progress incremental function to advance the progress bar, and so on.
My current solution is to pass a progress bar object instance, which I think isn't a proper solution; because it doesn't seem flexible for the long run.
A demonstration example of what I'm already doing:
function myFunction($progressBar = null)
{
for($i = 0; $i......)
{
//Do stuff
....
//finally...
if(!empty($progressBar))
$progressBar->advance();
}
}
So, if I want to add another function at the end of the loop, I'll have to pass it as an argument and call it manually later; but as I said, it just doesn't seem right.
I'm thinking of using a callback function(an anonymous function being passed to myFunction) But what is a proper way of doing that; should I just make each callback function as an individual argument? or, to make it even more flexible, should I be grouping all callback functions in an array(if that's possible).
Yes, you can use callbacks for this.
function myFunction($progressBar = null, callable $callback = null)
{
for($i = 0; $i......)
{
//Do stuff
....
//finally...
if(!empty($progressBar))
$progressBar->advance();
}
if ($callback){ //Execute the callback if it is passed as a parameter
$callback();
}
}
Also, you can specify parameters for an anonymous function:
Example: you want to echo something at some point.
myFunction($progressBar) ; //No need yet
myFunction($progressBar, function($result){ echo $result ; }) ; //Now you want to execute it
So, handle it in an appropriate way:
if ($callback){ //Execute the callback if it is passed as a parameter
$callback("All is fine"); //Execute the callback and pass a parameter
}
Array of callbacks also may be useful in this case like:
$callbacks = array(
"onStart" => function(){ echo "started" ; },
"onEnd" => function(){ echo "ended" ; }
) ;
function myFunc($progressBar = null, $callbacks){
if (isset($callbacks["onStart"]) && is_callable($callbacks["onStart"])){
$callbacks["onStart"]() ;//Execute on start.
}
//Execute your code
if (isset($callbacks["onEnd"]) && is_callable($callbacks["onEnd"])){
$callbacks["onEnd"]() ;//Execute on end.
}
}
I use the following pattern in my JS:
var lib =
{
module_one:
{
init: function () {
...
}
},
module_two:
{
init: function () {
...
}
}
};
Question is, whats the best way to add:
(function ($) {
...
})(jQuery);
I tried to put it around the var lib, but that didnt work. To add it inside each function worked, but seems a bit messy..?
Is it possible to add it to the init: function($) somehow?
Quite new on jQuery, so if you have any other suggestions around this pattern, let me know :-)
Basically, you can do this:
(function() {
var global, lib, oldlib;
// We call this anonymous scoping function directly, so we know that
// within it, `this` is the JavaScript global object. Grab a
// local reference to it so we can use it within functions that get
// called via dotted notation and so have different `this` values.
global = this;
// Remember any value that already exists for the `lib` property
// of the global
oldlib = global.lib;
// Define our lib, assigning it to a local variable
lib = {
/* ...your stuff as usual, plus: */
noConflict: function() {
global.lib = oldlib;
return lib;
}
};
// Publish our lib externally on the global object
global.lib = lib;
})();
...which can then be used like this:
var alias = lib.noConflict();
Here's how that works:
We define a scoping function and then immediately call it.
Within the scoping function, we grab the this value as a variable called global. This will be the JavaScript global object because of the way we're calling the scoping function. (The global object on browsers is window, but there's no need to limit this to browsers, hence getting global this way).
The first thing we do is save any old value the lib property of the global object had, in a local variable in our scoping function called oldlib.
We set up our new value for lib.
Our noConflict function restores the earlier value of the lib property, and returns our lib reference so someone can use it as an alias.
BTW, when you use a scoping function, you can also switch over to using named functions rather than anonymous ones, which has several benefits. Here's the above updated to use a named function for noConflict.
(function() {
var global, lib, oldlib;
// We call this anonymous scoping function directly, so we know that
// within it, `this` is the JavaScript global object. Grab a
// local reference to it so we can use it within functions that get
// called via dotted notation and so have different `this` values.
global = this;
// Remember any value that already exists for the `lib` property
// of the global
oldlib = global.lib;
// Define the functions for our lib. Because they're defined
// within our scoping function, they're completely private
function lib_noConflict() {
global.lib = oldlib;
return lib;
}
// Define our lib, publishing the functions we want to be public
lib = {
/* ...your stuff as usual, plus: */
noConflict: lib_noConflict
};
// Publish our lib externally on the global object
global.lib = lib;
})();
I have the following function, but I can't seem to get the myVar variable into the inline function. What am I doing wrong here? What I would like to have happen is when I click on myMc, it should print myVar to the console ("hello computer").
function doSomething():Void
{
myVar = "hello computer";
myMc.onRelease = function(){
trace(myVar); //prints as "undefined"
}
}
ps. - I cannot declare myVar as a global or static variable because in the real code, I'm parsing XML and the myVar is constantly changing.
This is a scope issue - when you apply an onRelease function like this in as2, the scope of the function is the MovieClip you apply the function to, not the calling function.
Because you are using AS2 and MovieClip is dynamic, you can assign the variable to the MC directly:
function doSomething():Void
{
myMc.myVar = "hello computer";
myMc.onRelease = function(){
trace(this.myVar);
}
}
Try declaring myVar with the var keyword:
var myVar = "hello computer";