Send an unknown method call: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Picat}}: code tag for functions)
m (syntax highlighting fixup automation)
Line 12: Line 12:
=={{header|AutoHotkey}}==
=={{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.
This object has 3 methods, and asks the user to name one to call. Instead of using Func(), one could use a class definition.
<lang AHK>obj := {mA: Func("mA"), mB: Func("mB"), mC: Func("mC")}
<syntaxhighlight lang="ahk">obj := {mA: Func("mA"), mB: Func("mB"), mC: Func("mC")}
InputBox, methodToCall, , Which method should I call?
InputBox, methodToCall, , Which method should I call?
obj[methodToCall].()
obj[methodToCall].()
Line 25: Line 25:
MsgBox Method C
MsgBox Method C
}
}
</syntaxhighlight>
</lang>


=={{header|Bracmat}}==
=={{header|Bracmat}}==
<lang Bracmat>(task=
<syntaxhighlight lang="bracmat">(task=
( oracle
( oracle
= (predicate="is made of green cheese")
= (predicate="is made of green cheese")
Line 47: Line 47:
& (SourceOfKnowledge..str$(generate !trueorlie))$!something
& (SourceOfKnowledge..str$(generate !trueorlie))$!something
);
);
</syntaxhighlight>
</lang>
{{out|Example}}
{{out|Example}}
<pre>{?} !task
<pre>{?} !task
Line 58: Line 58:


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


class Example
class Example
Line 79: Line 79:
}
}
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
foo(5) = 47
foo(5) = 47
Line 87: Line 87:
$METHOD executes a named instance method for a specified instance of a designated class.
$METHOD executes a named instance method for a specified instance of a designated class.


<lang cos>Class Unknown.Example Extends %RegisteredObject
<syntaxhighlight lang="cos">Class Unknown.Example Extends %RegisteredObject
{
{


Line 100: Line 100:
}
}


}</lang>
}</syntaxhighlight>
{{out|Examples}}
{{out|Examples}}
<pre>
<pre>
Line 112: Line 112:


=={{header|Clojure}}==
=={{header|Clojure}}==
<lang clojure>
<syntaxhighlight lang="clojure">
(import '[java.util Date])
(import '[java.util Date])
(import '[clojure.lang Reflector])
(import '[clojure.lang Reflector])
Line 132: Line 132:
;; then we run the code using eval
;; then we run the code using eval
(eval `(. date1 ~(symbol method) date2))
(eval `(. date1 ~(symbol method) date2))
</syntaxhighlight>
</lang>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
Unknown methods are called just like any other function. Find the method-naming symbol using INTERN then call it with FUNCALL.
Unknown methods are called just like any other function. Find the method-naming symbol using INTERN then call it with FUNCALL.
<lang lisp>(funcall (intern "SOME-METHOD") my-object a few arguments)</lang>
<syntaxhighlight lang="lisp">(funcall (intern "SOME-METHOD") my-object a few arguments)</syntaxhighlight>


=={{header|Déjà Vu}}==
=={{header|Déjà Vu}}==
<lang dejavu>local :object { :add @+ }
<syntaxhighlight lang="dejavu">local :object { :add @+ }
local :method :add
local :method :add


!. object! method 1 2</lang>
!. object! method 1 2</syntaxhighlight>
{{out}}
{{out}}
<pre>3</pre>
<pre>3</pre>
Line 150: Line 150:
This example goes well with the object named <code>example</code> in [[Respond to an unknown method call#E]].
This example goes well with the object named <code>example</code> in [[Respond to an unknown method call#E]].


<lang e>for name in ["foo", "bar"] {
<syntaxhighlight lang="e">for name in ["foo", "bar"] {
E.call(example, name, [])
E.call(example, name, [])
}</lang>
}</syntaxhighlight>


=={{header|Elena}}==
=={{header|Elena}}==
ELENA 4.1 :
ELENA 4.1 :
<lang elena>import extensions;
<syntaxhighlight lang="elena">import extensions;
class Example
class Example
Line 173: Line 173:
console.printLine(methodSignature,"(",5,") = ",result)
console.printLine(methodSignature,"(",5,") = ",result)
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 181: Line 181:
=={{header|Factor}}==
=={{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.
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.
<lang factor>USING: accessors kernel math prettyprint sequences words ;
<syntaxhighlight lang="factor">USING: accessors kernel math prettyprint sequences words ;
IN: rosetta-code.unknown-method-call
IN: rosetta-code.unknown-method-call


Line 193: Line 193:
! must specify vocab to look up a word
! must specify vocab to look up a word
"rosetta-code.unknown-method-call"
"rosetta-code.unknown-method-call"
lookup-word execute . ! 47</lang>
lookup-word execute . ! 47</syntaxhighlight>


=={{header|Forth}}==
=={{header|Forth}}==
Line 201: Line 201:
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
<lang forth>include FMS-SI.f
<syntaxhighlight lang="forth">include FMS-SI.f
include FMS-SILib.f
include FMS-SILib.f


Line 212: Line 212:
x p: 42 \ send the print message ( p: ) to x to verify the contents
x p: 42 \ send the print message ( p: ) to x to verify the contents


</syntaxhighlight>
</lang>


=={{header|Go}}==
=={{header|Go}}==
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 238: Line 238:
// interpret first return value as int
// interpret first return value as int
fmt.Println(r[0].Int()) // => 42
fmt.Println(r[0].Int()) // => 42
}</lang>
}</syntaxhighlight>


=={{header|Groovy}}==
=={{header|Groovy}}==
<lang grrovy>class Example {
<syntaxhighlight lang="grrovy">class Example {
def foo(value) {
def foo(value) {
"Invoked with '$value'"
"Invoked with '$value'"
Line 251: Line 251:
def arg = "test value"
def arg = "test value"


assert "Invoked with 'test value'" == example."$method"(arg)</lang>
assert "Invoked with 'test value'" == example."$method"(arg)</syntaxhighlight>


==Icon and {{header|Unicon}}==
==Icon and {{header|Unicon}}==
<lang Unicon>procedure main()
<syntaxhighlight lang="unicon">procedure main()
x := foo() # create object
x := foo() # create object
x.m1() # static call of m1 method
x.m1() # static call of m1 method
Line 265: Line 265:
method m1(x)
method m1(x)
end
end
end</lang>
end</syntaxhighlight>


For more information on this see [[Respond_to_an_unknown_method_call#Icon_and_Unicon|Respond to an unknown method call]].
For more information on this see [[Respond_to_an_unknown_method_call#Icon_and_Unicon|Respond to an unknown method call]].
Line 271: Line 271:
=={{header|Io}}==
=={{header|Io}}==
String literal "foo" may be replaced by any expression resulting in a string.
String literal "foo" may be replaced by any expression resulting in a string.
<lang Io>Example := Object clone
<syntaxhighlight lang="io">Example := Object clone
Example foo := method(x, 42+x)
Example foo := method(x, 42+x)


name := "foo"
name := "foo"
Example clone perform(name,5) println // prints "47"</lang>
Example clone perform(name,5) println // prints "47"</syntaxhighlight>


=={{header|J}}==
=={{header|J}}==
Line 283: Line 283:
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).
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''':<lang j> sum =: +/
'''Example''':<syntaxhighlight lang="j"> sum =: +/
prod =: */
prod =: */
count =: #
count =: #
Line 303: Line 303:
3
3
nameToDispatch (128!:2) 1 2 3
nameToDispatch (128!:2) 1 2 3
3</lang>
3</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==
Using reflection
Using reflection
<lang java>import java.lang.reflect.Method;
<syntaxhighlight lang="java">import java.lang.reflect.Method;


class Example {
class Example {
Line 324: Line 324:
System.out.println(result); // prints "47"
System.out.println(result); // prints "47"
}
}
}</lang>
}</syntaxhighlight>


=={{header|JavaScript}}==
=={{header|JavaScript}}==
String literal "foo" may be replaced by any expression resulting in a string
String literal "foo" may be replaced by any expression resulting in a string
<lang javascript>example = new Object;
<syntaxhighlight lang="javascript">example = new Object;
example.foo = function(x) {
example.foo = function(x) {
return 42 + x;
return 42 + x;
Line 334: Line 334:


name = "foo";
name = "foo";
example[name](5) # => 47</lang>
example[name](5) # => 47</syntaxhighlight>


=={{header|Julia}}==
=={{header|Julia}}==
{{works with|Julia|0.6}}
{{works with|Julia|0.6}}


<lang julia>const functions = Dict{String,Function}(
<syntaxhighlight lang="julia">const functions = Dict{String,Function}(
"foo" => x -> 42 + x,
"foo" => x -> 42 + x,
"bar" => x -> 42 * x)
"bar" => x -> 42 * x)


@show functions["foo"](3)
@show functions["foo"](3)
@show functions["bar"](3)</lang>
@show functions["bar"](3)</syntaxhighlight>


{{out}}
{{out}}
Line 352: Line 352:
=={{header|Kotlin}}==
=={{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.
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.
<lang scala>// Kotlin JS version 1.1.4-3
<syntaxhighlight lang="scala">// Kotlin JS version 1.1.4-3


class C {
class C {
Line 364: Line 364:
val f = "c.foo"
val f = "c.foo"
js(f)() // invokes c.foo dynamically
js(f)() // invokes c.foo dynamically
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 372: Line 372:


=={{header|Lasso}}==
=={{header|Lasso}}==
<lang Lasso>define mytype => type {
<syntaxhighlight lang="lasso">define mytype => type {
public foo() => {
public foo() => {
return 'foo was called'
return 'foo was called'
Line 382: Line 382:
local(obj = mytype, methodname = tag('foo'), methodname2 = tag('bar'))
local(obj = mytype, methodname = tag('foo'), methodname2 = tag('bar'))
#obj->\#methodname->invoke
#obj->\#methodname->invoke
#obj->\#methodname2->invoke</lang>
#obj->\#methodname2->invoke</syntaxhighlight>
{{out}}
{{out}}
<pre>foo was called
<pre>foo was called
Line 388: Line 388:


=={{header|Lingo}}==
=={{header|Lingo}}==
<lang lingo>obj = script("MyClass").new()
<syntaxhighlight lang="lingo">obj = script("MyClass").new()
-- ...
-- ...
method = #foo
method = #foo
arg1 = 23
arg1 = 23
res = call(method, obj, arg1)</lang>
res = call(method, obj, arg1)</syntaxhighlight>


=={{header|Logtalk}}==
=={{header|Logtalk}}==
For this task, we first define a simple object with a single method:
For this task, we first define a simple object with a single method:
<lang logtalk>:- object(foo).
<syntaxhighlight lang="logtalk">:- object(foo).


:- public(bar/1).
:- public(bar/1).
bar(42).
bar(42).


:- end_object.</lang>Second, we define another object that asks the user for a message to be sent to the first object:<lang logtalk>
:- end_object.</syntaxhighlight>Second, we define another object that asks the user for a message to be sent to the first object:<syntaxhighlight lang="logtalk">
:- object(query_foo).
:- object(query_foo).


Line 412: Line 412:
write(Message), nl.
write(Message), nl.


:- end_object.</lang>After compiling and loading both objects, we can try:
:- end_object.</syntaxhighlight>After compiling and loading both objects, we can try:
| ?- query_foo::query.
| ?- query_foo::query.
Message: bar(X).
Message: bar(X).
Line 419: Line 419:
=={{header|Lua}}==
=={{header|Lua}}==
Don't forget to pass the object for methods!
Don't forget to pass the object for methods!
<lang lua>local example = { }
<syntaxhighlight lang="lua">local example = { }
function example:foo (x) return 42 + x end
function example:foo (x) return 42 + x end


local name = "foo"
local name = "foo"
example[name](example, 5) --> 47</lang>
example[name](example, 5) --> 47</syntaxhighlight>


=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{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.
Creates a dialog box where one can type a function (Sin, Cos, Tan ...) and then a second dialog box for a value.
<lang>ToExpression[Input["function? E.g. Sin",]][Input["value? E.g. 0.4123"]]</lang>
<syntaxhighlight lang="text">ToExpression[Input["function? E.g. Sin",]][Input["value? E.g. 0.4123"]]</syntaxhighlight>
{{out}}
{{out}}
<pre>Input: Sin
<pre>Input: Sin
Line 436: Line 436:




<syntaxhighlight lang="matlab">
<lang Matlab>
funName = 'foo'; % generate function name
funName = 'foo'; % generate function name
feval (funNAME, ...) % evaluation function with optional parameters
feval (funNAME, ...) % evaluation function with optional parameters
Line 442: Line 442:
funName = 'a=atan(pi)'; % generate function name
funName = 'a=atan(pi)'; % generate function name
eval (funName, 'printf(''Error\n'')')
eval (funName, 'printf(''Error\n'')')
</syntaxhighlight>
</lang>


=={{header|Objective-C}}==
=={{header|Objective-C}}==
<lang objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>


@interface Example : NSObject
@interface Example : NSObject
Line 466: Line 466:
}
}
return 0;
return 0;
}</lang>
}</syntaxhighlight>
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.
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 472: Line 472:


A method object can be retrieved from its name using asMethod.
A method object can be retrieved from its name using asMethod.
<lang Oforth>16 "sqrt" asMethod perform</lang>
<syntaxhighlight lang="oforth">16 "sqrt" asMethod perform</syntaxhighlight>
Others :
Others :
Line 480: Line 480:


A generic way to search a word into the dictionary in to use find method :
A generic way to search a word into the dictionary in to use find method :
<lang Oforth>16 "sqrt" Word find perform</lang>
<syntaxhighlight lang="oforth">16 "sqrt" Word find perform</syntaxhighlight>


=={{header|PARI/GP}}==
=={{header|PARI/GP}}==
<lang parigp>foo()=5;
<syntaxhighlight lang="parigp">foo()=5;
eval(Str("foo","()"))</lang>
eval(Str("foo","()"))</syntaxhighlight>


=={{header|Perl}}==
=={{header|Perl}}==
<lang perl>package Example;
<syntaxhighlight lang="perl">package Example;
sub new {
sub new {
bless {}
bless {}
Line 498: Line 498:
package main;
package main;
my $name = "foo";
my $name = "foo";
print Example->new->$name(5), "\n"; # prints "47"</lang>
print Example->new->$name(5), "\n"; # prints "47"</syntaxhighlight>


=={{header|Phix}}==
=={{header|Phix}}==
Not specifically anything to do with objects, but you can construct routine names at runtime:
Not specifically anything to do with objects, but you can construct routine names at runtime:
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">Hello</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">Hello</span><span style="color: #0000FF;">()</span>
Line 514: Line 514:
<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>
<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>
<!--</lang>-->
<!--</syntaxhighlight>-->


=={{header|PHP}}==
=={{header|PHP}}==
<lang php><?php
<syntaxhighlight lang="php"><?php
class Example {
class Example {
function foo($x) {
function foo($x) {
Line 531: Line 531:
// alternately:
// alternately:
echo call_user_func(array($example, $name), 5), "\n";
echo call_user_func(array($example, $name), 5), "\n";
?></lang>
?></syntaxhighlight>


=={{header|Picat}}==
=={{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>.
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>.
<lang Picat>go =>
<syntaxhighlight lang="picat">go =>
println("Function: Use apply/n"),
println("Function: Use apply/n"),
Fun = "fib",
Fun = "fib",
Line 562: Line 562:
% A predicate
% A predicate
pyth(X,Y,Z) =>
pyth(X,Y,Z) =>
Z = X**2 + Y**2.</lang>
Z = X**2 + Y**2.</syntaxhighlight>


{{out}}
{{out}}
Line 574: Line 574:
=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
This can be done with the '[http://software-lab.de/doc/refS.html#send send]' function.
This can be done with the '[http://software-lab.de/doc/refS.html#send send]' function.
<lang PicoLisp>(send (expression) Obj arg1 arg2)</lang>
<syntaxhighlight lang="picolisp">(send (expression) Obj arg1 arg2)</syntaxhighlight>


=={{header|Pike}}==
=={{header|Pike}}==
with [] instead of -> a string can be used to name a method:
with [] instead of -> a string can be used to name a method:
<lang Pike>string unknown = "format_nice";
<syntaxhighlight lang="pike">string unknown = "format_nice";
object now = Calendar.now();
object now = Calendar.now();
now[unknown]();</lang>
now[unknown]();</syntaxhighlight>


=={{header|PowerShell}}==
=={{header|PowerShell}}==
A random method using a random number:
A random method using a random number:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$method = ([Math] | Get-Member -MemberType Method -Static | Where-Object {$_.Definition.Split(',').Count -eq 1} | Get-Random).Name
$method = ([Math] | Get-Member -MemberType Method -Static | Where-Object {$_.Definition.Split(',').Count -eq 1} | Get-Random).Name
$number = (1..9 | Get-Random) / 10
$number = (1..9 | Get-Random) / 10
Line 595: Line 595:


$output | Format-List
$output | Format-List
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 605: Line 605:
=={{header|Python}}==
=={{header|Python}}==
String literal "foo" may be replaced by any expression resulting in a string
String literal "foo" may be replaced by any expression resulting in a string
<lang python>class Example(object):
<syntaxhighlight lang="python">class Example(object):
def foo(self, x):
def foo(self, x):
return 42 + x
return 42 + x


name = "foo"
name = "foo"
getattr(Example(), name)(5) # => 47</lang>
getattr(Example(), name)(5) # => 47</syntaxhighlight>


=={{header|Qi}}==
=={{header|Qi}}==
<syntaxhighlight lang="qi">
<lang qi>
(define foo -> 5)
(define foo -> 5)


Line 620: Line 620:


(execute-function "foo")
(execute-function "foo")
</syntaxhighlight>
</lang>


=={{header|Racket}}==
=={{header|Racket}}==
<lang racket>
<syntaxhighlight lang="racket">
#lang racket
#lang racket
(define greeter
(define greeter
Line 636: Line 636:
(define unknown 'hello)
(define unknown 'hello)
(dynamic-send greeter unknown "World")
(dynamic-send greeter unknown "World")
</syntaxhighlight>
</lang>


=={{header|Raku}}==
=={{header|Raku}}==
(formerly Perl 6)
(formerly Perl 6)
Just for the fun of it, we'll mix in an anonymous role into an integer instead of defining a class.
Just for the fun of it, we'll mix in an anonymous role into an integer instead of defining a class.
<lang perl6>my $object = 42 but role { method add-me($x) { self + $x } }
<syntaxhighlight lang="raku" line>my $object = 42 but role { method add-me($x) { self + $x } }
my $name = 'add-me';
my $name = 'add-me';
say $object."$name"(5); # 47</lang>
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.
The double quotes are required, by the way; without them the variable would be interpreted as a hard ref to a method.


Line 649: Line 649:
You may replace :foo, :bar or "bar" with any expression that returns a Symbol or String.
You may replace :foo, :bar or "bar" with any expression that returns a Symbol or String.


<lang ruby>class Example
<syntaxhighlight lang="ruby">class Example
def foo
def foo
42
42
Line 662: Line 662:
Example.new.send( :bar, 1, 2 ) { |x,y| x+y } # => 3
Example.new.send( :bar, 1, 2 ) { |x,y| x+y } # => 3
args = [1, 2]
args = [1, 2]
Example.new.send( "bar", *args ) { |x,y| x+y } # => 3</lang>
Example.new.send( "bar", *args ) { |x,y| x+y } # => 3</syntaxhighlight>


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.
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}}
{{works with|Ruby|1.9}}
<lang ruby>class Example
<syntaxhighlight lang="ruby">class Example
private
private
def privacy; "secret"; end
def privacy; "secret"; end
Line 677: Line 677:
e.public_send :publicity # => "hi"
e.public_send :publicity # => "hi"
e.public_send :privacy # raises NoMethodError
e.public_send :privacy # raises NoMethodError
e.send :privacy # => "secret"</lang>
e.send :privacy # => "secret"</syntaxhighlight>


=={{header|Scala}}==
=={{header|Scala}}==
{{libheader|Scala}}<lang scala>class Example {
{{libheader|Scala}}<syntaxhighlight lang="scala">class Example {
def foo(x: Int): Int = 42 + x
def foo(x: Int): Int = 42 + x
}
}
Line 691: Line 691:
assert(meth.invoke(example, 5.asInstanceOf[AnyRef]) == 47.asInstanceOf[AnyRef], "Not confirm expectation.")
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]")
println(s"Successfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart} ms]")
}</lang>
}</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==
<lang ruby>class Example {
<syntaxhighlight lang="ruby">class Example {
method foo(x) {
method foo(x) {
42 + x
42 + x
Line 704: Line 704:


say obj.(name)(5) # prints: 47
say obj.(name)(5) # prints: 47
say obj.method(name)(5) # =//=</lang>
say obj.method(name)(5) # =//=</syntaxhighlight>


=={{header|Smalltalk}}==
=={{header|Smalltalk}}==
<lang smalltalk>Object subclass: #Example.
<syntaxhighlight lang="smalltalk">Object subclass: #Example.


Example extend [
Example extend [
Line 715: Line 715:
symbol := 'foo:' asSymbol. " same as symbol := #foo: "
symbol := 'foo:' asSymbol. " same as symbol := #foo: "


Example new perform: symbol with: 5. " returns 47 "</lang>
Example new perform: symbol with: 5. " returns 47 "</syntaxhighlight>
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.
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.


Line 727: Line 727:
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.
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.


<lang swift>import Foundation
<syntaxhighlight lang="swift">import Foundation


class MyUglyClass: NSObject {
class MyUglyClass: NSObject {
Line 738: Line 738:
let someObject: NSObject = MyUglyClass()
let someObject: NSObject = MyUglyClass()


someObject.perform(NSSelectorFromString("myUglyFunction"))</lang>
someObject.perform(NSSelectorFromString("myUglyFunction"))</syntaxhighlight>


{{out}}
{{out}}
Line 748: Line 748:
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.
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.


<lang swift>@dynamicCallable
<syntaxhighlight lang="swift">@dynamicCallable
protocol FunDynamics {
protocol FunDynamics {
var parent: MyDynamicThing { get }
var parent: MyDynamicThing { get }
Line 832: Line 832:
.subtract(adding: 10, subtracting: 14)
.subtract(adding: 10, subtracting: 14)


print(thing.n)</lang>
print(thing.n)</syntaxhighlight>


{{out}}
{{out}}
Line 840: Line 840:
=={{header|Tcl}}==
=={{header|Tcl}}==
Method names are really just strings, i.e., ordinary values that can be produced by any mechanism:
Method names are really just strings, i.e., ordinary values that can be produced by any mechanism:
<lang tcl>package require Tcl 8.6
<syntaxhighlight lang="tcl">package require Tcl 8.6
oo::class create Example {
oo::class create Example {
method foo {} {return 42}
method foo {} {return 42}
Line 853: Line 853:
for {set i 1} {$i <= 4} {incr i} {
for {set i 1} {$i <= 4} {incr i} {
$eg $i ...
$eg $i ...
}</lang>
}</syntaxhighlight>
{{out|The above produces this output}}
{{out|The above produces this output}}
42
42
Line 862: Line 862:


=={{header|Wren}}==
=={{header|Wren}}==
<lang ecmascript>import "meta" for Meta
<syntaxhighlight lang="ecmascript">import "meta" for Meta
class Test {
class Test {
Line 875: Line 875:
for (method in ["foo", "bar"]) {
for (method in ["foo", "bar"]) {
Meta.eval("test.%(method)()")
Meta.eval("test.%(method)()")
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 884: Line 884:


=={{header|zkl}}==
=={{header|zkl}}==
<lang zkl>name:="len"; "this is a test".resolve(name)() //-->14</lang>
<syntaxhighlight lang="zkl">name:="len"; "this is a test".resolve(name)() //-->14</syntaxhighlight>


{{omit from|Ada}}
{{omit from|Ada}}

Revision as of 13:44, 28 August 2022

Task
Send an unknown method call
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Invoke an object method where the name of the method to be invoked can be generated at run time.


Related tasks



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.

obj := {mA: Func("mA"), mB: Func("mB"), mC: Func("mC")}
InputBox, methodToCall, , Which method should I call?
obj[methodToCall].()

mA(){
 MsgBox Method A
}
mB(){
 MsgBox Method B
}
mC(){
 MsgBox Method C
}

Bracmat

(task=
  ( oracle
  =   (predicate="is made of green cheese")
      (generateTruth=.str$(!arg " " !(its.predicate) "."))
      (generateLie=.str$(!arg " " !(its.predicate) "!"))
  )
& new$oracle:?SourceOfKnowledge
&   put
  $ "You may ask the Source of Eternal Wisdom ONE thing.
Enter \"Truth\" or \"Lie\" on the next line and press the <Enter> key.
"
&   whl
  ' ( get':?trueorlie:~Truth:~Lie
    & put$"Try again\n"
    )
& put$(str$("You want a " !trueorlie ". About what?" \n))
& get'(,STR):?something
& (SourceOfKnowledge..str$(generate !trueorlie))$!something
);
Example:
{?} !task
You may ask the Source of Eternal Wisdom ONE thing.
Enter "Truth" or "Lie" on the next line and press the <Enter> key.
"Lie"
You want a Lie. About what?
The sea
{!} The sea is made of green cheese!

C#

using System;

class Example
{
    public int foo(int x)
    {
        return 42 + x;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var example = new Example();
        var method = "foo";
        
        var result = (int)example.GetType().GetMethod(method).Invoke(example, new object[]{ 5 });
        Console.WriteLine("{0}(5) = {1}", method, result);
    }
}
Output:
 foo(5) = 47

Caché ObjectScript

$METHOD executes a named instance method for a specified instance of a designated class.

Class Unknown.Example Extends %RegisteredObject
{

Method Foo()
{
	Write "This is foo", !
}

Method Bar()
{
	Write "This is bar", !
}

}
Examples:
USER>Set obj=##class(Unknown.Example).%New()
USER>Do $Method(obj, "Foo")
This is foo
USER>Do $Method(obj, "Bar")
This is bar


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))

Common Lisp

Unknown methods are called just like any other function. Find the method-naming symbol using INTERN then call it with FUNCALL.

(funcall (intern "SOME-METHOD") my-object a few arguments)

Déjà Vu

local :object { :add @+ }
local :method :add

!. object! method 1 2
Output:
3

E

This example goes well with the object named example in Respond to an unknown method call#E.

for name in ["foo", "bar"] {
    E.call(example, name, [])
}

Elena

ELENA 4.1 :

import extensions;
 
class Example
{
    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)
}
Output:
foo(5) = 47

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.

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
"add" "5" append      ! construct a word name
                      ! must specify vocab to look up a word
"rosetta-code.unknown-method-call"
lookup-word execute . ! 47

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

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.
\ This is equivalent to sending the !: message to object x
42 x  s" !:"  evaluate  

x p: 42     \ send the print message ( p: ) to x to verify the contents

Go

package main

import (
    "fmt"
    "reflect"
)

type example struct{}

// the method must be exported to be accessed through reflection.
func (example) Foo() int {
    return 42
}

func main() {
    // create an object with a method
    var e example
    // get the method by name
    m := reflect.ValueOf(e).MethodByName("Foo")
    // call the method with no argments
    r := m.Call(nil)
    // interpret first return value as int
    fmt.Println(r[0].Int()) // => 42
}

Groovy

class Example {
    def foo(value) {
        "Invoked with '$value'"
    }
}

def example = new Example()
def method = "foo"
def arg = "test value"

assert "Invoked with 'test value'" == example."$method"(arg)

Icon and Unicon

procedure main()
   x := foo()    # create object
   x.m1()        # static call of m1 method
   #  two examples where the method string can be dynamically constructed ...
   "foo_m1"(x)   # ... need to know class name and method name to construct name
   x.__m["m1"]   # ... general method (better)
end

class foo(a,b,c) # define object
method m1(x)
end
end

For more information on this see Respond to an unknown method call.

Io

String literal "foo" may be replaced by any expression resulting in a string.

Example := Object clone
Example foo := method(x, 42+x)

name := "foo"
Example clone perform(name,5) println  // prints "47"

J

Solution: There are multiple ways to evoke code at runtime. The most common is ". y (evaluate the code in the string y, producing a noun), but there's also 'name'~ (which will modify J's stack by replacing the two tokens 'name' and ~ with the named object) as well as x 128!:2 y (apply the verb described by x to the noun y).

There are other methods as well, e.g., @.,`:, and ^:, 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:

   sum =: +/
   prod =: */
   count =: #

   nameToDispatch =: 'sum'    NB. pick a name already defined

   ". nameToDispatch,' 1 2 3'
6
   nameToDispatch~ 1 2 3
6
   nameToDispatch (128!:2) 1 2 3
6

   nameToDispatch =: 'count'  NB. pick another name

   ". nameToDispatch,' 1 2 3'
3
   nameToDispatch~ 1 2 3
3
   nameToDispatch (128!:2) 1 2 3
3

Java

Using reflection

import java.lang.reflect.Method;

class Example {
  public int foo(int x) {
    return 42 + x;
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    Object example = new Example();
    String name = "foo";
    Class<?> clazz = example.getClass();
    Method meth = clazz.getMethod(name, int.class);
    Object result = meth.invoke(example, 5); // result is int wrapped in an object (Integer)
    System.out.println(result);        // prints "47"
  }
}

JavaScript

String literal "foo" may be replaced by any expression resulting in a string

example = new Object;
example.foo = function(x) {
    return 42 + x;
};

name = "foo";
example[name](5)      # => 47

Julia

Works with: Julia version 0.6
const functions = Dict{String,Function}(
    "foo" => x -> 42 + x,
    "bar" => x -> 42 * x)

@show functions["foo"](3)
@show functions["bar"](3)
Output:
(functions["foo"])(3) = 45
(functions["bar"])(3) = 126

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.

// 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
}
Output:
foo called 

Lasso

define mytype => type {
	public foo() => {
		return 'foo was called'
	}
	public bar() => {
		return 'this time is was bar'
	}
}
local(obj = mytype, methodname = tag('foo'), methodname2 = tag('bar'))
#obj->\#methodname->invoke
#obj->\#methodname2->invoke
Output:
foo was called
this time is was bar

Lingo

obj = script("MyClass").new()
-- ...
method = #foo
arg1 = 23
res = call(method, obj, arg1)

Logtalk

For this task, we first define a simple object with a single method:

:- object(foo).

	:- public(bar/1).
	bar(42).

:- end_object.

Second, we define another object that asks the user for a message to be sent to the first object:

:- object(query_foo).

	:- public(query/0).
	query :-
		write('Message: '),
		read(Message),
		foo::Message.
		write('Reply: '),
		write(Message), nl.

:- end_object.

After compiling and loading both objects, we can try:

| ?- query_foo::query.
Message: bar(X).
Reply: bar(42)

Lua

Don't forget to pass the object for methods!

local example = { }
function example:foo (x) return 42 + x end

local name = "foo"
example[name](example, 5) --> 47

Mathematica/Wolfram Language

Creates a dialog box where one can type a function (Sin, Cos, Tan ...) and then a second dialog box for a value.

ToExpression[Input["function? E.g. Sin",]][Input["value? E.g. 0.4123"]]
Output:
Input: Sin
Input: 3.1415
Output: 0.0000926536

MATLAB / Octave

  funName = 'foo';   % generate function name
  feval (funNAME, ...)  % evaluation function with optional parameters

  funName = 'a=atan(pi)';   % generate function name
  eval (funName, 'printf(''Error\n'')')

Objective-C

#import <Foundation/Foundation.h>

@interface Example : NSObject
- (NSNumber *)foo;
@end

@implementation Example
- (NSNumber *)foo {
  return @42;
}
@end

int main (int argc, const char *argv[]) {
  @autoreleasepool {

    id example = [[Example alloc] init];
    SEL selector = @selector(foo); // or = NSSelectorFromString(@"foo");
    NSLog(@"%@", [example performSelector:selector]);
  
  }
  return 0;
}

The performSelector: ... methods can only be used with methods with 0 - 2 object arguments, and an object or void return type. For all other calls, one can create an NSInvocation object and invoke it, or directly call one of the objc_msgSend family of runtime functions.

Oforth

A method object can be retrieved from its name using asMethod.

16 "sqrt" asMethod perform

Others :

  asFuntion  : retrieve a function
  asClass    : retrieve a class
  asProperty : retrieve a property

A generic way to search a word into the dictionary in to use find method :

16 "sqrt" Word find perform

PARI/GP

foo()=5;
eval(Str("foo","()"))

Perl

package Example;
sub new {
    bless {}
}
sub foo {
    my ($self, $x) = @_;
    return 42 + $x;
}

package main;
my $name = "foo";
print Example->new->$name(5), "\n"; # prints "47"

Phix

Not specifically anything to do with objects, but you can construct routine names at runtime:

with javascript_semantics
procedure Hello()
    ?"Hello"
end procedure
 
string erm = "Hemmm"
for i=3 to 5 do
    erm[i]+=-1+(i=5)*3
end for
 
call_proc(routine_id(erm),{})

PHP

<?php
class Example {
  function foo($x) {
    return 42 + $x;
  }
}

$example = new Example();

$name = 'foo';
echo $example->$name(5), "\n";        // prints "47"

// alternately:
echo call_user_func(array($example, $name), 5), "\n";
?>

Picat

For functions use apply/n and for predicates call/n. The name of the function/predicate must be an atom and strings must be converted to atom, e.g. with to_atom/1.

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.
Output:
Function: Use apply/n
55

Predicate: use call/n
z = 25
z2 = 365

PicoLisp

This can be done with the 'send' function.

(send (expression) Obj arg1 arg2)

Pike

with [] instead of -> a string can be used to name a method:

string unknown = "format_nice";
object now = Calendar.now();
now[unknown]();

PowerShell

A random method using a random number:

$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
Output:
Method : Atan
Number : 0.5
Result : 0.463647609000806

Python

String literal "foo" may be replaced by any expression resulting in a string

class Example(object):
     def foo(self, x):
             return 42 + x

name = "foo"
getattr(Example(), name)(5)      # => 47

Qi

(define foo -> 5)

(define execute-function
  Name -> (eval [(INTERN Name)]))

(execute-function "foo")

Racket

#lang racket 
(define greeter
  (new (class object% (super-new)
         (define/public (hello name)
           (displayln (~a "Hello " name "."))))))

; normal method call
(send greeter hello "World")

; sending an unknown method
(define unknown 'hello)
(dynamic-send greeter unknown "World")

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.

my $object = 42 but role { method add-me($x) { self + $x } }
my $name = 'add-me';
say $object."$name"(5);  # 47

The double quotes are required, by the way; without them the variable would be interpreted as a hard ref to a method.

Ruby

You may replace :foo, :bar or "bar" with any expression that returns a Symbol or String.

class Example
  def foo
    42
  end
  def bar(arg1, arg2, &block)
    block.call arg1, arg2
  end
end

symbol = :foo
Example.new.send symbol                         # => 42
Example.new.send( :bar, 1, 2 ) { |x,y| x+y }    # => 3
args = [1, 2]
Example.new.send( "bar", *args ) { |x,y| x+y }  # => 3

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 version 1.9
class Example
  private
  def privacy; "secret"; end
  public
  def publicity; "hi"; end
end

e = Example.new
e.public_send :publicity  # => "hi"
e.public_send :privacy    # raises NoMethodError
e.send :privacy           # => "secret"

Scala

Library: Scala
class Example {
  def foo(x: Int): Int = 42 + x
}

object Main extends App {
  val example = new Example

  val meth = example.getClass.getMethod("foo", classOf[Int])

  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]")
}

Sidef

class Example {
    method foo(x) {
        42 + x
    }
}

var name = 'foo'
var obj = Example()

say obj.(name)(5)          # prints: 47
say obj.method(name)(5)    # =//=

Smalltalk

Object subclass: #Example.

Example extend [
  foo: x [
    ^ 42 + x ] ].

symbol := 'foo:' asSymbol. " same as symbol := #foo: "

Example new perform: symbol with: 5. " returns 47 "

The perform:with:with: family of methods exist for methods with 0 - 2 (3 in GNU Smalltalk) arguments. For methods with more arguments, use perform:withArguments:, which takes an array of arguments.


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.

import Foundation

class MyUglyClass: NSObject {
  @objc
  func myUglyFunction() {
    print("called myUglyFunction")
  }
}

let someObject: NSObject = MyUglyClass()

someObject.perform(NSSelectorFromString("myUglyFunction"))
Output:
called myUglyFunction

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 @dynamicCallable and @dynamicMemberLookup attributes which allow for runtime handling of method calls.

@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)
Output:
16

Tcl

Method names are really just strings, i.e., ordinary values that can be produced by any mechanism:

package require Tcl 8.6
oo::class create Example {
    method foo {} {return 42}
    method 1 {s} {puts "fee$s"}
    method 2 {s} {puts "fie$s"}
    method 3 {s} {puts "foe$s"}
    method 4 {s} {puts "fum$s"}
}
set eg [Example new]
set mthd [format "%c%c%c" 102 111 111];    # A "foo" by any other means would smell as sweet
puts [$eg $mthd]
for {set i 1} {$i <= 4} {incr i} {
    $eg $i ...
}
The above produces this output:
42
fee...
fie...
foe...
fum...

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)()")
}
Output:
Foo called.
Bar called.

zkl

name:="len"; "this is a test".resolve(name)() //-->14