Send an unknown method call: Difference between revisions
(lua again) |
(added Caché ObjectScript) |
||
Line 23: | Line 23: | ||
} |
} |
||
</lang> |
</lang> |
||
=={{header|Caché ObjectScript}}== |
|||
$METHOD executes a named instance method for a specified instance of a designated class. |
|||
<lang cos>Class Unknown.Example Extends %RegisteredObject |
|||
{ |
|||
Method Foo() |
|||
{ |
|||
Write "This is foo", ! |
|||
} |
|||
Method Bar() |
|||
{ |
|||
Write "This is bar", ! |
|||
} |
|||
}</lang> |
|||
{{out|Examples}} |
|||
<pre> |
|||
USER>Set obj=##class(Unknown.Example).%New() |
|||
USER>Do $Method(obj, "Foo") |
|||
This is foo |
|||
USER>Do $Method(obj, "Bar") |
|||
This is bar |
|||
</pre> |
|||
=={{header|E}}== |
=={{header|E}}== |
||
Revision as of 21:02, 11 May 2013
You are encouraged to solve this task according to the task description, using any language you may know.
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>
Caché ObjectScript
$METHOD executes a named instance method for a specified instance of a designated class.
<lang cos>Class Unknown.Example Extends %RegisteredObject {
Method Foo() { Write "This is foo", ! }
Method Bar() { Write "This is bar", ! }
}</lang>
- Examples:
USER>Set obj=##class(Unknown.Example).%New() USER>Do $Method(obj, "Foo") This is foo USER>Do $Method(obj, "Bar") This is bar
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>
Go
<lang 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
}</lang>
Icon and Unicon
<lang 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</lang>
For more information on this see Respond to an unknown method call.
Java
Using reflection <lang java>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" }
}</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>
Lua
Don't forget to pass the object for methods! <lang lua>local example = { } function example:foo (x) return 42 + x end
local name = "foo" example[name](example, 5) --> 47</lang>
MATLAB / Octave
<lang Matlab>
funName = 'foo'; % generate function name feval (funNAME, ...) % evaluation function with optional parameters
funName = 'a=atan(pi)'; % generate function name eval (funName, 'printf(Error\n)')
</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]); [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>
Pike
with [] instead of -> a string can be used to name a method: <lang Pike>string unknown = "format_nice"; object now = Calendar.now(); now[unknown]();</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...