Send an unknown method call: Difference between revisions

add Ecstasy example
(Added Io entry)
(add Ecstasy example)
 
(37 intermediate revisions by 23 users not shown)
Line 1:
{{task|Object oriented}}
 
;Task:
Invoke an object method where the name of the method to be invoked can be generated at run time.
 
 
;Cf:
;Related tasks:
* [[Respond to an unknown method call]].
* [[Runtime evaluation]]
<br><br>
 
=={{header|AutoHotkey}}==
This object has 3 methods, and asks the user to name one to call. Instead of using Func(), one could use a class definition.
<langsyntaxhighlight AHKlang="ahk">obj := {mA: Func("mA"), mB: Func("mB"), mC: Func("mC")}
InputBox, methodToCall, , Which method should I call?
obj[methodToCall].()
Line 22 ⟶ 25:
MsgBox Method C
}
</syntaxhighlight>
</lang>
 
=={{header|Bracmat}}==
<langsyntaxhighlight Bracmatlang="bracmat">(task=
( oracle
= (predicate="is made of green cheese")
Line 44 ⟶ 47:
& (SourceOfKnowledge..str$(generate !trueorlie))$!something
);
</syntaxhighlight>
</lang>
{{out|Example}}
<pre>{?} !task
Line 55 ⟶ 58:
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
 
class Example
Line 76 ⟶ 79:
}
}
</syntaxhighlight>
</lang>
{{out}}
foo(5) = 47
Line 84 ⟶ 87:
$METHOD executes a named instance method for a specified instance of a designated class.
 
<langsyntaxhighlight lang="cos">Class Unknown.Example Extends %RegisteredObject
{
 
Line 97 ⟶ 100:
}
 
}</langsyntaxhighlight>
{{out|Examples}}
<pre>
Line 106 ⟶ 109:
This is bar
</pre>
 
 
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">
(import '[java.util Date])
(import '[clojure.lang Reflector])
 
(def date1 (Date.))
(def date2 (Date.))
(def method "equals")
 
;; Two ways of invoking method "equals" on object date1
;; using date2 as argument
 
;; Way 1 - Using Reflector class
;; NOTE: The argument date2 is passed inside an array
(Reflector/invokeMethod date1 method (object-array [date2]))
 
;; Way 2 - Using eval
;; Eval runs any piece of valid Clojure code
;; So first we construct a piece of code to do what we want (where method name is inserted dynamically),
;; then we run the code using eval
(eval `(. date1 ~(symbol method) date2))
</syntaxhighlight>
 
=={{header|Common Lisp}}==
Unknown methods are called just like any other function. Find the method-naming symbol using INTERN then call it with FUNCALL.
<langsyntaxhighlight lang="lisp">(funcall (intern "SOME-METHOD") my-object a few arguments)</langsyntaxhighlight>
 
=={{header|Déjà Vu}}==
<langsyntaxhighlight lang="dejavu">local :object { :add @+ }
local :method :add
 
!. object! method 1 2</langsyntaxhighlight>
{{out}}
<pre>3</pre>
Line 123 ⟶ 150:
This example goes well with the object named <code>example</code> in [[Respond to an unknown method call#E]].
 
<langsyntaxhighlight lang="e">for name in ["foo", "bar"] {
E.call(example, name, [])
}</langsyntaxhighlight>
=={{header|Elena}}==
<lang elena>#import system.
#import extensions.
 
=={{header|Ecstasy}}==
#class Example
Here's a simple example of a test module using its runtime type to search for methods by some name (specified on the the command line), grabbing the one by that name that requires no parameters, and dynamically invoking it:
 
<syntaxhighlight lang="ecstasy">
module test {
@Inject Console console;
 
void run(String[] args) {
String name = args.empty ? "foo" : args[0];
if (val mm := &this.actualType.multimethods.get(name),
val m := mm.methods.any(m -> m.ParamTypes.size == 0)) {
m.invoke(this, Tuple:());
} else {
console.print($"No such 0-parameter method: {name.quoted()}");
}
}
 
void foo() {
console.print("this is the foo() method");
}
 
void bar() {
console.print("this is the bar() method");
}
}
</syntaxhighlight>
 
{{out}}
<pre>
x$ xec test foo
this is the foo() method
x$ xec test bar
this is the bar() method
x$ xec test baz
No such 0-parameter method: "baz"
</pre>
 
=={{header|Elena}}==
ELENA 4.1 :
<syntaxhighlight lang="elena">import extensions;
class Example
{
#method foo : (x)
= x + 42.;
}
public program()
{
var example := new Example();
var methodSignature := "foo";
var invoker := new MessageName(methodSignature);
var result := invoker(example,5);
console.printLine(methodSignature,"(",5,") = ",result)
}</syntaxhighlight>
{{out}}
<pre>
foo(5) = 47
</pre>
 
=={{header|Factor}}==
Factor's object model is such that objects themselves don't contain methods — generic words do. So there is nothing different about invoking an unknown method than invoking an unknown word in general.
<syntaxhighlight lang="factor">USING: accessors kernel math prettyprint sequences words ;
IN: rosetta-code.unknown-method-call
 
TUPLE: foo num ;
C: <foo> foo
GENERIC: add5 ( x -- y )
M: foo add5 num>> 5 + ;
 
42 <foo> ! construct a foo
#symbol program =
"add" "5" append ! construct a word name
[
! must specify vocab to look up a word
#var example := Example new.
"rosetta-code.unknown-method-call"
#var methodSignature := "foo".
lookup-word execute . ! 47</syntaxhighlight>
#var result := example::(Signature new &literal:methodSignature) eval:5.
console writeLine:methodSignature:"(":5:") = ":result.
].</lang>
 
=={{header|Forth}}==
Line 152 ⟶ 238:
Needs the FMS-SI (single inheritance) library code located here:
http://soton.mpeforth.com/flag/fms/index.html
<langsyntaxhighlight lang="forth">include FMS-SI.f
include FMS-SILib.f
 
var x \ instantiate a class var object named x
 
\ Use a standard Forth string and evaluate it.
: test
\ This is equivalent to sending the !: message to object x
heap> string locals| s |
42 x s" !:" evaluate
'!' s +: ':' s +: \ build the message "!:" into string s
42 x s @: evaluate \ retrieve the text from s and execute it
x p: ; \ lastly, send the p: message to x to print it
 
x p: 42 \ send the print message ( p: ) to x to verify the contents
test \ => 42 ok
 
</lang>
</syntaxhighlight>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="basic">Type Example
foo As Integer Ptr
Declare Constructor (x As Integer)
End Type
 
Constructor Example(x As Integer)
This.foo = New Integer
*This.foo = 42 + x
End Constructor
 
Dim As Example result = 5
Print *result.foo
 
Sleep</syntaxhighlight>
{{out}}
<pre> 47</pre>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 190 ⟶ 293:
// interpret first return value as int
fmt.Println(r[0].Int()) // => 42
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="grrovy">class Example {
def foo(value) {
"Invoked with '$value'"
Line 203 ⟶ 306:
def arg = "test value"
 
assert "Invoked with 'test value'" == example."$method"(arg)</langsyntaxhighlight>
 
==Icon and {{header|Unicon}}==
<langsyntaxhighlight Uniconlang="unicon">procedure main()
x := foo() # create object
x.m1() # static call of m1 method
Line 217 ⟶ 320:
method m1(x)
end
end</langsyntaxhighlight>
 
For more information on this see [[Respond_to_an_unknown_method_call#Icon_and_Unicon|Respond to an unknown method call]].
 
=={{header|Io}}==
String literal "foo" may be replaced by any expression resulting in a string.
<langsyntaxhighlight Iolang="io">Example := Object clone
Example foo := method(x, 42+x)
 
name := "foo"
Example clone perform(name,5) println // prints "47"</langsyntaxhighlight>
 
=={{header|J}}==
Line 234 ⟶ 338:
There are other methods as well, e.g., '''<tt>@.</tt>''','''<tt>`:</tt>''', and '''<tt>^:</tt>''', though these are designed to consume gerunds (pre-parsed ASTs) rather than strings (though, of course, a pre-processor can always be provided to convert strings into ASTs before feeding them to these operators).
 
'''Example''':<langsyntaxhighlight lang="j"> sum =: +/
prod =: */
count =: #
Line 254 ⟶ 358:
3
nameToDispatch (128!:2) 1 2 3
3</langsyntaxhighlight>
 
=={{header|Java}}==
Using reflection
<langsyntaxhighlight lang="java">import java.lang.reflect.Method;
 
class Example {
Line 275 ⟶ 379:
System.out.println(result); // prints "47"
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
String literal "foo" may be replaced by any expression resulting in a string
<langsyntaxhighlight lang="javascript">example = new Object;
example.foo = function(x) {
return 42 + x;
Line 285 ⟶ 389:
 
name = "foo";
example[name](5) # => 47</langsyntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<syntaxhighlight lang="julia">const functions = Dict{String,Function}(
"foo" => x -> 42 + x,
"bar" => x -> 42 * x)
 
@show functions["foo"](3)
@show functions["bar"](3)</syntaxhighlight>
 
{{out}}
<pre>(functions["foo"])(3) = 45
(functions["bar"])(3) = 126</pre>
 
=={{header|Kotlin}}==
When you try to compile the following program, it will appear to the compiler that the local variable 'c' is assigned but never used and a warning will be issued accordingly. You can get rid of this warning by compiling using the -nowarn flag.
<syntaxhighlight lang="scala">// Kotlin JS version 1.1.4-3
 
class C {
fun foo() {
println("foo called")
}
}
 
fun main(args: Array<String>) {
val c = C()
val f = "c.foo"
js(f)() // invokes c.foo dynamically
}</syntaxhighlight>
 
{{out}}
<pre>
foo called
</pre>
 
=={{header|Lasso}}==
<langsyntaxhighlight Lassolang="lasso">define mytype => type {
public foo() => {
return 'foo was called'
Line 297 ⟶ 437:
local(obj = mytype, methodname = tag('foo'), methodname2 = tag('bar'))
#obj->\#methodname->invoke
#obj->\#methodname2->invoke</langsyntaxhighlight>
{{out}}
<pre>foo was called
this time is was bar</pre>
 
=={{header|Lingo}}==
<syntaxhighlight lang="lingo">obj = script("MyClass").new()
-- ...
method = #foo
arg1 = 23
res = call(method, obj, arg1)</syntaxhighlight>
 
=={{header|Logtalk}}==
For this task, we first define a simple object with a single method:
<langsyntaxhighlight lang="logtalk">:- object(foo).
 
:- public(bar/1).
bar(42).
 
:- end_object.</langsyntaxhighlight>Second, we define another object that asks the user for a message to be sent to the first object:<langsyntaxhighlight lang="logtalk">
:- object(query_foo).
 
Line 320 ⟶ 467:
write(Message), nl.
 
:- end_object.</langsyntaxhighlight>After compiling and loading both objects, we can try:
| ?- query_foo::query.
Message: bar(X).
Reply: bar(42)
 
=={{header|Lua}}==
Don't forget to pass the object for methods!
<langsyntaxhighlight lang="lua">local example = { }
function example:foo (x) return 42 + x end
 
local name = "foo"
example[name](example, 5) --> 47</langsyntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Creates a dialog box where one can type a function (Sin, Cos, Tan ...) and then a second dialog box for a value.
<syntaxhighlight lang="text">ToExpression[Input["function? E.g. Sin",]][Input["value? E.g. 0.4123"]]</langsyntaxhighlight>
{{out}}
<pre>Input: Sin
Input: Sin
Input: 3.1415
Output: 0.0000926536</pre>
</pre>
 
 
=={{header|MATLAB}} / {{header|Octave}}==
 
 
<syntaxhighlight lang="matlab">
<lang Matlab>
funName = 'foo'; % generate function name
feval (funNAME, ...) % evaluation function with optional parameters
Line 352 ⟶ 497:
funName = 'a=atan(pi)'; % generate function name
eval (funName, 'printf(''Error\n'')')
</syntaxhighlight>
</lang>
 
=={{header|Objective-C}}==
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
@interface Example : NSObject
Line 376 ⟶ 521:
}
return 0;
}</langsyntaxhighlight>
The <code>performSelector: ...</code> methods can only be used with methods with 0 - 2 object arguments, and an object or <code>void</code> return type. For all other calls, one can create an <code>NSInvocation</code> object and invoke it, or directly call one of the <code>objc_msgSend</code> family of runtime functions.
 
Line 382 ⟶ 527:
 
A method object can be retrieved from its name using asMethod.
<langsyntaxhighlight Oforthlang="oforth">16 "sqrt" asMethod perform</langsyntaxhighlight>
Others :
Line 390 ⟶ 535:
 
A generic way to search a word into the dictionary in to use find method :
<langsyntaxhighlight Oforthlang="oforth">16 Word find("sqrt") Word find perform</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">foo()=5;
eval(Str("foo","()"))</langsyntaxhighlight>
 
=={{header|Pascal}}==
 
Works with FPC (tested with version 3.2.2).
 
In the simplest case, when the methods are procedures without parameters, it might look something like this (note that these methods are currently required to have PUBLISHED visibility):
<syntaxhighlight lang="pascal">
program Test;
{$mode objfpc}{$h+}
uses
SysUtils;
 
type
TProc = procedure of object;
 
{$push}{$m+}
TMyObj = class
strict private
FName: string;
public
constructor Create(const aName: string);
property Name: string read FName;
published
procedure Foo;
procedure Bar;
end;
{$pop}
 
constructor TMyObj.Create(const aName: string);
begin
FName := aName;
end;
 
procedure TMyObj.Foo;
begin
WriteLn(Format('This is %s.Foo()', [Name]));
end;
 
procedure TMyObj.Bar;
begin
WriteLn(Format('This is %s.Bar()', [Name]));
end;
 
procedure CallByName(o: TMyObj; const aName: string);
var
m: TMethod;
begin
m.Code := o.MethodAddress(aName);
if m.Code <> nil then begin
m.Data := o;
TProc(m)();
end else
WriteLn(Format('Unknown method(%s)', [aName]));
end;
 
var
o: TMyObj;
 
begin
o := TMyObj.Create('Obj');
CallByName(o, 'Bar');
CallByName(o, 'Foo');
CallByName(o, 'Baz');
o.Free;
end.
</syntaxhighlight>
 
{{out}}
<pre>
This is Obj.Bar()
This is Obj.Foo()
Unknown method(Baz)
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">package Example;
sub new {
bless {}
Line 408 ⟶ 626:
package main;
my $name = "foo";
print Example->new->$name(5), "\n"; # prints "47"</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
Not specifically anything to do with objects, but you can construct routine names at runtime:
Just for the fun of it, we'll mix in an anonymous role into an integer instead of defining a class.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang perl6>my $object = 42 but role { method add-me($x) { self + $x } }
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
my $name = 'add-me';
<span style="color: #008080;">procedure</span> <span style="color: #000000;">Hello</span><span style="color: #0000FF;">()</span>
say $object."$name"(5); # 47</lang>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"Hello"</span>
The double quotes are required, by the way; without them the variable would be interpreted as a hard ref to a method.
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">erm</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Hemmm"</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span> <span style="color: #008080;">to</span> <span style="color: #000000;">5</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">erm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]+=-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">3</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">call_proc</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #000000;">erm</span><span style="color: #0000FF;">),{})</span>
<!--</syntaxhighlight>-->
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php"><?php
class Example {
function foo($x) {
Line 432 ⟶ 659:
// alternately:
echo call_user_func(array($example, $name), 5), "\n";
?></langsyntaxhighlight>
 
=={{header|Picat}}==
For functions use <code>apply/n</code> and for predicates <code>call/n</code>. The name of the function/predicate must be an atom and strings must be converted to atom, e.g. with <code>to_atom/1</code>.
<syntaxhighlight lang="picat">go =>
println("Function: Use apply/n"),
Fun = "fib",
A = 10,
% Convert F to an atom
println(apply(to_atom(Fun),A)),
nl,
 
println("Predicate: use call/n"),
Pred = "pyth",
call(Pred.to_atom,3,4,Z),
println(z=Z),
 
% Pred2 is an atom so it can be used directly with call/n.
Pred2 = pyth,
call(Pred.to_atom,13,14,Z2),
println(z2=Z2),
nl.
 
% A function
fib(1) = 1.
fib(2) = 1.
fib(N) = fib(N-1) + fib(N-2).
 
% A predicate
pyth(X,Y,Z) =>
Z = X**2 + Y**2.</syntaxhighlight>
 
{{out}}
<pre>Function: Use apply/n
55
 
Predicate: use call/n
z = 25
z2 = 365</pre>
 
=={{header|PicoLisp}}==
This can be done with the '[http://software-lab.de/doc/refS.html#send send]' function.
<langsyntaxhighlight PicoLisplang="picolisp">(send (expression) Obj arg1 arg2)</langsyntaxhighlight>
 
=={{header|Pike}}==
with [] instead of -> a string can be used to name a method:
<langsyntaxhighlight Pikelang="pike">string unknown = "format_nice";
object now = Calendar.now();
now[unknown]();</langsyntaxhighlight>
 
=={{header|PowerShell}}==
A random method using a random number:
<syntaxhighlight lang="powershell">
$method = ([Math] | Get-Member -MemberType Method -Static | Where-Object {$_.Definition.Split(',').Count -eq 1} | Get-Random).Name
$number = (1..9 | Get-Random) / 10
$result = [Math]::$method($number)
$output = [PSCustomObject]@{
Method = $method
Number = $number
Result = $result
}
 
$output | Format-List
</syntaxhighlight>
{{Out}}
<pre>
Method : Atan
Number : 0.5
Result : 0.463647609000806
</pre>
 
=={{header|Python}}==
String literal "foo" may be replaced by any expression resulting in a string
<langsyntaxhighlight lang="python">class Example(object):
def foo(self, x):
return 42 + x
 
name = "foo"
getattr(Example(), name)(5) # => 47</langsyntaxhighlight>
 
=={{header|Qi}}==
<syntaxhighlight lang="qi">
<lang qi>
(define foo -> 5)
 
Line 461 ⟶ 748:
 
(execute-function "foo")
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(define greeter
Line 477 ⟶ 764:
(define unknown 'hello)
(dynamic-send greeter unknown "World")
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
Just for the fun of it, we'll mix in an anonymous role into an integer instead of defining a class.
<syntaxhighlight lang="raku" line>my $object = 42 but role { method add-me($x) { self + $x } }
my $name = 'add-me';
say $object."$name"(5); # 47</syntaxhighlight>
The double quotes are required, by the way; without them the variable would be interpreted as a hard ref to a method.
 
=={{header|Ruby}}==
You may replace :foo, :bar or "bar" with any expression that returns a Symbol or String.
 
<langsyntaxhighlight lang="ruby">class Example
def foo
42
Line 495 ⟶ 790:
Example.new.send( :bar, 1, 2 ) { |x,y| x+y } # => 3
args = [1, 2]
Example.new.send( "bar", *args ) { |x,y| x+y } # => 3</langsyntaxhighlight>
 
Object#send can also call protected and private methods, skipping the usual access checks. Ruby 1.9 adds Object#public_send, which only calls public methods.
 
{{works with|Ruby|1.9}}
<langsyntaxhighlight lang="ruby">class Example
private
def privacy; "secret"; end
Line 510 ⟶ 805:
e.public_send :publicity # => "hi"
e.public_send :privacy # raises NoMethodError
e.send :privacy # => "secret"</langsyntaxhighlight>
 
=={{header|Scala}}==
{{libheader|Scala}}<langsyntaxhighlight lang="scala">class Example {
def foo(x: Int): Int = 42 + x
}
Line 524 ⟶ 819:
assert(meth.invoke(example, 5.asInstanceOf[AnyRef]) == 47.asInstanceOf[AnyRef], "Not confirm expectation.")
println(s"Successfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart} ms]")
}</langsyntaxhighlight>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">class Example {
method foo(x) {
42 + x;
}
}
 
var name = 'foo';
var obj = Example();
 
say obj.(name)(5); # prints: 47</lang>
say obj.(name)(5) # prints: 47
say obj.method(name)(5) # =//=</syntaxhighlight>
 
=={{header|Smalltalk}}==
<langsyntaxhighlight lang="smalltalk">Object subclass: #Example.
 
Example extend [
Line 546 ⟶ 843:
symbol := 'foo:' asSymbol. " same as symbol := #foo: "
 
Example new perform: symbol with: 5. " returns 47 "</langsyntaxhighlight>
The <code>perform:with:with:</code> family of methods exist for methods with 0 - 2 (3 in [[GNU Smalltalk]]) arguments. For methods with more arguments, use <code>perform:withArguments:</code>, which takes an array of arguments.
 
 
=={{header|Swift}}==
 
Generally speaking, pure Swift is a very statically typed language, and calling unknown methods is impossible. However, Swift provides a few ways in which instances of specially marked objects can receive unknown method calls.
 
===Objective-C Compatibility Using @objc===
 
The first case is used for interfacing with legacy Objective-C libraries. Objective-C is heavily dynamic with Smalltalk-style message passing. So Swift must be able to participate in this.
 
<syntaxhighlight lang="swift">import Foundation
 
class MyUglyClass: NSObject {
@objc
func myUglyFunction() {
print("called myUglyFunction")
}
}
 
let someObject: NSObject = MyUglyClass()
 
someObject.perform(NSSelectorFromString("myUglyFunction"))</syntaxhighlight>
 
{{out}}
 
<pre>called myUglyFunction</pre>
 
===Dynamic Language Interop with @dynamicCallable and @dynamicMemberLookup===
 
One of Swift's goals is to able to effectively bridge to dynamic languages such as Python and JavaScript. In order to facilitate more natural APIs, Swift provides the <code>@dynamicCallable</code> and <code>@dynamicMemberLookup</code> attributes which allow for runtime handling of method calls.
 
<syntaxhighlight lang="swift">@dynamicCallable
protocol FunDynamics {
var parent: MyDynamicThing { get }
 
func dynamicallyCall(withArguments args: [Int]) -> MyDynamicThing
func dynamicallyCall(withKeywordArguments args: [String: Int]) -> MyDynamicThing
}
 
extension FunDynamics {
func dynamicallyCall(withKeywordArguments args: [String: Int]) -> MyDynamicThing {
if let add = args["adding"] {
parent.n += add
}
 
if let sub = args["subtracting"] {
parent.n -= sub
}
 
return parent
}
}
 
@dynamicMemberLookup
class MyDynamicThing {
var n: Int
 
init(n: Int) {
self.n = n
}
 
subscript(dynamicMember member: String) -> FunDynamics {
switch member {
case "subtract":
return Subtracter(parent: self)
case "add":
return Adder(parent: self)
case _:
return Nuller(parent: self)
}
}
}
 
struct Nuller: FunDynamics {
var parent: MyDynamicThing
 
func dynamicallyCall(withArguments args: [Int]) -> MyDynamicThing { parent }
}
 
struct Subtracter: FunDynamics {
var parent: MyDynamicThing
 
func dynamicallyCall(withArguments args: [Int]) -> MyDynamicThing {
switch args.count {
case 1:
parent.n -= args[0]
case _:
print("Unknown call")
}
 
return parent
}
}
 
struct Adder: FunDynamics {
var parent: MyDynamicThing
 
func dynamicallyCall(withArguments arg: [Int]) -> MyDynamicThing {
switch arg.count {
case 1:
parent.n += arg[0]
case _:
print("Unknown call")
}
 
return parent
}
}
 
let thing =
MyDynamicThing(n: 0)
.add(20)
.divide(2) // Unhandled call, do nothing
.subtract(adding: 10, subtracting: 14)
 
print(thing.n)</syntaxhighlight>
 
{{out}}
 
<pre>16</pre>
 
=={{header|Tcl}}==
Method names are really just strings, i.e., ordinary values that can be produced by any mechanism:
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
oo::class create Example {
method foo {} {return 42}
Line 564 ⟶ 981:
for {set i 1} {$i <= 4} {incr i} {
$eg $i ...
}</langsyntaxhighlight>
{{out|The above produces this output}}
42
Line 571 ⟶ 988:
foe...
fum...
 
=={{header|Wren}}==
<syntaxhighlight lang="wren">import "meta" for Meta
class Test {
construct new() {}
foo() { System.print("Foo called.") }
bar() { System.print("Bar called.") }
}
 
var test = Test.new()
for (method in ["foo", "bar"]) {
Meta.eval("test.%(method)()")
}</syntaxhighlight>
 
{{out}}
<pre>
Foo called.
Bar called.
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">name:="len"; "this is a test".resolve(name)() //-->14</langsyntaxhighlight>
 
{{omit from|Ada}}
{{omit from|Axe}}
{{omit from|BASIC}}
{{omit from|C|No such thing as object method}}
{{omit from|C++}}
{{omit from|GUISS}}
{{omit from|REXX|No such thing as object methodNim}}
{{omit from|Rust|No runtime reflection}}
{{omit from|ZX Spectrum Basic}}
162

edits