Respond to an unknown method call: Difference between revisions

From Rosetta Code
Content added Content deleted
(add E example)
(added ruby and perl)
Line 20: Line 20:
}
}
}</lang>
}</lang>

=={{header|Perl}}==
<lang perl>package Example;
sub new {
bless {}
}
sub foo {
print "this is foo\n";
}
sub bar {
print "this is bar\n";
}
sub AUTOLOAD {
my $name = $AUTOLOAD;
my ($self, @args) = @_;
print "tried to handle unknown method $name\n";
if (@args) {
print "it had arguments: @args\n";
}
}
1;

package main;
my $example = Example->new;

$example->foo; # prints “this is foo”
$example->bar; # prints “this is bar”
$example->grill; # prints “tried to handle unknown method Example::grill”
$example->ding("dong"); # prints “tried to handle unknown method Example::ding”
# prints “it had arguments: dong”
# prints “tried to handle unknown method Example::DESTROY” <- I don't know why it does this</lang>


=={{header|Python}}==
=={{header|Python}}==
Line 42: Line 73:
example.ding("dong") # prints “tried to handle unknown method ding”
example.ding("dong") # prints “tried to handle unknown method ding”
# prints “it had arguments: ('dong',)”</lang>
# prints “it had arguments: ('dong',)”</lang>

=={{header|Ruby}}==
<lang ruby>class Example
def foo
puts "this is foo"
end
def bar
puts "this is bar"
end
def method_missing(name, *args)
puts "tried to handle unknown method %s" % name # name is a symbol
unless args.empty?
puts "it had arguments: %p" % [args]
end
end
end

example = Example.new

example.foo # prints “this is foo”
example.bar # prints “this is bar”
example.grill # prints “tried to handle unknown method grill”
example.ding("dong") # prints “tried to handle unknown method ding”
# prints “it had arguments: ["dong"]”</lang>


=={{header|Tcl}}==
=={{header|Tcl}}==

Revision as of 07:27, 4 June 2009

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

Demonstrate how to make the object respond (sensibly/usefully) to an invocation of a method on it that it does not support through its class definitions. Note that this is not the same as just invoking a defined method whose name is given dynamically; the method named at the point of invocation must not be defined.

This task is intended only for object systems that use a dynamic dispatch mechanism.

E

In E, a message consists of a verb (arbitrary string) and arguments (sequence of arbitrary objects). It is conceptually entirely up to any given object how it dispatches incoming messages.

Practically, the object definition syntax provides a matcher clause to handle unrecognized messages. This example has the same behavior as the Python example.

<lang e>def example {

   to foo() { println("this is foo") }
   to bar() { println("this is bar") }
   match [verb, args] {
       println(`got unrecognized message $verb`)
       if (args.size() > 0) {
           println(`it had arguments: $args`)
       }
   }

}</lang>

Perl

<lang perl>package Example; sub new {

   bless {}

} sub foo {

   print "this is foo\n";

} sub bar {

   print "this is bar\n";

} sub AUTOLOAD {

   my $name = $AUTOLOAD;
   my ($self, @args) = @_;
   print "tried to handle unknown method $name\n";
   if (@args) {
       print "it had arguments: @args\n";
   }

} 1;

package main; my $example = Example->new;

$example->foo; # prints “this is foo” $example->bar; # prints “this is bar” $example->grill; # prints “tried to handle unknown method Example::grill” $example->ding("dong"); # prints “tried to handle unknown method Example::ding”

                       # prints “it had arguments: dong”
                       # prints “tried to handle unknown method Example::DESTROY” <- I don't know why it does this</lang>

Python

Python objects can implement a __getattr__() method to handle accesses of unknown attributes (methods are just attributes that are callable; so this function handles both methods and non-method fields). Here we assume that if you access an unknown attribute, you want a method, so we return a function that can be called. <lang python>class Example:

   def foo(self):
       print "this is foo"
   def bar(self):
       print "this is bar"
   def __getattr__(self, name):
       def method(*args):
           print "tried to handle unknown method " + name
           if args:
               print "it had arguments: " + str(args)
       return method

example = Example()

example.foo() # prints “this is foo” example.bar() # prints “this is bar” example.grill() # prints “tried to handle unknown method grill” example.ding("dong") # prints “tried to handle unknown method ding”

                    # prints “it had arguments: ('dong',)”</lang>

Ruby

<lang ruby>class Example

   def foo
       puts "this is foo"
   end
   def bar
       puts "this is bar"
   end
   def method_missing(name, *args)
       puts "tried to handle unknown method %s" % name # name is a symbol
       unless args.empty?
           puts "it had arguments: %p" % [args]
       end
   end

end

example = Example.new

example.foo # prints “this is foo” example.bar # prints “this is bar” example.grill # prints “tried to handle unknown method grill” example.ding("dong") # prints “tried to handle unknown method ding”

                    # prints “it had arguments: ["dong"]”</lang>

Tcl

Works with: Tcl version 8.6

<lang tcl># First create a simple, conventional class and object oo::class create Example {

   method foo {} {
       puts "this is foo"
   }
   method bar {} {
       puts "this is bar"
   }

} Example create example

  1. Modify the object to have a custom ‘unknown method’ interceptor

oo::objdefine example {

   method unknown {name args} {
       puts "tried to handle unknown method \"$name\""
       if {[llength $args]} {
           puts "it had arguments: $args"
       }
   }

}

  1. Show off what we can now do...

example foo; # prints “this is foo” example bar; # prints “this is bar” example grill; # prints “tried to handle unknown method "grill"” example ding dong; # prints “tried to handle unknown method "ding"”

                  # prints “it had arguments: dong”</lang>