Delegates: Difference between revisions

31,576 bytes added ,  2 months ago
Added FreeBASIC
(Added FreeBASIC)
 
(69 intermediate revisions by 27 users not shown)
Line 16:
=={{header|Ada}}==
All that is needed in order to implement this is a common base type. The delegator holds a pointer to an "untyped" object from the base class. Querying if the target implements the delegate interface is done using run-time type identification.
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Delegation is
Line 63:
A.Delegate := Has_Thing'Access; -- Set a thing
Put_Line (A.Operation);
end Delegation;</langsyntaxhighlight>
Sample output:
<pre>
Line 70:
delegate implementation
</pre>
 
=={{header|Aikido}}==
<syntaxhighlight lang="aikido">
class Delegator {
public generic delegate = none
 
public function operation {
if (typeof(delegate) == "none") {
return "default implementation"
}
return delegate()
}
}
 
function thing {
return "delegate implementation"
}
 
// default, no delegate
var d = new Delegator()
println (d.operation())
 
// delegate
var d1 = new Delegator()
d1.delegate = thing
println (d1.operation())
 
</syntaxhighlight>
 
=={{header|Aime}}==
<langsyntaxhighlight lang="aime">text
thing(void)
{
Line 113 ⟶ 141:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|AikidoALGOL 68}}==
As Algol 68 doesn't have classes, we supply a non-OO approximation, similar to the C version.
<lang aikido>
<syntaxhighlight lang="algol68"># An Algol 68 approximation of delegates #
class Delegator {
public generic delegate = none
 
# The delegate mode - the delegate is a STRUCT with a single field #
public function operation {
# that is a REF PROC STRING. If this is NIL, it doesn't implement #
if (typeof(delegate) == "none") {
# thing #
return "default implementation"
MODE DELEGATE = STRUCT( REF PROC STRING thing );
}
return delegate()
}
}
 
function thing {
return "delegate implementation"
}
 
# A delegator mode that will invoke the delegate's thing method #
// default, no delegate
# - if there is a delegate and the delegate has a thing method #
var d = new Delegator()
MODE DELEGATOR = STRUCT( REF DELEGATE delegate
println (d.operation())
, PROC( REF DELEGATE )STRING thing
);
 
# constructs a new DELEGATE with the specified PROC as its thing #
// delegate
# Algol 68 HEAP is like "new" in e.g. Java, but it can't take #
var d1 = new Delegator()
# parameters, so this PROC does the equivalent #
d1.delegate = thing
PROC new delegate = ( REF PROC STRING thing )REF DELEGATE:
println (d1.operation())
BEGIN
REF DELEGATE result = HEAP DELEGATE;
thing OF result := thing;
 
result
</lang>
END # new delegate #
;
 
# constructs a new DELEGATOR with the specified DELEGATE #
PROC new delegator = ( REF DELEGATE delegate )REF DELEGATOR:
HEAP DELEGATOR := ( delegate
, # anonymous PROC to invoke the delegate's thing #
( REF DELEGATE delegate )STRING:
IF delegate IS REF DELEGATE(NIL)
THEN
# we have no delegate #
"default implementation"
 
ELIF thing OF delegate IS REF PROC STRING(NIL)
THEN
# the delegate doesn't have an implementation #
"default implementation"
 
ELSE
# the delegate can thing #
thing OF delegate
 
FI
)
;
 
 
# invokes the delegate's thing via the delagator #
# Because the PROCs of a STRUCT don't have an equivalent of e.g. Java's #
# "this", we have to explicitly pass the delegate as a parameter #
PROC invoke thing = ( REF DELEGATOR delegator )STRING:
# the following is Algol 68 for what would be written in Java as #
# "delegator.thing( delegator.delegate )" #
( thing OF delegator )( delegate OF delegator )
;
 
main:
(
 
print( ( "No delegate : "
, invoke thing( new delegator( NIL ) )
, newline
, "Delegate with no thing: "
, invoke thing( new delegator( new delegate( NIL ) ) )
, newline
, "Delegate with a thing : "
, invoke thing( new delegator( new delegate( HEAP PROC STRING := STRING: ( "delegate implementation" ) ) ) )
, newline
)
)
 
)
</syntaxhighlight>
{{out}}<pre>
No delegate : default implementation
Delegate with no thing: default implementation
Delegate with a thing : delegate implementation
</pre>
 
 
=={{header|Atari Basic}}==
 
The code does not fully implement all requirements from above.
If you find which requirements have not been met that's great.
What is your proposal to solve that in the code?
 
<syntaxhighlight lang="ataribasic">
10 REM DELEGATION CODE AND EXAMPLE . ATARI BASIC 2020 A. KRESS andreas.kress@hood-group.com
14 REM
15 GOTO 100:REM MAINLOOP
16 REM
20 REM DELEGATOR OBJECT
21 REM
30 IF DELEGATE THEN GOSUB DELEGATE:GOTO 56
35 REM
50 REM DELEGATOR HAS TO DO THE JOB
55 PRINT "DEFAULT IMPLEMENTATION - DONE BY DELEGATOR"
56 RETURN
60 REM CALL DELEGATE
65 GOSUB DELEGATOR
66 RETURN
79 REM
80 REM DELEGATE OBJECT
81 REM
90 PRINT "DELEGATE IMPLEMENTATION - DONE BY DELEGATE"
91 RETURN
99 REM
100 REM MAINLOOP - DELEGATION EXAMPLE
101 REM
110 DELEGATE=0:REM NO DELEGATE
120 GOSUB 20:REM INIT DELEGATOR
130 DELEGATE=80:REM DELEGATE IS
140 GOSUB 20:REM INIT DELEGATOR
</syntaxhighlight>
{{out}}<pre>
RUN
DEFAULT IMPLEMENTATION - DONE BY DELEGATOR
DELEGATE IMPLEMENTATION - DONE BY DELEGATE
 
Ready
</pre>
 
=={{header|C}}==
As best you can do, without support for classes.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 230 ⟶ 357:
Delegator_Operation( theDelegator, 3, del2));
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
 
interface IOperable
Line 271 ⟶ 398:
}
}
}</langsyntaxhighlight>
Output:
<pre>Default implementation.
Line 280 ⟶ 407:
Delegates in the C# or D style are available in C++ through std::tr1::function class template. These delegates don't exactly match this problem statement though, as they only support a single method call (which is operator()), and so don't support querying for support of particular methods.
 
<syntaxhighlight lang="cpp">
<lang Cpp>
#include <tr1/memory>
#include <string>
Line 360 ⟶ 487:
*/
}
</syntaxhighlight>
</lang>
 
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">(defprotocol Thing
(thing [_]))
 
(defprotocol Operation
(operation [_]))
 
(defrecord Delegator [delegate]
Operation
(operation [_] (try (thing delegate) (catch IllegalArgumentException e "default implementation"))))
 
(defrecord Delegate []
Thing
(thing [_] "delegate implementation"))</syntaxhighlight>
 
{{out}}
<pre>
; without a delegate
=> (operation (Delegator. nil))
"default implementation"
 
; with a delegate that does not implement "thing"
=> (operation (Delegator. (Object.)))
"default implementation"
 
; with a delegate that implements "thing"
=> (operation (Delegator. (Delegate.)))
"delegate implementation"
</pre>
 
=={{header|CoffeeScript}}==
{{trans|Python}}
<langsyntaxhighlight lang="coffeescript">
class Delegator
operation: ->
Line 388 ⟶ 546:
testDelegator()
</syntaxhighlight>
</lang>
output
<syntaxhighlight lang="text">
> coffee foo.coffee
default implementation
default implementation
Delegate Implementation
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
Line 402 ⟶ 560:
In CLOS, methods exist apart from classes, and are specialized based on the types of their arguments. This example defines two classes (delegator and delegate), and a thing generic method which is specialized in three ways: (1) for 'any' argument, providing a default method; (2) for delegators, where thing is recursively applied to the delegator's delegate (if there is one); and (3) for delegates.
 
<langsyntaxhighlight lang="lisp">(defgeneric thing (object)
(:documentation "Thing the object."))
 
Line 430 ⟶ 588:
(assert (string= "no delegate" (thing d1)))
(assert (string= "default implementation" (thing d2)))
(assert (string= "delegate implementation" (thing d3))))</langsyntaxhighlight>
 
=={{header|D}}==
Line 436 ⟶ 594:
''Delegate'' object and pass a real delegate directly to '''Delegator'''.
 
<langsyntaxhighlight lang="d">class Delegator {
string delegate() hasDelegate;
 
Line 459 ⟶ 617:
writeln(dr.operation());
writeln(dr.setDg(thing).operation());
}</langsyntaxhighlight>
{{out}}
<pre>Default implementation
Line 467 ⟶ 625:
===Version using Tango===
{{libheader|tango}}
<langsyntaxhighlight lang="d">import tango.io.Stdout;
 
class Delegator
Line 495 ⟶ 653:
Stdout ( dr.setDg(thing).operation ).newline;
return 0;
}</langsyntaxhighlight>
 
=={{header|Dart}}==
I didn't find a way to check for existing methods, so the version with Object doesn't work yet. The code is adapted from the Java version, but using var instead of an Interface
<langsyntaxhighlight lang="dart">class Delegator {
var delegate;
Line 527 ⟶ 685:
a.delegate = d;
Expect.equals("delegate implementation",a.operation());
}</langsyntaxhighlight>
 
=={{header|Delphi}}==
Translation of the Java example found at [http://en.wikipedia.org/wiki/Delegation_pattern Wikipedia].
<langsyntaxhighlight Delphilang="delphi">unit Printer;
 
interface
Line 580 ⟶ 738:
end;
 
end.</langsyntaxhighlight>
<langsyntaxhighlight Delphilang="delphi">program Delegate;
 
{$APPTYPE CONSOLE}
Line 599 ⟶ 757:
PrinterObj.Free;
end;
end.</langsyntaxhighlight>
 
=={{header|E}}==
 
<langsyntaxhighlight lang="e">def makeDelegator {
/** construct without an explicit delegate */
to run() {
Line 636 ⟶ 794:
> })
> delegator.operation()
# value: "default implementation"</langsyntaxhighlight>
 
=={{header|Elena}}==
ELENA 6.x :
 
Using multi methods:
<syntaxhighlight lang="elena">import extensions;
import system'routines;
interface IOperable
{
abstract operate();
}
class Operable : IOperable
{
constructor() {}
operate()
= "delegate implementation";
}
class Delegator
{
object theDelegate;
set Delegate(object)
{
theDelegate := object
}
internal operate(operable)
= "default implementation";
internal operate(IOperable operable)
= operable.operate();
operate()
<= operate(theDelegate);
}
public program()
{
var delegator := new Delegator();
new object[]{nil, new Object(), new Operable()}.forEach::(o)
{
delegator.Delegate := o;
console.printLine(delegator.operate())
}
}</syntaxhighlight>
Generic solution:
<syntaxhighlight lang="elena">import extensions;
import system'routines;
 
class Operable
{
Operable = self;
operate()
= "delegate implementation";
}
class Delegator
{
object Delegate : prop;
constructor()
{
Delegate := nil
}
operate()
{
// if the object does not support "Operable" message - returns nil
var operable := Delegate.Operable \ back(nil);
if (nil == operable)
{
^ "default implementation"
}
else
{
^ operable.operate()
}
}
}
public program()
{
var delegator := new Delegator();
new object[]{nil, new Object(), new Operable()}.forEach::(o)
{
delegator.Delegate := o;
console.printLine(delegator.operate())
}
}</syntaxhighlight>
{{out}}
<pre>
default implementation
default implementation
delegate implementation
</pre>
 
=={{header|FreeBASIC}}==
{{trans|Phix}}
FreeBASIC does not directly support objects or delegation functions. However, you can achieve similar functionality using user-defined types and function pointers.
<syntaxhighlight lang="vbnet">
Type Objeto
operation As Function() As String
other As String
End Type
 
Function xthing() As String
Return "default implementation"
End Function
 
Function newX() As Objeto
Dim As Objeto o
o.operation = @xthing
Return o
End Function
 
Function newY() As Objeto
Dim As Objeto o = newX()
o.other = "something else"
o.operation = 0 ' remove delegate
Return o
End Function
 
Function zthing() As String
Return "delegate implementation"
End Function
 
Function newZ() As Objeto
Dim As Objeto o = newX()
o.operation = @zthing ' replace delegate
Return o
End Function
 
Function operation(o As Objeto) As String
Return Iif(o.operation <> 0, o.operation(), "no implementation")
End Function
 
Dim As Objeto x = newX()
Dim As Objeto y = newY()
Dim As Objeto z = newZ()
 
Print operation(x)
Print operation(y)
Print operation(z)
 
Sleep</syntaxhighlight>
{{out}}
<pre>Similar as Phix entry.</pre>
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">type Delegator() =
let defaultOperation() = "default implementation"
let mutable del = null
Line 664 ⟶ 979:
 
d.Delegate <- new Delegate()
assert (d.operation() = "delegate implementation")</langsyntaxhighlight>
 
=={{header|Forth}}==
{{works with|Forth}}
Works with any ANS Forth
 
Needs the FMS-SI (single inheritance) library code located here:
http://soton.mpeforth.com/flag/fms/index.html
<syntaxhighlight lang="forth">include FMS-SI.f
 
:class delegate
:m thing ." delegate implementation" ;m
;class
 
delegate slave
 
:class delegator
ivar del \ object container
:m !: ( n -- ) del ! ;m
:m init: 0 del ! ;m
:m default ." default implementation" ;m
:m operation
del @ 0= if self default exit then
del @ has-meth thing
if del @ thing
else self default
then ;m
;class
 
delegator master
\ First, without a delegate
master operation \ => default implementation
 
\ then with a delegate that does not implement "thing"
object o
o master !:
master operation \ => default implementation
 
\ and last with a delegate that implements "thing"
slave master !:
master operation \ => delegate implementation
</syntaxhighlight>
 
=={{header|Go}}==
 
<langsyntaxhighlight lang="go">package main
import "fmt"
 
Line 706 ⟶ 1,063:
a.delegate = d
fmt.Println(a.operation()) // prints "delegate implementation"
}</langsyntaxhighlight>
 
=={{header|Io}}==
{{trans|Python}}
<syntaxhighlight lang="io">Delegator := Object clone do(
delegate ::= nil
operation := method(
if((delegate != nil) and (delegate hasSlot("thing")),
delegate thing,
"default implementation"
)
)
)
 
Delegate := Object clone do(
thing := method("delegate implementation")
)
 
a := clone Delegator
a operation println
 
a setDelegate("A delegate may be any object")
a operation println
 
a setDelegate(Delegate clone)
a operation println</syntaxhighlight>
{{out}}
<pre>default implementation
default implementation
delegate implementation
</pre>
 
=={{header|J}}==
Life becomes slightly cleaner if we delegate to ourselves in the absence of some other delegate.
 
<langsyntaxhighlight Jlang="j">coclass 'delegator'
operation=:3 :'thing__delegate ::thing y'
thing=: 'default implementation'"_
Line 723 ⟶ 1,110:
 
NB. set context in case this script was used interactively, instead of being loaded
cocurrent 'base'</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight Jlang="j"> obj=:conew'delegator'
operation__obj''
default implementation
Line 741 ⟶ 1,128:
└─┘
operation__obj''
delegate implementation</langsyntaxhighlight>
 
=={{header|Java}}==
This implementation uses an interface called Thingable to specify the type of delegates that respond to thing(). The downside is that any delegate you want to use has to explicitly declare to implement the interface. The upside is that the type system guarantees that when the delegate is non-null, it must implement the "thing" method.
 
<langsyntaxhighlight lang="java">interface Thingable {
String thing();
}
Line 788 ⟶ 1,175:
assert a.operation().equals("anonymous delegate implementation");
}
}</langsyntaxhighlight>
 
{{works with|Java|8+}}
<langsyntaxhighlight lang="java">package delegate;
 
@FunctionalInterface
public interface Thingable {
public String thing();
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="java">package delegate;
 
import java.util.Optional;
Line 816 ⟶ 1,203:
;
}
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="java">package delegate;
 
@FunctionalInterface
Line 834 ⟶ 1,221:
return () -> thingable;
}
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="java">package delegate;
 
public final class Delegate implements Thingable {
Line 843 ⟶ 1,230:
return "delegate implementation";
}
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="java">package delegate;
 
// Example usage
Line 880 ⟶ 1,267:
assert d5.operation().equals("lambda expression implementation");
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
{{trans|Python}}
<langsyntaxhighlight lang="javascript">function Delegator() {
this.delegate = null ;
this.operation = function(){
Line 908 ⟶ 1,295:
a.delegate = new Delegate() ;
document.write(a.operation() + "\n") ;
}</langsyntaxhighlight>
 
=={{header|Julia}}==
'''Module''':
<syntaxhighlight lang="julia">module Delegates
 
export Delegator, Delegate
 
struct Delegator{T}
delegate::T
end
 
struct Delegate end
 
operation(x::Delegator) = thing(x.delegate)
thing(::Any) = "default implementation"
thing(::Delegate) = "delegate implementation"
 
end # module Delegates</syntaxhighlight>
 
'''Main''':
<syntaxhighlight lang="julia">using .Delegates
 
a = Delegator(nothing)
b = Delegator("string")
 
d = Delegate()
c = Delegator(d)
 
@show Delegates.operation(a)
@show Delegates.operation(b)
@show Delegates.operation(c)</syntaxhighlight>
 
{{out}}
<pre>Delegates.operation(a) = "default implementation"
Delegates.operation(b) = "default implementation"
Delegates.operation(c) = "delegate implementation"</pre>
 
=={{header|Kotlin}}==
Whilst Kotlin supports class delegation 'out of the box', the delegate and delegator both have to implement a particular interface and the delegate cannot be optional or null.
 
The first two scenarios are not therefore strictly possible though the second can be simulated by passing a 'responds' parameter to the delegate class constructor.
<syntaxhighlight lang="scala">// version 1.1.51
 
interface Thingable {
fun thing(): String?
}
 
class Delegate(val responds: Boolean) : Thingable {
override fun thing() = if (responds) "delegate implementation" else null
}
 
class Delegator(d: Delegate) : Thingable by d {
fun operation() = thing() ?: "default implementation"
}
 
fun main(args: Array<String>) {
// delegate doesn't respond to 'thing'
val d = Delegate(false)
val dd = Delegator(d)
println(dd.operation())
 
// delegate responds to 'thing'
val d2 = Delegate(true)
val dd2 = Delegator(d2)
println(dd2.operation())
}</syntaxhighlight>
 
{{out}}
<pre>
default implementation
delegate implementation
</pre>
 
=={{header|Latitude}}==
 
{{trans|Python}}
<syntaxhighlight lang="latitude">Delegator ::= Object clone tap {
self delegate := Nil.
self clone := {
Parents above (parent self, 'clone) call tap {
self delegate := #'(self delegate).
}.
}.
self operation := {
localize.
if { this delegate slot? 'thing. } then {
this delegate thing.
} else {
"default implementation".
}.
}.
}.
 
Delegate ::= Object clone tap {
self thing := "delegate implementation".
}.
 
;; No delegate
foo := Delegator clone.
println: foo operation. ;; "default implementation"
 
;; Delegate which lacks `thing`
foo delegate := Object.
println: foo operation. ;; "default implementation"
 
;; Delegate which implements `thing`
foo delegate := Delegate.
println: foo operation. ;; "delegate implementation"</syntaxhighlight>
 
=={{header|Logtalk}}==
We use prototypes instead of classes for simplicity.
<langsyntaxhighlight lang="logtalk">% define a category for holding the interface
% and implementation for delegator objects
 
Line 987 ⟶ 1,482:
a_delegator::operation(String3),
String3 == 'delegate implementation'
)).</langsyntaxhighlight>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">local function Delegator()
return {
operation = function(self)
if (type(self.delegate)=="table") and (type(self.delegate.thing)=="function") then
return self.delegate:thing()
else
return "default implementation"
end
end
}
end
 
local function Delegate()
return {
thing = function(self)
return "delegate implementation"
end
}
end
 
local function NonDelegate(which)
if (which == 1) then return true -- boolean
elseif (which == 2) then return 12345 -- number
elseif (which == 3) then return "Hello" -- string
elseif (which == 4) then return function() end -- function
elseif (which == 5) then return { nothing = function() end } -- table (without "thing")
elseif (which == 6) then return coroutine.create(function() end) -- thread
elseif (which == 7) then return io.open("delegates.lua","r") -- userdata (if exists, or nil)
end
end
 
-- WITH NO (NIL) DELEGATE
local d = Delegator()
assert(d:operation() == "default implementation")
 
-- WITH A NON-DELEGATE
for i = 1, 7 do
d.delegate = NonDelegate(i)
assert(d:operation() == "default implementation")
end
 
-- WITH A PROPER DELEGATE
d.delegate = Delegate()
assert(d:operation() == "delegate implementation")
 
print("pass")</syntaxhighlight>
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module Checkit {
\\ there are some kinds of objects in M2000, one of them is the Group, the user object
\\ the delegate is a pointer to group
\\ 1. We pass parameters to function operations$(), $ means that this function return string value
\\ 2. We see how this can be done with pointers to group
global doc$ \\ first define a global (for this module) to log output
document doc$="Output:"+{
}
class Delegator {
private:
group delegate
group null
public:
function operation$ {
if not .delegate is .null then
try ok {
ret$="Delegate implementation:"+.delegate=>operation$(![])
\\ [] is the stack of values (leave empty stack), ! used to place this to callee stack
}
if not ok or error then ret$="No implementation"
else
ret$= "Default implementation"
end if
\\ a global variable and all group members except arrays use <= not =. Simple = used for declaring local variables
doc$<=ret$+{
}
=ret$
}
class:
Module Delegator {
class none {}
.null->none()
If match("G") then .delegate->(group) else .delegate<=.null
}
}
Class Thing {
function operation$(a,b) {
=str$(a*b)
}
}
Module CallbyReference (&z as group) {
Print Z.operation$(5,30)
}
Module CallbyValue (z as group) {
Print Z.operation$(2,30)
}
Module CallbyReference2 (&z as pointer) {
Print Z=>operation$(5,30)
}
Module CallbyValue2 (z as pointer) {
Print Z=>operation$(2,30)
}
\\ Normal Group ' no logging to doc$
N=Thing()
Print N.operation$(10,20)
CallbyReference &N
CallbyValue N
N1->N ' N1 is a pointer to a named group
Print N1=>operation$(10,20)
CallbyReference2 &N1
CallbyValue2 N1
N1->(N) ' N1 now is a pointer to a float group (a copy of N)
Print N1=>operation$(10,20)
CallbyReference2 &N1
CallbyValue2 N1
\\ using named groups (A is a group, erased when this module exit)
A=Delegator()
B=Delegator(Thing())
Print A.operation$(10,20)
Print B.operation$(10,20)
A=B
CallbyReference &A
CallbyValue A
\\ M2000 has two kinds of pointers to groups
\\ one is a pointer to a no named group (a float group)
\\ a float group leave until no pointer refer to it
\\ using pointers to groups (A1 is a pointer to Group)
A1->Delegator()
B1->Delegator(Thing())
Print A1=>operation$(10,20)
Print B1=>operation$(10,20)
A1=B1
CallbyReference2 &A1
CallbyValue2 A1
\\ Second type is a pointer to a named group
\\ the pointer hold a weak reference to named group
\\ so a returned pointer of thid kind can be invalid if actual reference not exist
A=Delegator() ' copy a float group to A
A1->A
B1->B
Print A1=>operation$(10,20)
Print B1=>operation$(10,20)
A1=B1
CallbyReference2 &A1
CallbyValue2 A1
Group Something {
}
B=Delegator(Something)
Print B.operation$(10,20)
CallbyReference &B
CallbyValue B
Report Doc$
Clipboard Doc$
}
Checkit
 
</syntaxhighlight>
{{out}}
<pre>
200
150
60
200
150
60
200
150
60
Output:
Default implementation
Delegate implementation: 200
Delegate implementation: 150
Delegate implementation: 60
Default implementation
Delegate implementation: 200
Delegate implementation: 150
Delegate implementation: 60
Default implementation
Delegate implementation: 200
Delegate implementation: 150
Delegate implementation: 60
No implementation
No implementation
No implementation
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">delegator[del_]@operate :=
If[StringQ[del@operate], del@operate, "default implementation"];
del1 = Null;
del2@banana = "phone";
del3@operate = "delegate implementation";
Print[delegator[#]@operate] & /@ {del1, del2, del3};</syntaxhighlight>
{{out}}
<pre>default implementation
default implementation
delegate implementation</pre>
 
=={{header|NGS}}==
<syntaxhighlight lang="ngs">{
type Delegator
 
F init(d:Delegator) d.delegate = null
 
F default_impl(d:Delegator) 'default implementation'
 
F operation(d:Delegator) default_impl(d)
 
F operation(d:Delegator) {
guard defined thing
guard thing is Fun
try {
d.delegate.thing()
}
catch(e:ImplNotFound) {
# Might be unrelated exception, so check and optionally rethrow
e.callable !== thing throws e
default_impl(d)
}
}
 
F operation(d:Delegator) {
guard d.delegate is Null
default_impl(d)
}
 
 
a = Delegator()
echo(a.operation())
 
# There is no method thing(s:Str)
a.delegate = "abc"
echo(a.operation())
 
# ... now there is method thing(s:Str)
F thing(s:Str) 'delegate implementation'
echo(a.operation())
}</syntaxhighlight>
{{out}}
<pre>default implementation
default implementation
delegate implementation</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">####################################################################################################
# Base delegate.
 
type Delegate = ref object of RootObj
nil
 
method thing(d: Delegate): string {.base.} =
## Default implementation of "thing".
## Using a method rather than a proc allows dynamic dispatch.
"default implementation"
 
 
####################################################################################################
# Delegator.
 
type Delegator = object
delegate: Delegate
 
proc initDelegator(d: Delegate = nil): Delegator =
## Create a delegator with given delegate or nil.
if d.isNil:
Delegator(delegate: Delegate()) # Will use a default delegate instance.
else:
Delegator(delegate: d) # Use the provided delegate instance.
 
proc operation(d: Delegator): string =
## Calls the delegate.
d.delegate.thing()
 
 
####################################################################################################
# Usage.
 
let d = initDelegator()
echo "Without any delegate: ", d.operation()
 
type Delegate1 = ref object of Delegate
 
let d1 = initDelegator(Delegate1())
echo "With a delegate which desn’t provide the “thing” method: ", d1.operation()
 
type Delegate2 = ref object of Delegate
 
method thing(d: Delegate2): string =
"delegate implementation"
 
let d2 = initDelegator(Delegate2())
echo "With a delegate which provided the “thing” method: ", d2.operation()</syntaxhighlight>
 
{{out}}
<pre>Without any delegate: default implementation
With a delegate which desn’t provide the “thing” method: default implementation
With a delegate which provided the “thing” method: delegate implementation</pre>
 
=={{header|Objeck}}==
{{trans|Java}}
<syntaxhighlight lang="objeck">interface Thingable {
method : virtual : public : Thing() ~ String;
}
class Delegator {
@delegate : Thingable;
 
New() {
}
 
method : public : SetDelegate(delegate : Thingable) ~ Nil {
@delegate := delegate;
}
 
method : public : Operation() ~ String {
if(@delegate = Nil) {
return "default implementation";
}
else {
return @delegate->Thing();
};
}
}
 
class Delegate implements Thingable {
New() {
}
 
method : public : Thing() ~ String {
return "delegate implementation";
}
}
 
class Example {
function : Main(args : String[]) ~ Nil {
# Without a delegate:
a := Delegator->New();
Runtime->Assert(a->Operation()->Equals("default implementation"));
# With a delegate:
d := Delegate->New();
a->SetDelegate(d);
Runtime->Assert(a->Operation()->Equals("delegate implementation"));
 
# Same as the above, but with an anonymous class:
a->SetDelegate(Base->New() implements Thingable {
method : public : Thing() ~ String {
return "anonymous delegate implementation";
}
});
 
Runtime->Assert(a->Operation()->Equals("anonymous delegate implementation"));
}
}
</syntaxhighlight>
 
=={{header|Objective-C}}==
Line 993 ⟶ 1,846:
{{works with|Cocoa}}
{{works with|GNUstep}}
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
@interface Delegator : NSObject {
Line 1,068 ⟶ 1,921:
 
return 0;
}</langsyntaxhighlight>
 
Objective-C 2.0, modern runtime, Automatic Reference Counting, Autosynthesize (LLVM 4.0+)
{{works with|Cocoa}}
 
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
// Formal protocol for the delegate
Line 1,117 ⟶ 1,970:
}
return 0;
}</langsyntaxhighlight>
 
 
=={{header|Oforth}}==
<langsyntaxhighlight Oforthlang="oforth">Object Class new: Delegate1
 
Object Class new: Delegate2
Delegate2 method: thing { "Delegate implementation" println };
 
Object Class new: Delegator(delegate)
Delegator method: initialize { := delegate };
 
Delegator method: thingoperation
{
@delegate respondTo(#thing) ifTrue: [ @delegate thing return ]
"Default implementation" println ;</syntaxhighlight>
}</lang>
Usage :
 
<langsyntaxhighlight Oforthlang="oforth">Delegator new(null) thingoperation
Default implementation
 
Delegator new(Delegate1 new) thingoperation
Default implementation
 
Delegator new(Delegate2 new) thingoperation
Delegate implementation</langsyntaxhighlight>
 
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
<lang ooRexx>
delegator = .delegator~new -- no delegate
say delegator~operation
Line 1,187 ⟶ 2,037:
nomethod:
return "default implementation"
</syntaxhighlight>
</lang>
 
=={{header|OxygenBasic}}==
<langsyntaxhighlight lang="oxygenbasic">
class DelegateA 'not implmenting thing()
'==============
Line 1,235 ⟶ 2,085:
print dgr.thing 'result "not using Delegate"
print dg.thing 'result "Delegate Implementation"
</syntaxhighlight>
</lang>
 
=={{header|Oz}}==
{{trans|Python}}
<langsyntaxhighlight lang="oz">declare
class Delegator from BaseObject
attr
Line 1,281 ⟶ 2,131:
 
{A set({New Delegate noop})}
{System.showInfo {A operation($)}}</langsyntaxhighlight>
 
=={{header|Pascal}}==
Line 1,288 ⟶ 2,138:
=={{header|Perl}}==
{{trans|Python}}
<langsyntaxhighlight lang="perl">use strict;
 
package Delegator;
Line 1,326 ⟶ 2,176:
$a->{delegate} = Delegate->new;
$a->operation eq 'delegate implementation' or die;
</syntaxhighlight>
</lang>
 
Using Moose.
 
<langsyntaxhighlight lang="perl">
use 5.010_000;
 
Line 1,386 ⟶ 2,236:
$delegator->operation eq 'delegate implementation' or die;
 
</syntaxhighlight>
</lang>
 
=={{header|Perl 6Phix}}==
Phix is not object orientated, instead I would just use a routine_id for this sort of thing.<br>
<lang perl6>class Non-Delegate { }
I will admit that the whole concept of "no delegate/with one that does not implement" makes no sense whatsoever to me.<br>
While I've shown this using a single rid, you could of course hold an entire sequence of them or even better a dictionary and use named lookups for rids in that.
<syntaxhighlight lang="phix">enum OTHER, OPERATION
 
function operation(object o)
class Delegate {
integer rid = o[OPERATION]
method thing {
if rid!=NULL then
return "delegate implementation"
return call_func(rid,{})
}
end if
}
return "no implementation"
end function
 
function xthing()
class Delegator {
return "default implementation"
has $.delegate is rw;
end function
 
function newX()
method operation {
return {1,routine_id("xthing"),2}
$.delegate.^can( 'thing' ) ?? $.delegate.thing
end function
!! "default implementation"
}
}
 
function newY()
my Delegator $d .= new;
object res = newX()
res[OTHER] = "something else"
-- remove delegate:
res[OPERATION] = NULL
return res
end function
 
function zthing()
say "empty: "~$d.operation;
return "delegate implementation"
end function
 
function newZ()
$d.delegate = Non-Delegate.new;
object res = newX()
-- replace delegate:
res[OPERATION] = routine_id("zthing")
return res
end function
 
object x = newX(),
say "Non-Delegate: "~$d.operation;
y = newY(),
z = newZ()
 
?operation(x)
$d.delegate = Delegate.new;
?operation(y)
?operation(z)</syntaxhighlight>
 
{{out}}
say "Delegate: "~$d.operation;</lang>
<pre>
"default implementation"
"no implementation"
"delegate implementation"
</pre>
Obviously, you can explictly test for rid=NULL as shown, or remove that test and catch exceptions, ie:
<syntaxhighlight lang="phix">?operation(x)
try -- (since rid=NULL check commented out)
?operation(y)
catch e
?"oops, no implementation"
end try
?operation(z)</syntaxhighlight>
 
=={{header|PHP}}==
{{trans|Python}}
<langsyntaxhighlight lang="php">class Delegator {
function __construct() {
$this->delegate = NULL ;
Line 1,444 ⟶ 2,328:
 
$a->delegate = new Delegate() ;
print "{$a->operation()}\n" ;</langsyntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(class +Delegator)
# delegate
 
Line 1,476 ⟶ 2,360:
# With delegate that implements 'thing>'
(put A 'delegate (new '(+Delegate) "delegate implementation"))
(println (operation> A)) )</langsyntaxhighlight>
Output:
<pre>"default implementation"
Line 1,483 ⟶ 2,367:
 
=={{header|Pop11}}==
<langsyntaxhighlight lang="pop11">uses objectclass;
define :class Delegator;
slot delegate = false;
Line 1,514 ⟶ 2,398:
;;; delegating to a freshly created Delegate
newDelegate() -> delegate(a);
operation(a) =></langsyntaxhighlight>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">class Delegator:
def __init__(self):
self.delegate = None
Line 1,541 ⟶ 2,425:
# With delegate that implements "thing"
a.delegate = Delegate()
assert a.operation() == 'delegate implementation'</langsyntaxhighlight>
 
=={{header|Racket}}==
Line 1,553 ⟶ 2,437:
follows the requirement of the task better.
 
<langsyntaxhighlight lang="racket">#lang racket
;; Delegates. Tim Brown 2014-10-16
 
Line 1,587 ⟶ 2,471:
(send delegator-2 operation) => "delegate implementation"
(send (new delegator% [delegate thinging-delegate]) operation) => "delegate implementation"))
</syntaxhighlight>
</lang>
 
All the tests pass. Believe me.
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>class Non-Delegate { }
 
class Delegate {
method thing {
return "delegate implementation"
}
}
 
class Delegator {
has $.delegate is rw;
 
method operation {
$.delegate.^can( 'thing' ) ?? $.delegate.thing
!! "default implementation"
}
}
 
my Delegator $d .= new;
 
say "empty: "~$d.operation;
 
$d.delegate = Non-Delegate.new;
 
say "Non-Delegate: "~$d.operation;
 
$d.delegate = Delegate.new;
 
say "Delegate: "~$d.operation;</syntaxhighlight>
 
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight lang="ruby">class Delegator
attr_accessor :delegate
def operation
Line 1,623 ⟶ 2,538:
a.delegate = Delegate.new
puts a.operation # prints "delegate implementation"
end</langsyntaxhighlight>
 
Using Forwardable lib
 
<langsyntaxhighlight lang="ruby">require 'forwardable'
 
class Delegator; extend Forwardable
Line 1,646 ⟶ 2,561:
a = Delegator.new
puts a.delegated # prints "Delegate"
</syntaxhighlight>
</lang>
 
=={{header|Rust}}==
Requiring delegates to implement Thingable:
<syntaxhighlight lang="rust">trait Thingable {
fn thing(&self) -> &str;
}
 
struct Delegator<T>(Option<T>);
 
struct Delegate {}
 
impl Thingable for Delegate {
fn thing(&self) -> &'static str {
"Delegate implementation"
}
}
 
impl<T: Thingable> Thingable for Delegator<T> {
fn thing(&self) -> &str {
self.0.as_ref().map(|d| d.thing()).unwrap_or("Default implmementation")
}
}
 
fn main() {
let d: Delegator<Delegate> = Delegator(None);
println!("{}", d.thing());
let d: Delegator<Delegate> = Delegator(Some(Delegate {}));
println!("{}", d.thing());
}</syntaxhighlight>
{{Out}}
<pre>Default implmementation
Delegate implementation</pre>
 
Using nightly-only specialization feature:
<syntaxhighlight lang="rust">#![feature(specialization)]
 
trait Thingable {
fn thing(&self) -> &str;
}
 
struct Delegator<T>(Option<T>);
 
struct Delegate {}
 
impl Thingable for Delegate {
fn thing(&self) -> &'static str {
"Delegate implementation"
}
}
 
impl<T> Thingable for Delegator<T> {
default fn thing(&self) -> &str {
"Default implementation"
}
}
 
impl<T: Thingable> Thingable for Delegator<T> {
fn thing(&self) -> &str {
self.0.as_ref().map(|d| d.thing()).unwrap_or("Default implmementation")
}
}
 
fn main() {
let d: Delegator<i32> = Delegator(None);
println!("{}", d.thing());
let d: Delegator<i32> = Delegator(Some(42));
println!("{}", d.thing());
let d: Delegator<Delegate> = Delegator(None);
println!("{}", d.thing());
let d: Delegator<Delegate> = Delegator(Some(Delegate {}));
println!("{}", d.thing());
}</syntaxhighlight>
{{Out}}
<pre>Default implementation
Default implementation
Default implmementation
Delegate implementation</pre>
 
=={{header|Scala}}==
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/cCYD9tQ/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/2TWYJifpTuOVhrAfWP51oA Scastie (remote JVM)].
<syntaxhighlight lang="scala">trait Thingable {
def thing: String
}
 
class Delegator {
var delegate: Thingable = _
 
def operation: String = if (delegate == null) "default implementation"
else delegate.thing
}
 
class Delegate extends Thingable {
override def thing = "delegate implementation"
}
 
// Example usage
// Memory management ignored for simplification
object DelegateExample extends App {
 
val a = new Delegator
assert(a.operation == "default implementation")
// With a delegate:
val d = new Delegate
a.delegate = d
assert(a.operation == "delegate implementation")
// Same as the above, but with an anonymous class:
a.delegate = new Thingable() {
override def thing = "anonymous delegate implementation"
}
assert(a.operation == "anonymous delegate implementation")
 
}</syntaxhighlight>
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">class NonDelegate { }
 
class Delegate {
method thing {
return "delegate implementation"
}
}
 
class Delegator (delegate = null) {
method operation {
 
if (delegate.respond_to(:thing)) {
return delegate.thing
}
 
return "default implementation"
}
}
 
var d = Delegator()
say "empty: #{d.operation}"
d.delegate = NonDelegate()
say "NonDelegate: #{d.operation}"
d.delegate = Delegate()
say "Delegate: #{d.operation}"</syntaxhighlight>
{{out}}
empty: default implementation
NonDelegate: default implementation
Delegate: delegate implementation
 
=={{header|Smalltalk}}==
{{works with|Smalltalk/X}}
Definition of the thingy:
<syntaxhighlight lang="smalltalk">Object
subclass:#Thingy
instanceVariableNames:''
 
thing
^ 'thingy implementation'</syntaxhighlight>
Definition of the delegator:
<syntaxhighlight lang="smalltalk">Object
subclass:#Delegator
instanceVariableNames:'delegate'
 
delegate:something
delegate := something
 
operation
^ delegate
perform:#thing ifNotUnderstood:'default implementation'.</syntaxhighlight>
Sample use:
<syntaxhighlight lang="smalltalk">|d|
d := Delegator new.
d operation.
-> 'default implementation'
 
d delegate:(Thingy new).
d operation.
-> 'thingy implementation'</syntaxhighlight>
 
=={{header|Swift}}==
Allowing the delegate to be any type and taking advantage of dynamism of method lookup:
<langsyntaxhighlight lang="swift">import Foundation
 
@objc protocol Thingable { // prior to Swift 1.2, needs to be declared @objc
func thing() -> String
}
Line 1,682 ⟶ 2,774:
let d = Delegate()
a.delegate = d
println(a.operation()) // prints "delegate implementation"</langsyntaxhighlight>
 
 
Alternately, requiring the delegate to conform to a given protocol:
<langsyntaxhighlight lang="swift">protocol Thingable : class {
func thing() -> String
}
Line 1,712 ⟶ 2,804:
let d = Delegate()
a.delegate = d
println(a.operation()) // prints "delegate implementation"</langsyntaxhighlight>
 
=={{header|Tcl}}==
{{works with|Tcl|8.6}} or {{libheader|TclOO}}
Uses [[Assertions#Tcl]]
<langsyntaxhighlight lang="tcl">package require TclOO
 
oo::class create Delegate {
Line 1,769 ⟶ 2,861:
assert {[a operation] ne "default implementation"}
 
puts "all assertions passed"</langsyntaxhighlight>
 
To code the <code>operation</code> method without relying on catching an exception, but strictly by using introspection:
<langsyntaxhighlight lang="tcl">method operation {} {
if { [info exists delegate] &&
[info object isa object $delegate] &&
Line 1,781 ⟶ 2,873:
set result "default implementation"
}
}</langsyntaxhighlight>
 
=={{header|TXR}}==
 
<syntaxhighlight lang="txrlisp">;; TXR Lisp's :delegate implementation is hard delegation: the indicated
;; delegate object must exist and take the method call. To do soft
;; delegation, we develop a macro (delegate-or-fallback x y z)
;; which chooses x if x is an object which supports a z method,
;; or else chooses y.
 
(defun delegate-or-fallback-impl (del-inst fb-inst required-meth)
(let (del-type)
(if (and (structp del-inst)
(set del-type (struct-type del-inst))
(static-slot-p del-type required-meth)
(functionp (static-slot del-type required-meth)))
del-inst
fb-inst)))
 
(defmacro delegate-or-fallback (delegate-expr fallback-obj : required-meth)
^(delegate-or-fallback-impl ,delegate-expr ,fallback-obj ',required-meth))
 
;; With the above, we can use the defstruct delegate clause syntax:
;;
;; (:delegate source-method (obj) target-obj target-method)
;;
;; which writes a delegate method called source-method, that delegates
;; to target-method on target-obj. We calculate target-obj using
;; our macro and ensure that the delegator itself imlpements target-method.
 
(defstruct delegator ()
delegate
(:delegate operation (me) (delegate-or-fallback me.delegate me thing) thing)
 
(:method thing (me)
"default implementation"))
 
(defstruct delegate ()
(:method thing (me)
"delegate implementation"))
 
;; Tests:
 
;; no delegate
(prinl (new delegator).(operation))
 
;; struct delegate, but not with thing method
(prinl (new delegator delegate (new time)).(operation))
 
;; delegate with thing method
(prinl (new delegator delegate (new delegate)).(operation))</syntaxhighlight>
 
{{out}}
 
<pre>"default implementation"
"default implementation"
"delegate implementation"</pre>
 
=={{header|Vorpal}}==
Delegate objects can be an array of delegates or as a single delegate.
<langsyntaxhighlight lang="vorpal">a = new()
a.f = method(){
.x.print()
Line 1,808 ⟶ 2,956:
d.delegate = a
d.x = 7
d.f()</langsyntaxhighlight>
 
The resulting output:
Line 1,815 ⟶ 2,963:
4
7
</pre>
 
=={{header|Wren}}==
Wren is dynamically typed so we can plug any kind of delegate into the Delegator.
<syntaxhighlight lang="wren">class Thingable {
thing { }
}
 
// Delegate that doesn't implement Thingable
class Delegate {
construct new() { }
}
 
// Delegate that implements Thingable
class Delegate2 is Thingable {
construct new() { }
 
thing { "delegate implementation" }
}
 
class Delegator {
construct new() {
_delegate = null
}
 
delegate { _delegate }
delegate=(d) { _delegate = d }
 
operation {
if (!_delegate || !(_delegate is Thingable)) return "default implementation"
return _delegate.thing
}
}
 
// without a delegate
var d = Delegator.new()
System.print(d.operation)
 
// with a delegate that doesn't implement Thingable
d.delegate = Delegate.new()
System.print(d.operation)
 
// with a delegate that does implement Thingable
d.delegate = Delegate2.new()
System.print(d.operation)</syntaxhighlight>
 
{{out}}
<pre>
default implementation
default implementation
delegate implementation
</pre>
 
=={{header|zkl}}==
{{trans|Scala}}
<langsyntaxhighlight lang="zkl">class Thingable{ var thing; }
class Delegator{
Line 1,829 ⟶ 3,028:
}
class Delegate(Thingable){ thing = "delegate implementation" }</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl"> // Without a delegate:
a:= Delegator();
a.operation().println(); //--> "default implementation"
Line 1,837 ⟶ 3,036:
// With a delegate:
a.delegate = Delegate();
a.operation().println(); //-->"delegate implementation"</langsyntaxhighlight>
A second example
<langsyntaxhighlight lang="zkl">class [static] Logger{ // Only one logging resource
var [mixin=File] dst; // File like semantics, eg Data, Pipe
dst = File.DevNull;
// initially, the logger does nothing
fcn log(msg){dst.writeln(vm.pasteArgs())}
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="zkl">Logger.log("this is a test"); //-->nada
Logger.dst=Console;
Logger.log("this is a test 2"); //-->writes to Console
 
class B(Logger){ log("Hello from ",self,"'s constructor"); }
B(); //-->Hello from Class(B)'s constructor</langsyntaxhighlight>
 
The base class B was constructed at startup,
Line 1,858 ⟶ 3,057:
 
 
{{<!-- Omit From|ALGOL 68}} <!--although it isn't immediately obvious that ALGOL 68 is object oriented, if C can do it... -->
{{omit From|Fortran}}
{{omit From|Maxima}}
2,169

edits