Delegates: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (→{{header|C sharp}}: Regularize header markup to recommended on category page) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 16: | Line 16: | ||
=={{header|Ada}}== |
=={{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. |
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. |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO; |
||
procedure Delegation is |
procedure Delegation is |
||
Line 63: | Line 63: | ||
A.Delegate := Has_Thing'Access; -- Set a thing |
A.Delegate := Has_Thing'Access; -- Set a thing |
||
Put_Line (A.Operation); |
Put_Line (A.Operation); |
||
end Delegation;</ |
end Delegation;</syntaxhighlight> |
||
Sample output: |
Sample output: |
||
<pre> |
<pre> |
||
Line 72: | Line 72: | ||
=={{header|Aikido}}== |
=={{header|Aikido}}== |
||
< |
<syntaxhighlight lang="aikido"> |
||
class Delegator { |
class Delegator { |
||
public generic delegate = none |
public generic delegate = none |
||
Line 97: | Line 97: | ||
println (d1.operation()) |
println (d1.operation()) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Aime}}== |
=={{header|Aime}}== |
||
< |
<syntaxhighlight lang="aime">text |
||
thing(void) |
thing(void) |
||
{ |
{ |
||
Line 141: | Line 141: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
As Algol 68 doesn't have classes, we supply a non-OO approximation, similar to the C version. |
As Algol 68 doesn't have classes, we supply a non-OO approximation, similar to the C version. |
||
< |
<syntaxhighlight lang="algol68"># An Algol 68 approximation of delegates # |
||
# The delegate mode - the delegate is a STRUCT with a single field # |
# The delegate mode - the delegate is a STRUCT with a single field # |
||
Line 220: | Line 220: | ||
) |
) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}}<pre> |
{{out}}<pre> |
||
No delegate : default implementation |
No delegate : default implementation |
||
Line 234: | Line 234: | ||
What is your proposal to solve that in the code? |
What is your proposal to solve that in the code? |
||
<syntaxhighlight lang="ataribasic"> |
|||
<lang AtariBasic> |
|||
10 REM DELEGATION CODE AND EXAMPLE . ATARI BASIC 2020 A. KRESS andreas.kress@hood-group.com |
10 REM DELEGATION CODE AND EXAMPLE . ATARI BASIC 2020 A. KRESS andreas.kress@hood-group.com |
||
14 REM |
14 REM |
||
Line 261: | Line 261: | ||
130 DELEGATE=80:REM DELEGATE IS |
130 DELEGATE=80:REM DELEGATE IS |
||
140 GOSUB 20:REM INIT DELEGATOR |
140 GOSUB 20:REM INIT DELEGATOR |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}}<pre> |
{{out}}<pre> |
||
RUN |
RUN |
||
Line 272: | Line 272: | ||
=={{header|C}}== |
=={{header|C}}== |
||
As best you can do, without support for classes. |
As best you can do, without support for classes. |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <string.h> |
#include <string.h> |
||
Line 357: | Line 357: | ||
Delegator_Operation( theDelegator, 3, del2)); |
Delegator_Operation( theDelegator, 3, del2)); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
interface IOperable |
interface IOperable |
||
Line 398: | Line 398: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>Default implementation. |
<pre>Default implementation. |
||
Line 407: | Line 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. |
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 <tr1/memory> |
||
#include <string> |
#include <string> |
||
Line 487: | Line 487: | ||
*/ |
*/ |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
< |
<syntaxhighlight lang="clojure">(defprotocol Thing |
||
(thing [_])) |
(thing [_])) |
||
Line 502: | Line 502: | ||
(defrecord Delegate [] |
(defrecord Delegate [] |
||
Thing |
Thing |
||
(thing [_] "delegate implementation"))</ |
(thing [_] "delegate implementation"))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 521: | Line 521: | ||
=={{header|CoffeeScript}}== |
=={{header|CoffeeScript}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="coffeescript"> |
||
class Delegator |
class Delegator |
||
operation: -> |
operation: -> |
||
Line 546: | Line 546: | ||
testDelegator() |
testDelegator() |
||
</syntaxhighlight> |
|||
</lang> |
|||
output |
output |
||
<lang> |
<syntaxhighlight lang="text"> |
||
> coffee foo.coffee |
> coffee foo.coffee |
||
default implementation |
default implementation |
||
default implementation |
default implementation |
||
Delegate Implementation |
Delegate Implementation |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 560: | Line 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. |
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. |
||
< |
<syntaxhighlight lang="lisp">(defgeneric thing (object) |
||
(:documentation "Thing the object.")) |
(:documentation "Thing the object.")) |
||
Line 588: | Line 588: | ||
(assert (string= "no delegate" (thing d1))) |
(assert (string= "no delegate" (thing d1))) |
||
(assert (string= "default implementation" (thing d2))) |
(assert (string= "default implementation" (thing d2))) |
||
(assert (string= "delegate implementation" (thing d3))))</ |
(assert (string= "delegate implementation" (thing d3))))</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
Line 594: | Line 594: | ||
''Delegate'' object and pass a real delegate directly to '''Delegator'''. |
''Delegate'' object and pass a real delegate directly to '''Delegator'''. |
||
< |
<syntaxhighlight lang="d">class Delegator { |
||
string delegate() hasDelegate; |
string delegate() hasDelegate; |
||
Line 617: | Line 617: | ||
writeln(dr.operation()); |
writeln(dr.operation()); |
||
writeln(dr.setDg(thing).operation()); |
writeln(dr.setDg(thing).operation()); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Default implementation |
<pre>Default implementation |
||
Line 625: | Line 625: | ||
===Version using Tango=== |
===Version using Tango=== |
||
{{libheader|tango}} |
{{libheader|tango}} |
||
< |
<syntaxhighlight lang="d">import tango.io.Stdout; |
||
class Delegator |
class Delegator |
||
Line 653: | Line 653: | ||
Stdout ( dr.setDg(thing).operation ).newline; |
Stdout ( dr.setDg(thing).operation ).newline; |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Dart}}== |
=={{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 |
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 |
||
< |
<syntaxhighlight lang="dart">class Delegator { |
||
var delegate; |
var delegate; |
||
Line 685: | Line 685: | ||
a.delegate = d; |
a.delegate = d; |
||
Expect.equals("delegate implementation",a.operation()); |
Expect.equals("delegate implementation",a.operation()); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
Translation of the Java example found at [http://en.wikipedia.org/wiki/Delegation_pattern Wikipedia]. |
Translation of the Java example found at [http://en.wikipedia.org/wiki/Delegation_pattern Wikipedia]. |
||
< |
<syntaxhighlight lang="delphi">unit Printer; |
||
interface |
interface |
||
Line 738: | Line 738: | ||
end; |
end; |
||
end.</ |
end.</syntaxhighlight> |
||
< |
<syntaxhighlight lang="delphi">program Delegate; |
||
{$APPTYPE CONSOLE} |
{$APPTYPE CONSOLE} |
||
Line 757: | Line 757: | ||
PrinterObj.Free; |
PrinterObj.Free; |
||
end; |
end; |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|E}}== |
=={{header|E}}== |
||
< |
<syntaxhighlight lang="e">def makeDelegator { |
||
/** construct without an explicit delegate */ |
/** construct without an explicit delegate */ |
||
to run() { |
to run() { |
||
Line 794: | Line 794: | ||
> }) |
> }) |
||
> delegator.operation() |
> delegator.operation() |
||
# value: "default implementation"</ |
# value: "default implementation"</syntaxhighlight> |
||
=={{header|Elena}}== |
=={{header|Elena}}== |
||
Line 800: | Line 800: | ||
Using multi methods: |
Using multi methods: |
||
< |
<syntaxhighlight lang="elena">import extensions; |
||
import system'routines; |
import system'routines; |
||
Line 845: | Line 845: | ||
console.printLine(delegator.operate()) |
console.printLine(delegator.operate()) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Generic solution: |
Generic solution: |
||
< |
<syntaxhighlight lang="elena">import extensions; |
||
import system'routines; |
import system'routines; |
||
Line 893: | Line 893: | ||
console.printLine(delegator.operate()) |
console.printLine(delegator.operate()) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 902: | Line 902: | ||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
< |
<syntaxhighlight lang="fsharp">type Delegator() = |
||
let defaultOperation() = "default implementation" |
let defaultOperation() = "default implementation" |
||
let mutable del = null |
let mutable del = null |
||
Line 927: | Line 927: | ||
d.Delegate <- new Delegate() |
d.Delegate <- new Delegate() |
||
assert (d.operation() = "delegate implementation")</ |
assert (d.operation() = "delegate implementation")</syntaxhighlight> |
||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
Line 935: | Line 935: | ||
Needs the FMS-SI (single inheritance) library code located here: |
Needs the FMS-SI (single inheritance) library code located here: |
||
http://soton.mpeforth.com/flag/fms/index.html |
http://soton.mpeforth.com/flag/fms/index.html |
||
< |
<syntaxhighlight lang="forth">include FMS-SI.f |
||
:class delegate |
:class delegate |
||
Line 969: | Line 969: | ||
slave master !: |
slave master !: |
||
master operation \ => delegate implementation |
master operation \ => delegate implementation |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 1,011: | Line 1,011: | ||
a.delegate = d |
a.delegate = d |
||
fmt.Println(a.operation()) // prints "delegate implementation" |
fmt.Println(a.operation()) // prints "delegate implementation" |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Io}}== |
=={{header|Io}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="io">Delegator := Object clone do( |
||
delegate ::= nil |
delegate ::= nil |
||
operation := method( |
operation := method( |
||
Line 1,036: | Line 1,036: | ||
a setDelegate(Delegate clone) |
a setDelegate(Delegate clone) |
||
a operation println</ |
a operation println</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>default implementation |
<pre>default implementation |
||
Line 1,046: | Line 1,046: | ||
Life becomes slightly cleaner if we delegate to ourselves in the absence of some other delegate. |
Life becomes slightly cleaner if we delegate to ourselves in the absence of some other delegate. |
||
< |
<syntaxhighlight lang="j">coclass 'delegator' |
||
operation=:3 :'thing__delegate ::thing y' |
operation=:3 :'thing__delegate ::thing y' |
||
thing=: 'default implementation'"_ |
thing=: 'default implementation'"_ |
||
Line 1,058: | Line 1,058: | ||
NB. set context in case this script was used interactively, instead of being loaded |
NB. set context in case this script was used interactively, instead of being loaded |
||
cocurrent 'base'</ |
cocurrent 'base'</syntaxhighlight> |
||
Example use: |
Example use: |
||
< |
<syntaxhighlight lang="j"> obj=:conew'delegator' |
||
operation__obj'' |
operation__obj'' |
||
default implementation |
default implementation |
||
Line 1,076: | Line 1,076: | ||
└─┘ |
└─┘ |
||
operation__obj'' |
operation__obj'' |
||
delegate implementation</ |
delegate implementation</syntaxhighlight> |
||
=={{header|Java}}== |
=={{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. |
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. |
||
< |
<syntaxhighlight lang="java">interface Thingable { |
||
String thing(); |
String thing(); |
||
} |
} |
||
Line 1,123: | Line 1,123: | ||
assert a.operation().equals("anonymous delegate implementation"); |
assert a.operation().equals("anonymous delegate implementation"); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{works with|Java|8+}} |
{{works with|Java|8+}} |
||
< |
<syntaxhighlight lang="java">package delegate; |
||
@FunctionalInterface |
@FunctionalInterface |
||
public interface Thingable { |
public interface Thingable { |
||
public String thing(); |
public String thing(); |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="java">package delegate; |
||
import java.util.Optional; |
import java.util.Optional; |
||
Line 1,151: | Line 1,151: | ||
; |
; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="java">package delegate; |
||
@FunctionalInterface |
@FunctionalInterface |
||
Line 1,169: | Line 1,169: | ||
return () -> thingable; |
return () -> thingable; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="java">package delegate; |
||
public final class Delegate implements Thingable { |
public final class Delegate implements Thingable { |
||
Line 1,178: | Line 1,178: | ||
return "delegate implementation"; |
return "delegate implementation"; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="java">package delegate; |
||
// Example usage |
// Example usage |
||
Line 1,215: | Line 1,215: | ||
assert d5.operation().equals("lambda expression implementation"); |
assert d5.operation().equals("lambda expression implementation"); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="javascript">function Delegator() { |
||
this.delegate = null ; |
this.delegate = null ; |
||
this.operation = function(){ |
this.operation = function(){ |
||
Line 1,243: | Line 1,243: | ||
a.delegate = new Delegate() ; |
a.delegate = new Delegate() ; |
||
document.write(a.operation() + "\n") ; |
document.write(a.operation() + "\n") ; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
'''Module''': |
'''Module''': |
||
< |
<syntaxhighlight lang="julia">module Delegates |
||
export Delegator, Delegate |
export Delegator, Delegate |
||
Line 1,261: | Line 1,261: | ||
thing(::Delegate) = "delegate implementation" |
thing(::Delegate) = "delegate implementation" |
||
end # module Delegates</ |
end # module Delegates</syntaxhighlight> |
||
'''Main''': |
'''Main''': |
||
< |
<syntaxhighlight lang="julia">using .Delegates |
||
a = Delegator(nothing) |
a = Delegator(nothing) |
||
Line 1,274: | Line 1,274: | ||
@show Delegates.operation(a) |
@show Delegates.operation(a) |
||
@show Delegates.operation(b) |
@show Delegates.operation(b) |
||
@show Delegates.operation(c)</ |
@show Delegates.operation(c)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,285: | Line 1,285: | ||
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. |
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 { |
interface Thingable { |
||
Line 1,309: | Line 1,309: | ||
val dd2 = Delegator(d2) |
val dd2 = Delegator(d2) |
||
println(dd2.operation()) |
println(dd2.operation()) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,320: | Line 1,320: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="latitude">Delegator ::= Object clone tap { |
||
self delegate := Nil. |
self delegate := Nil. |
||
self clone := { |
self clone := { |
||
Line 1,351: | Line 1,351: | ||
;; Delegate which implements `thing` |
;; Delegate which implements `thing` |
||
foo delegate := Delegate. |
foo delegate := Delegate. |
||
println: foo operation. ;; "delegate implementation"</ |
println: foo operation. ;; "delegate implementation"</syntaxhighlight> |
||
=={{header|Logtalk}}== |
=={{header|Logtalk}}== |
||
We use prototypes instead of classes for simplicity. |
We use prototypes instead of classes for simplicity. |
||
< |
<syntaxhighlight lang="logtalk">% define a category for holding the interface |
||
% and implementation for delegator objects |
% and implementation for delegator objects |
||
Line 1,430: | Line 1,430: | ||
a_delegator::operation(String3), |
a_delegator::operation(String3), |
||
String3 == 'delegate implementation' |
String3 == 'delegate implementation' |
||
)).</ |
)).</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang="lua">local function Delegator() |
||
return { |
return { |
||
operation = function(self) |
operation = function(self) |
||
Line 1,478: | Line 1,478: | ||
assert(d:operation() == "delegate implementation") |
assert(d:operation() == "delegate implementation") |
||
print("pass")</ |
print("pass")</syntaxhighlight> |
||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module Checkit { |
Module Checkit { |
||
\\ there are some kinds of objects in M2000, one of them is the Group, the user object |
\\ there are some kinds of objects in M2000, one of them is the Group, the user object |
||
Line 1,589: | Line 1,589: | ||
Checkit |
Checkit |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,620: | Line 1,620: | ||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">delegator[del_]@operate := |
||
If[StringQ[del@operate], del@operate, "default implementation"]; |
If[StringQ[del@operate], del@operate, "default implementation"]; |
||
del1 = Null; |
del1 = Null; |
||
del2@banana = "phone"; |
del2@banana = "phone"; |
||
del3@operate = "delegate implementation"; |
del3@operate = "delegate implementation"; |
||
Print[delegator[#]@operate] & /@ {del1, del2, del3};</ |
Print[delegator[#]@operate] & /@ {del1, del2, del3};</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>default implementation |
<pre>default implementation |
||
Line 1,632: | Line 1,632: | ||
=={{header|NGS}}== |
=={{header|NGS}}== |
||
<syntaxhighlight lang="ngs">{ |
|||
<lang NGS>{ |
|||
type Delegator |
type Delegator |
||
Line 1,671: | Line 1,671: | ||
echo(a.operation()) |
echo(a.operation()) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>default implementation |
<pre>default implementation |
||
Line 1,678: | Line 1,678: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">#################################################################################################### |
||
# Base delegate. |
# Base delegate. |
||
Line 1,725: | Line 1,725: | ||
let d2 = initDelegator(Delegate2()) |
let d2 = initDelegator(Delegate2()) |
||
echo "With a delegate which provided the “thing” method: ", d2.operation()</ |
echo "With a delegate which provided the “thing” method: ", d2.operation()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,734: | Line 1,734: | ||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang="objeck">interface Thingable { |
||
method : virtual : public : Thing() ~ String; |
method : virtual : public : Thing() ~ String; |
||
} |
} |
||
Line 1,788: | Line 1,788: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
Line 1,794: | Line 1,794: | ||
{{works with|Cocoa}} |
{{works with|Cocoa}} |
||
{{works with|GNUstep}} |
{{works with|GNUstep}} |
||
< |
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h> |
||
@interface Delegator : NSObject { |
@interface Delegator : NSObject { |
||
Line 1,869: | Line 1,869: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
Objective-C 2.0, modern runtime, Automatic Reference Counting, Autosynthesize (LLVM 4.0+) |
Objective-C 2.0, modern runtime, Automatic Reference Counting, Autosynthesize (LLVM 4.0+) |
||
{{works with|Cocoa}} |
{{works with|Cocoa}} |
||
< |
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h> |
||
// Formal protocol for the delegate |
// Formal protocol for the delegate |
||
Line 1,918: | Line 1,918: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
< |
<syntaxhighlight lang="oforth">Object Class new: Delegate1 |
||
Object Class new: Delegate2 |
Object Class new: Delegate2 |
||
Line 1,931: | Line 1,931: | ||
Delegator method: operation |
Delegator method: operation |
||
@delegate respondTo(#thing) ifTrue: [ @delegate thing return ] |
@delegate respondTo(#thing) ifTrue: [ @delegate thing return ] |
||
"Default implementation" println ;</ |
"Default implementation" println ;</syntaxhighlight> |
||
Usage : |
Usage : |
||
< |
<syntaxhighlight lang="oforth">Delegator new(null) operation |
||
Default implementation |
Default implementation |
||
Line 1,941: | Line 1,941: | ||
Delegator new(Delegate2 new) operation |
Delegator new(Delegate2 new) operation |
||
Delegate implementation</ |
Delegate implementation</syntaxhighlight> |
||
=={{header|ooRexx}}== |
=={{header|ooRexx}}== |
||
<syntaxhighlight lang="oorexx"> |
|||
<lang ooRexx> |
|||
delegator = .delegator~new -- no delegate |
delegator = .delegator~new -- no delegate |
||
say delegator~operation |
say delegator~operation |
||
Line 1,985: | Line 1,985: | ||
nomethod: |
nomethod: |
||
return "default implementation" |
return "default implementation" |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|OxygenBasic}}== |
=={{header|OxygenBasic}}== |
||
< |
<syntaxhighlight lang="oxygenbasic"> |
||
class DelegateA 'not implmenting thing() |
class DelegateA 'not implmenting thing() |
||
'============== |
'============== |
||
Line 2,033: | Line 2,033: | ||
print dgr.thing 'result "not using Delegate" |
print dgr.thing 'result "not using Delegate" |
||
print dg.thing 'result "Delegate Implementation" |
print dg.thing 'result "Delegate Implementation" |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="oz">declare |
||
class Delegator from BaseObject |
class Delegator from BaseObject |
||
attr |
attr |
||
Line 2,079: | Line 2,079: | ||
{A set({New Delegate noop})} |
{A set({New Delegate noop})} |
||
{System.showInfo {A operation($)}}</ |
{System.showInfo {A operation($)}}</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
Line 2,086: | Line 2,086: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="perl">use strict; |
||
package Delegator; |
package Delegator; |
||
Line 2,124: | Line 2,124: | ||
$a->{delegate} = Delegate->new; |
$a->{delegate} = Delegate->new; |
||
$a->operation eq 'delegate implementation' or die; |
$a->operation eq 'delegate implementation' or die; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Using Moose. |
Using Moose. |
||
< |
<syntaxhighlight lang="perl"> |
||
use 5.010_000; |
use 5.010_000; |
||
Line 2,184: | Line 2,184: | ||
$delegator->operation eq 'delegate implementation' or die; |
$delegator->operation eq 'delegate implementation' or die; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 2,190: | Line 2,190: | ||
I will admit that the whole concept of "no delegate/with one that does not implement" makes no sense whatsoever to me.<br> |
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. |
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) |
function operation(object o) |
||
Line 2,233: | Line 2,233: | ||
?operation(x) |
?operation(x) |
||
?operation(y) |
?operation(y) |
||
?operation(z)</ |
?operation(z)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,242: | Line 2,242: | ||
</pre> |
</pre> |
||
Obviously, you can explictly test for rid=NULL as shown, or remove that test and catch exceptions, ie: |
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) |
try -- (since rid=NULL check commented out) |
||
?operation(y) |
?operation(y) |
||
Line 2,248: | Line 2,248: | ||
?"oops, no implementation" |
?"oops, no implementation" |
||
end try |
end try |
||
?operation(z)</ |
?operation(z)</syntaxhighlight> |
||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="php">class Delegator { |
||
function __construct() { |
function __construct() { |
||
$this->delegate = NULL ; |
$this->delegate = NULL ; |
||
Line 2,276: | Line 2,276: | ||
$a->delegate = new Delegate() ; |
$a->delegate = new Delegate() ; |
||
print "{$a->operation()}\n" ;</ |
print "{$a->operation()}\n" ;</syntaxhighlight> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(class +Delegator) |
||
# delegate |
# delegate |
||
Line 2,308: | Line 2,308: | ||
# With delegate that implements 'thing>' |
# With delegate that implements 'thing>' |
||
(put A 'delegate (new '(+Delegate) "delegate implementation")) |
(put A 'delegate (new '(+Delegate) "delegate implementation")) |
||
(println (operation> A)) )</ |
(println (operation> A)) )</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>"default implementation" |
<pre>"default implementation" |
||
Line 2,315: | Line 2,315: | ||
=={{header|Pop11}}== |
=={{header|Pop11}}== |
||
< |
<syntaxhighlight lang="pop11">uses objectclass; |
||
define :class Delegator; |
define :class Delegator; |
||
slot delegate = false; |
slot delegate = false; |
||
Line 2,346: | Line 2,346: | ||
;;; delegating to a freshly created Delegate |
;;; delegating to a freshly created Delegate |
||
newDelegate() -> delegate(a); |
newDelegate() -> delegate(a); |
||
operation(a) =></ |
operation(a) =></syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang="python">class Delegator: |
||
def __init__(self): |
def __init__(self): |
||
self.delegate = None |
self.delegate = None |
||
Line 2,373: | Line 2,373: | ||
# With delegate that implements "thing" |
# With delegate that implements "thing" |
||
a.delegate = Delegate() |
a.delegate = Delegate() |
||
assert a.operation() == 'delegate implementation'</ |
assert a.operation() == 'delegate implementation'</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Line 2,385: | Line 2,385: | ||
follows the requirement of the task better. |
follows the requirement of the task better. |
||
< |
<syntaxhighlight lang="racket">#lang racket |
||
;; Delegates. Tim Brown 2014-10-16 |
;; Delegates. Tim Brown 2014-10-16 |
||
Line 2,419: | Line 2,419: | ||
(send delegator-2 operation) => "delegate implementation" |
(send delegator-2 operation) => "delegate implementation" |
||
(send (new delegator% [delegate thinging-delegate]) operation) => "delegate implementation")) |
(send (new delegator% [delegate thinging-delegate]) operation) => "delegate implementation")) |
||
</syntaxhighlight> |
|||
</lang> |
|||
All the tests pass. Believe me. |
All the tests pass. Believe me. |
||
Line 2,425: | Line 2,425: | ||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
(formerly Perl 6) |
(formerly Perl 6) |
||
<lang |
<syntaxhighlight lang="raku" line>class Non-Delegate { } |
||
class Delegate { |
class Delegate { |
||
Line 2,452: | Line 2,452: | ||
$d.delegate = Delegate.new; |
$d.delegate = Delegate.new; |
||
say "Delegate: "~$d.operation;</ |
say "Delegate: "~$d.operation;</syntaxhighlight> |
||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="ruby">class Delegator |
||
attr_accessor :delegate |
attr_accessor :delegate |
||
def operation |
def operation |
||
Line 2,486: | Line 2,486: | ||
a.delegate = Delegate.new |
a.delegate = Delegate.new |
||
puts a.operation # prints "delegate implementation" |
puts a.operation # prints "delegate implementation" |
||
end</ |
end</syntaxhighlight> |
||
Using Forwardable lib |
Using Forwardable lib |
||
< |
<syntaxhighlight lang="ruby">require 'forwardable' |
||
class Delegator; extend Forwardable |
class Delegator; extend Forwardable |
||
Line 2,509: | Line 2,509: | ||
a = Delegator.new |
a = Delegator.new |
||
puts a.delegated # prints "Delegate" |
puts a.delegated # prints "Delegate" |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
Requiring delegates to implement Thingable: |
Requiring delegates to implement Thingable: |
||
< |
<syntaxhighlight lang="rust">trait Thingable { |
||
fn thing(&self) -> &str; |
fn thing(&self) -> &str; |
||
} |
} |
||
Line 2,539: | Line 2,539: | ||
let d: Delegator<Delegate> = Delegator(Some(Delegate {})); |
let d: Delegator<Delegate> = Delegator(Some(Delegate {})); |
||
println!("{}", d.thing()); |
println!("{}", d.thing()); |
||
}</ |
}</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>Default implmementation |
<pre>Default implmementation |
||
Line 2,545: | Line 2,545: | ||
Using nightly-only specialization feature: |
Using nightly-only specialization feature: |
||
< |
<syntaxhighlight lang="rust">#![feature(specialization)] |
||
trait Thingable { |
trait Thingable { |
||
Line 2,585: | Line 2,585: | ||
let d: Delegator<Delegate> = Delegator(Some(Delegate {})); |
let d: Delegator<Delegate> = Delegator(Some(Delegate {})); |
||
println!("{}", d.thing()); |
println!("{}", d.thing()); |
||
}</ |
}</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>Default implementation |
<pre>Default implementation |
||
Line 2,594: | Line 2,594: | ||
=={{header|Scala}}== |
=={{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)]. |
{{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 |
def thing: String |
||
} |
} |
||
Line 2,625: | Line 2,625: | ||
assert(a.operation == "anonymous delegate implementation") |
assert(a.operation == "anonymous delegate implementation") |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">class NonDelegate { } |
||
class Delegate { |
class Delegate { |
||
Line 2,652: | Line 2,652: | ||
say "NonDelegate: #{d.operation}" |
say "NonDelegate: #{d.operation}" |
||
d.delegate = Delegate() |
d.delegate = Delegate() |
||
say "Delegate: #{d.operation}"</ |
say "Delegate: #{d.operation}"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
empty: default implementation |
empty: default implementation |
||
Line 2,661: | Line 2,661: | ||
{{works with|Smalltalk/X}} |
{{works with|Smalltalk/X}} |
||
Definition of the thingy: |
Definition of the thingy: |
||
< |
<syntaxhighlight lang="smalltalk">Object |
||
subclass:#Thingy |
subclass:#Thingy |
||
instanceVariableNames:'' |
instanceVariableNames:'' |
||
thing |
thing |
||
^ 'thingy implementation'</ |
^ 'thingy implementation'</syntaxhighlight> |
||
Definition of the delegator: |
Definition of the delegator: |
||
< |
<syntaxhighlight lang="smalltalk">Object |
||
subclass:#Delegator |
subclass:#Delegator |
||
instanceVariableNames:'delegate' |
instanceVariableNames:'delegate' |
||
Line 2,677: | Line 2,677: | ||
operation |
operation |
||
^ delegate |
^ delegate |
||
perform:#thing ifNotUnderstood:'default implementation'.</ |
perform:#thing ifNotUnderstood:'default implementation'.</syntaxhighlight> |
||
Sample use: |
Sample use: |
||
< |
<syntaxhighlight lang="smalltalk">|d| |
||
d := Delegator new. |
d := Delegator new. |
||
d operation. |
d operation. |
||
Line 2,686: | Line 2,686: | ||
d delegate:(Thingy new). |
d delegate:(Thingy new). |
||
d operation. |
d operation. |
||
-> 'thingy implementation'</ |
-> 'thingy implementation'</syntaxhighlight> |
||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
Allowing the delegate to be any type and taking advantage of dynamism of method lookup: |
Allowing the delegate to be any type and taking advantage of dynamism of method lookup: |
||
< |
<syntaxhighlight lang="swift">import Foundation |
||
protocol Thingable { // prior to Swift 1.2, needs to be declared @objc |
protocol Thingable { // prior to Swift 1.2, needs to be declared @objc |
||
Line 2,722: | Line 2,722: | ||
let d = Delegate() |
let d = Delegate() |
||
a.delegate = d |
a.delegate = d |
||
println(a.operation()) // prints "delegate implementation"</ |
println(a.operation()) // prints "delegate implementation"</syntaxhighlight> |
||
Alternately, requiring the delegate to conform to a given protocol: |
Alternately, requiring the delegate to conform to a given protocol: |
||
< |
<syntaxhighlight lang="swift">protocol Thingable : class { |
||
func thing() -> String |
func thing() -> String |
||
} |
} |
||
Line 2,752: | Line 2,752: | ||
let d = Delegate() |
let d = Delegate() |
||
a.delegate = d |
a.delegate = d |
||
println(a.operation()) // prints "delegate implementation"</ |
println(a.operation()) // prints "delegate implementation"</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{works with|Tcl|8.6}} or {{libheader|TclOO}} |
{{works with|Tcl|8.6}} or {{libheader|TclOO}} |
||
Uses [[Assertions#Tcl]] |
Uses [[Assertions#Tcl]] |
||
< |
<syntaxhighlight lang="tcl">package require TclOO |
||
oo::class create Delegate { |
oo::class create Delegate { |
||
Line 2,809: | Line 2,809: | ||
assert {[a operation] ne "default implementation"} |
assert {[a operation] ne "default implementation"} |
||
puts "all assertions passed"</ |
puts "all assertions passed"</syntaxhighlight> |
||
To code the <code>operation</code> method without relying on catching an exception, but strictly by using introspection: |
To code the <code>operation</code> method without relying on catching an exception, but strictly by using introspection: |
||
< |
<syntaxhighlight lang="tcl">method operation {} { |
||
if { [info exists delegate] && |
if { [info exists delegate] && |
||
[info object isa object $delegate] && |
[info object isa object $delegate] && |
||
Line 2,821: | Line 2,821: | ||
set result "default implementation" |
set result "default implementation" |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Vorpal}}== |
=={{header|Vorpal}}== |
||
Delegate objects can be an array of delegates or as a single delegate. |
Delegate objects can be an array of delegates or as a single delegate. |
||
< |
<syntaxhighlight lang="vorpal">a = new() |
||
a.f = method(){ |
a.f = method(){ |
||
.x.print() |
.x.print() |
||
Line 2,848: | Line 2,848: | ||
d.delegate = a |
d.delegate = a |
||
d.x = 7 |
d.x = 7 |
||
d.f()</ |
d.f()</syntaxhighlight> |
||
The resulting output: |
The resulting output: |
||
Line 2,859: | Line 2,859: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
Wren is dynamically typed so we can plug any kind of delegate into the Delegator. |
Wren is dynamically typed so we can plug any kind of delegate into the Delegator. |
||
< |
<syntaxhighlight lang="ecmascript">class Thingable { |
||
thing { } |
thing { } |
||
} |
} |
||
Line 2,899: | Line 2,899: | ||
// with a delegate that does implement Thingable |
// with a delegate that does implement Thingable |
||
d.delegate = Delegate2.new() |
d.delegate = Delegate2.new() |
||
System.print(d.operation)</ |
System.print(d.operation)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,910: | Line 2,910: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|Scala}} |
{{trans|Scala}} |
||
< |
<syntaxhighlight lang="zkl">class Thingable{ var thing; } |
||
class Delegator{ |
class Delegator{ |
||
Line 2,920: | Line 2,920: | ||
} |
} |
||
class Delegate(Thingable){ thing = "delegate implementation" }</ |
class Delegate(Thingable){ thing = "delegate implementation" }</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl"> // Without a delegate: |
||
a:= Delegator(); |
a:= Delegator(); |
||
a.operation().println(); //--> "default implementation" |
a.operation().println(); //--> "default implementation" |
||
Line 2,928: | Line 2,928: | ||
// With a delegate: |
// With a delegate: |
||
a.delegate = Delegate(); |
a.delegate = Delegate(); |
||
a.operation().println(); //-->"delegate implementation"</ |
a.operation().println(); //-->"delegate implementation"</syntaxhighlight> |
||
A second example |
A second example |
||
< |
<syntaxhighlight lang="zkl">class [static] Logger{ // Only one logging resource |
||
var [mixin=File] dst; // File like semantics, eg Data, Pipe |
var [mixin=File] dst; // File like semantics, eg Data, Pipe |
||
dst = File.DevNull; |
dst = File.DevNull; |
||
// initially, the logger does nothing |
// initially, the logger does nothing |
||
fcn log(msg){dst.writeln(vm.pasteArgs())} |
fcn log(msg){dst.writeln(vm.pasteArgs())} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">Logger.log("this is a test"); //-->nada |
||
Logger.dst=Console; |
Logger.dst=Console; |
||
Logger.log("this is a test 2"); //-->writes to Console |
Logger.log("this is a test 2"); //-->writes to Console |
||
class B(Logger){ log("Hello from ",self,"'s constructor"); } |
class B(Logger){ log("Hello from ",self,"'s constructor"); } |
||
B(); //-->Hello from Class(B)'s constructor</ |
B(); //-->Hello from Class(B)'s constructor</syntaxhighlight> |
||
The base class B was constructed at startup, |
The base class B was constructed at startup, |