D (dlang) passing a lambda function as argument - function

With D, how can I pass a function (possibly reference to a function) as an argument to be executed inside other function?
import std.stdio : writeln;
class Event {}
class EventTarget
{
void addEventListener(string eventName, void delegate(Event event) callback)
{
// TODO: add to slice to execute later, for now execute directly
callback();
}
}
void main()
{
auto variableFromParentScope = "lorem ipsum";
auto target = new EventTarget();
target.addEventListener("load", (Event event) => { writeln(variableFromParentScope, event); }, true);
}
Gives me the error:
onlineapp.d(10): Error: delegate callback(Event event) is not callable using argument types ()
onlineapp.d(10): missing argument for parameter #1: Event event
onlineapp.d(18): Error: function onlineapp.EventTarget.addEventListener(string eventName, void delegate(Event event) callback) is not callable using argument types (string, void delegate() #system delegate(Event event) pure nothrow #safe, bool)
onlineapp.d(18): cannot pass argument __lambda1 of type void delegate() #system delegate(Event event) pure nothrow #safe to parameter void delegate(Event event) callback
I have set up the example here: https://run.dlang.io/is/FnQoId
SOLUTION, With the help from the answers I fixed it like this:
import std.stdio : writeln;
class Event {}
class EventTarget
{
void addEventListener(string eventName, void delegate(Event event) callback)
{
// TODO: add to slice to execute later, for now execute directly
callback(new Event());
}
}
void main()
{
auto variableFromParentScope = "lorem ipsum";
auto target = new EventTarget();
target.addEventListener(
"load",
(Event event) {
writeln(variableFromParentScope, event);
}
);
}
Working example: https://run.dlang.io/is/6aDRoU

You are using the wrong syntax for the delegate, as you can also see in the error message it doesn't have the expected type.
To explain further, I will show you how it changes if you extend it to the longer form of a delegate instead of using the shorthand =>:
(Event event) => { writeln(variableFromParentScope, event); }
becomes
(Event event) { return { writeln(variableFromParentScope, event); }; }
As you can see you are returning a delegate with no parameters inside your actual delegate. If you remove the =>, your delegate will work as expected.
Alternative valid forms for your delegate parameter would be:
(event) { ... }
delegate (Event event) { ... }
delegate (event) { ... }
&someMemberMethod // some object member method taking in Event as first parameter
toDelegate(&someGlobalFunction) // from std.functional
Only if you want to return something you use the => arrow. A use-case for () => { something } would be a delegate returning a delegate (like a delegate generating delegates for a given input)
But also wrong in your question is that you are calling that function with a , true in the calling parameters, which makes the error message very confused, and that you aren't passing an event parameter to the callback, which would be another error in the code snippet.

target.addEventListener("load", (Event event) => { writeln(variableFromParentScope, event); }, true);
(Args) => {} is a lambda which returns a lambda.
Correct forms:
target.addEventListener("load", (Event event) { writeln(variableFromParentScope, event); }, true);
target.addEventListener("load", (Event event) => writeln(variableFromParentScope, event), true);

Related

What is the difference between Function and Method in Dart programming language?

I am new to Dart and Flutter, I wanted to know what i the actual difference and when to use which one.
A function is a top-level function which is declared outside of a class or an inline function that is created inside another function or inside method.
A method is tied to an instance of a class and has an implicit reference to this.
main.dart
// function
void foo() => print('foo');
// function
String bar() {
return 'bar';
}
void fooBar() {
int add(int a, int b) => a + b; // inline function
int value = 0;
for(var i = 0; i < 9; i++) {
value = add(value, i); // call of inline function
print(value);
}
}
class SomeClass {
static void foo() => print('foo'); // function in class context sometimes called static method but actually not a method
SomeClass(this.firstName);
String firstName;
// a real method with implicit access to `this`
void bar() {
print('${this.firstName} bar');
print('$firstName bar'); // this can and should be omitted in Dart
void doSomething() => print('doSomething'); // inline function declared in a method
doSomething(); // call of inline function
}
}
Like inline functions you can also create unnamed inline functions, also called closures. They are often used as callbacks like
button.onClick.listen( /* function start */ (event) {
print(event.name);
handleClick();
} /* function end */);

Is it possible to make use of a value returned from a method called by a delegate?

While experimenting with a basic coding stuff, I wondered, if a value returned by a method called by a delegate, could be used or captured. In other words, where will the return value will go ?
For example :
class Main extends Sprite
{
public var mc:MyMc;
function Main()
{
mc.addEventListener( "myClick" , myClick);
}
function myClick(e:Event):String //returning a string
{
return "What happens to this return value ???"
}
}
class MyMc extends MovieClip
{
function MyMc()
{
addEventListener( MouseEvent.CLICK , onClick);
}
function onClick(e:Event):String //returning a string
{
dispatchEvent(new Event("myClick"));
}
}
As I know it's not possible to do, but, there are at least some ways to implement the logic similar to what you've told about.
For example, you may call a method of a dispatcher, from a listener method:
class Main extends Sprite
{
public var mc:MyMc;
function Main()
{
mc.addEventListener("myClick" , myClick);
}
function myClick(e:Event):void
{
mc.specialMethod("some string");
}
}
class MyMc extends MovieClip
{
function MyMc()
{
addEventListener(MouseEvent.CLICK , onClick);
}
function onClick(e:Event):void
{
dispatchEvent(new Event("myClick"));
}
public function specialMethod(param:String):void
{
// Do something to the param
}
}
Also, you may think about dispatching an event from the Main class, and listen to it in the MyMc class, or pass a callback, which returns a string, from Main to the MyMc.
It's according to you and your needs to return something from the listener function because normally it must return nothing :
... This function must accept an Event object as its only parameter and must return nothing, ...
but you can of course get the returned value(s), take a look on this little example :
var light_on:Boolean = false;
btn_light_on.addEventListener(MouseEvent.CLICK, btn_on_onPress);
btn_light_off.addEventListener(MouseEvent.CLICK, btn_off_onPress);
function btn_on_onPress(e:MouseEvent): Boolean {
light_on = true;
if(e.target === btn_light_off){
light_on = false;
}
return light_on;
}
function btn_off_onPress(e:MouseEvent): void {
trace('The light is', btn_on_onPress(e) ? 'on' : 'off');
}
Hope that can help.

Finding the method name from an ExternalInterface.addCallback

Let's say we have a number of ExternalInterface.addCallback functions, like so:
ExternalInterface.addCallback( 'foo', handler );
ExternalInterface.addCallback( 'bar', handler );
ExternalInterface.addCallback( 'foobar', handler );
In the function handler I'd like to find the method name called through the external interface, such as foo, bar or foobar; is there a way? Eg:
private function handler(...args):void
{
arguments.callee.arguments[ 0 ];
}
But I doubt that'll work
This should work. Just pass a parameter that identifies your function from the javascript, for example a string. So when you call the flash-function in your javascript code, pass a string, which you then parse in your handler function. For example:
actionscript:
ExternalInterface.addCallback( 'foo', handler );
private function handler(s:String):void
{
if(s == "foo") {
//foo specific code
}
}
javascript:
document.getElementById('flashObj').foo("foo");
Not exactly what you are asking for, but it will give you the info you need.
Just make the first parameter that you send the function name or in this case the object with funcname attribute so you can test if it exists.
JavaSCript
function thisMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
}
thisMovie("ExternalInterfaceExample").genericCallBack({ funcname:'foo' })
thisMovie("ExternalInterfaceExample").genericCallBack({ funcname:'poo' })
thisMovie("ExternalInterfaceExample").genericCallBack({ funcname:'moo' })
AS3
public function foo( ):void{
trace('in foo')
}
public function poo( ):void{
trace('in poo')
}
public function moo( ):void{
trace('in moo')
}
public function genericCallBack( o:Object ):void{
trace( 'calling '+o.funcname)
this[o.funcname]()
}
// add this somewhere in your init process
ExternalInterface.addCallback( 'genericCallBack', genericCallBack );

Using a callback (instead of an event) in Actionscript 3.0

Can anyone provide an example of how to write a callback instead of using an event to communicate between two classes (objects) in Actionscript 3.0?
Just pass a function to another one as parameter to make your callback :
class A {
function A(){
}
// function to be called when work is finished
private function workDone():void {
//...
}
public function foo():void {
var b:B=new B();
b.doWork(workDone); // pass the callback to the work function
//can also be an anonymous function, etc..
b.doWork(
function():void{
//....
}
);
}
}
class B {
function B(){
}
public function doWork(callback:Function):void{
// do my work
callback(); // call the callback function when necessary
}
}
What do you mean? A callback is a function that is called in response to an event - in AS parlance, it's an event listener. If you just want classes to communicate, have one of them call a method on the other.

How to call "this" from an anonymous method?(flex, as)

This is my code:
public function setPaneContent(names : Array, parent : AbstractPane) : void {
//....
okButton.addEventListener(MouseEvent.CLICK, function okMouseClickHandler(e : Event) : void {
parent.addNewPane(valuesPane, parent);
PopUpManager.removePopUp(/*need to put "this"*/);
});
//.....
}
When i call PopUpManager.removePopUp(/*need to put "this"*/);, i need to make a reference at the object that contains this method(this).
So my question is: "Is it possible to make a reference at 'this' keyword within an anonymous method?"
store this to some variable: _this = this in the constructor, use _this. (it works in javascript)
You don't have to, you can call another function
public function setPaneContent(names : Array, parent : AbstractPane) : void
{
okButton.addEventListener(MouseEvent.CLICK,
function okMouseClickHandler(e : Event) :void
{
parent.addNewPane(valuesPane, parent);
// call the remove function where you can reference "this"
remove();
});
//.....
}
private function remove():void
{
PopUpManager.removePopUp(this);
}