Delegates: Difference between revisions

5,693 bytes removed ,  5 years ago
(Added Rust)
Line 1,359:
 
=={{header|M2000 Interpreter}}==
Delegates in M2000 used with Event Objects. An Event object has a signature for arguments and has a list of functions which we can add or remove, and may have a default function. For adding a function(s) we use Event NameOfEvent New. To remove functions we use Event NameofEvent Drop and the names of functions. Functions insert to list as code, and maybe with a weak reference to object where function belong (a static group). So there is no name to compare, only code. To drop a function we have to use a function with same code.
 
In first example we make a Group from a Class (a function which return a group). We make two external events and we call methods in group using events objects by reference. All handling done from outside.
 
The task is to show a call to event when no function defined in event list, then a call to default function (as the second event has a default function), then adding new functions to events we will see how we get feedback using a function from another group.
 
We cab make Global events so we can use them without passing by reference, but code have global names references and that isn't for universal use.
 
<lang M2000 Interpreter>
class Delegator {
Module CheckIt {
private:
Event Alfa {
group delegate
Read X, &Z
group null
}
public:
Event Beta {
function operation$ {
Read A$
if not .delegate is .null then
Function {
=.delegate=>operation$()
Print "Default:"; A$
else
}
= "Default implementation"
}
end if
}
Class ObjectA {
class:
Private:
Module Delegator {
Aname$="No Name Yet"
class none {}
mX=10, mY=20
.null->none()
Public:
If match("G") then .delegate->(group) else .delegate<=.null
Remove {
}
Print "Delete:";.Aname$
}
Module MethodA (&eventA){
oldy=.mY
Call Event EventA .mX, &oldy
If oldy=.mY then Print "Nothing Happen"
}
Module MethodB (&eventB) {
Call Event eventB .Aname$
}
Module SetName (.Aname$) {}
Class:
Module ObjectA {
if match("S") then Read .Aname$
}
}
A=ObjectA("Master")
A.MethodA &Alfa 'Nothing Happen
A.MethodB Beta 'Default:Master
Group CountOne {
counter=0
Function ToDelegateA (a, &b){
b+=a
.counter++
}
}
\\ Now add a function to ALfa, twice
Event Alfa New CountOne.ToDelegateA(), CountOne.ToDelegateA()
For i=1 to 5 : A.MethodA &Alfa :Next i
Print CountOne.counter=10 ' true
Function DelegateB (a$){
Print "Delegate:";a$
}
Event Beta New DelegateB()
A.MethodB &Beta 'Default:Master & Delegate:Master
Event Beta Drop DelegateB()
A.MethodB &Beta 'Default:Master
Event Alfa Hold
For i=1 to 5 : A.MethodA &Alfa :Next i
Print CountOne.counter=10
Event Alfa Release
For i=1 to 5 : A.MethodA &Alfa :Next i
Print CountOne.counter=20
Event Alfa Clear
A.MethodA &Alfa 'Nothing Happen
Clear A
}
Checkit
</lang>
In second example we make a Group with event objects as members. One event is private so we have to make some methods (modules inside group) to handle it. The other event is public so we can handle it from outside the object.
We can use a module B to copy this (supposed we have in module A the above program), so we can run A and B, from M2000 console and see that they have the same output.
 
Class Thing {
Try this too: Copy Alfa and Beta events in module Checikt below, and change A definition using this A=ObjectA("Master", Alfa, Beta) so now we provide two events (passed by copy), from outside but for this group only.
function operation$ {
 
="Delegate implementation"
<lang M2000 Interpreter>
}
Module CheckIt {
Class ObjectA {
Private:
Aname$="No Name Yet"
mX=10, mY=20
Event EventA {}
Public:
Remove {
Print "Delete:";.Aname$
}
Event EventB {}
Module Hold {
Event .EventA Hold
}
Module Release {
Event .EventA Release
}
Module Clear {
Event .EventA Clear
}
Function AddDelegate {
while not empty {
read def$
Event .EventA New def$
}
=true
}
Module MethodA {
oldy=.mY
Call Event .EventA .mX, &oldy
If oldy=.mY then Print "Nothing Happen"
}
Module MethodB {
Call Event .eventB .Aname$
}
Module SetName (.Aname$) {}
Class:
Module ObjectA {
if match("S") then Read .Aname$
if match("EE") then {
Read .EventA, .EventB
} Else {
Event LocalAlfa {
Read X, &Z
}
Event LocalBeta {
Read A$
Function {
Print "Default:"; A$
}
}
.EventA<=LocalAlfa
.EventB<=LocalBeta
}
}
}
A=ObjectA("Master")
A.MethodA 'Nothing Happen
A.MethodB 'Default:Master
Group CountOne {
counter=0
Function ToDelegateA (a, &b){
b+=a
.counter++
}
}
If A.AddDelegate(&CountOne.ToDelegateA(), &CountOne.ToDelegateA()) Then {
For i=1 to 5 : A.MethodA : Next i
Print CountOne.counter=10 ' true
}
Function DelegateB (a$){
Print "Delegate:";a$
}
Event A.EventB New DelegateB()
A.MethodB 'Default:Master & Delegate:Master
Event A.EventB Drop DelegateB()
A.MethodB 'Default:Master
A.Hold
For i=1 to 5 : A.MethodA :Next i
Print CountOne.counter=10
A.Release
For i=1 to 5 : A.MethodA :Next i
Print CountOne.counter=20
A.Clear
A.MethodA 'Nothing Happen
Clear A \\ call Remove function by default
}
A=Delegator()
Checkit
B=Delegator(Thing())
</lang>
Print A.operation$() ' default implementation
Print B.operation$() ' delegate implementation
A=B
Print A.operation$() ' delegate implementation
ebend</lang>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Anonymous user