Send an unknown method call
Invoke an object method where the name of the method to be invoked can be generated at run time.
- Cf
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. <lang AHK>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
} </lang>
E
This example goes well with the object named example
in Respond to an unknown method call#E.
<lang e>for name in ["foo", "bar"] {
E.call(example, name, [])
}</lang>
JavaScript
String literal "foo" may be replaced by any expression resulting in a string <lang javascript>example = new Object; example.foo = function(x) {
return 42 + x;
};
name = "foo"; example[name](5) # => 47</lang>
Objective-C
<lang objc>#import <Foundation/Foundation.h>
@interface Example : NSObject { } - (NSNumber *)foo; @end
@implementation Example - (NSNumber *)foo {
return [NSNumber numberWithInt:42];
} @end
int main (int argc, const char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id example = [[Example alloc] init]; SEL selector = @selector(foo); // or = NSSelectorFromString(@"foo"); NSLog(@"%@", [example performSelector:selector withObject:nil]); [example release]; [pool release]; return 0;
}</lang>
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.
PARI/GP
<lang parigp>foo()=5; eval(Str("foo","()"))</lang>
Perl
<lang 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"</lang>
Perl 6
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 } } my $name = 'add-me'; say $object."$name"(5); # 47</lang> The double quotes are required, by the way; without them the variable would be interpreted as a hard ref to a method.
PHP
<lang 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"; ?></lang>
PicoLisp
This can be done with the 'send' function. <lang PicoLisp>(send (expression) Obj arg1 arg2)</lang>
Python
String literal "foo" may be replaced by any expression resulting in a string <lang python>class Example(object):
def foo(self, x): return 42 + x
name = "foo" getattr(Example(), name)(5) # => 47</lang>
Qi
<lang qi> (define foo -> 5)
(define execute-function
Name -> (eval [(INTERN Name)]))
(execute-function "foo") </lang>
Ruby
You may replace :foo, :bar or "bar" with any expression that returns a Symbol or String.
<lang ruby>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</lang>
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.
<lang ruby>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"</lang>
Smalltalk
<lang 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 "</lang>
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.
Tcl
Method names are really just strings, i.e., ordinary values that can be produced by any mechanism: <lang tcl>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 ...
}</lang> The above produces this output:
42 fee... fie... foe... fum...