Send an unknown method call: Difference between revisions
m (→{{header|Ruby}}: It uses "bar".) |
(Added PicoLisp) |
||
Line 76: | Line 76: | ||
echo call_user_func(array($example, $name), 5), "\n"; |
echo call_user_func(array($example, $name), 5), "\n"; |
||
?></lang> |
?></lang> |
||
=={{header|PicoLisp}}== |
|||
This can be done with the '[http://software-lab.de/doc/refS.html#send send]' function. |
|||
<lang PicoLisp>(send (expression) Obj arg1 arg2)</lang> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
Revision as of 10:02, 29 August 2011
Invoke an object method where the name of the method to be invoked can be generated at run time.
- Cf
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.
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
<lang perl6>$object."$methname"(5)</lang>
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>
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>
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...