Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
3
Task/Respond-to-an-unknown-method-call/00-META.yaml
Normal file
3
Task/Respond-to-an-unknown-method-call/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Respond_to_an_unknown_method_call
|
||||
note: Object oriented
|
||||
12
Task/Respond-to-an-unknown-method-call/00-TASK.txt
Normal file
12
Task/Respond-to-an-unknown-method-call/00-TASK.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
;Task:
|
||||
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 without static checking.
|
||||
|
||||
|
||||
;Related task:
|
||||
* [[Send an unknown method call]].
|
||||
<br><br>
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
class example
|
||||
{
|
||||
foo()
|
||||
{
|
||||
Msgbox Called example.foo()
|
||||
}
|
||||
|
||||
__Call(method, params*)
|
||||
{
|
||||
funcRef := Func(funcName := this.__class "." method)
|
||||
if !IsObject(funcRef)
|
||||
{
|
||||
str := "Called undefined method " funcName "() with these parameters:"
|
||||
for k,v in params
|
||||
str .= "`n" v
|
||||
Msgbox %str%
|
||||
}
|
||||
else
|
||||
{
|
||||
return funcRef.(this, params*)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ex := new example
|
||||
ex.foo()
|
||||
ex.bar(1,2)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
example = object.new
|
||||
|
||||
example.no_method = { meth_name, *args |
|
||||
p "#{meth_name} was called with these arguments: #{args}"
|
||||
}
|
||||
|
||||
example.this_does_not_exist "at all" #Prints "this_does_not_exist was called with these arguments: [at all]"
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
class animal {
|
||||
public:
|
||||
virtual void bark() // concrete virtual, not pure
|
||||
{
|
||||
throw "implement me: do not know how to bark";
|
||||
}
|
||||
};
|
||||
|
||||
class elephant : public animal // does not implement bark()
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
elephant e;
|
||||
e.bark(); // throws exception
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Dynamic;
|
||||
|
||||
class Example : DynamicObject
|
||||
{
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
|
||||
{
|
||||
result = null;
|
||||
|
||||
Console.WriteLine("This is {0}.", binder.Name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
dynamic ex = new Example();
|
||||
|
||||
ex.Foo();
|
||||
ex.Bar();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
(defgeneric do-something (thing)
|
||||
(:documentation "Do something to thing."))
|
||||
|
||||
(defmethod no-applicable-method ((method (eql #'do-something)) &rest args)
|
||||
(format nil "No method for ~w on ~w." method args))
|
||||
|
||||
(defmethod do-something ((thing (eql 3)))
|
||||
(format nil "Do something to ~w." thing))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(list (do-something 3) (do-something 4))
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
("Do something to 3."
|
||||
"No method for #<STANDARD-GENERIC-FUNCTION DO-SOMETHING 214FC042> on (4).")
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import std.stdio;
|
||||
|
||||
struct Catcher {
|
||||
void foo() { writeln("This is foo"); }
|
||||
|
||||
void bar() { writeln("This is bar"); }
|
||||
|
||||
void opDispatch(string name, ArgsTypes...)(ArgsTypes args) {
|
||||
writef("Tried to handle unknown method '%s'", name);
|
||||
if (ArgsTypes.length) {
|
||||
write(", with arguments: ");
|
||||
foreach (arg; args)
|
||||
write(arg, " ");
|
||||
}
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
Catcher ca;
|
||||
ca.foo();
|
||||
ca.bar();
|
||||
ca.grill();
|
||||
ca.ding("dong", 11);
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
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`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import extensions;
|
||||
|
||||
class Example
|
||||
{
|
||||
generic()
|
||||
{
|
||||
// __received is an built-in variable containing the incoming message name
|
||||
console.printLine(__received," was invoked")
|
||||
}
|
||||
|
||||
generic(x)
|
||||
{
|
||||
console.printLine(__received,"(",x,") was invoked")
|
||||
}
|
||||
|
||||
generic(x,y)
|
||||
{
|
||||
console.printLine(__received,"(",x,",",y,") was invoked")
|
||||
}
|
||||
}
|
||||
|
||||
public program()
|
||||
{
|
||||
var o := new Example();
|
||||
|
||||
o.foo();
|
||||
o.bar(1);
|
||||
o.someMethod(1,2)
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
class CatchThemAll {
|
||||
def foo {
|
||||
"foo received" println
|
||||
}
|
||||
|
||||
def bar {
|
||||
"bar received" println
|
||||
}
|
||||
|
||||
def unknown_message: msg with_params: params {
|
||||
"message: " ++ msg print
|
||||
"arguments: " ++ (params join: ", ") println
|
||||
}
|
||||
}
|
||||
|
||||
a = CatchThemAll new
|
||||
a foo
|
||||
a bar
|
||||
a we_can_do_it
|
||||
a they_can_too: "eat" and: "walk"
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
class A
|
||||
{
|
||||
public Void doit (Int n)
|
||||
{
|
||||
echo ("known function called on $n")
|
||||
}
|
||||
|
||||
// override the 'trap' method, which catches dynamic invocations of methods
|
||||
override Obj? trap(Str name, Obj?[]? args := null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.trap(name, args)
|
||||
}
|
||||
catch (UnknownSlotErr err)
|
||||
{
|
||||
echo ("In trap, you called: " + name + " with args " + args.join(","))
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Main
|
||||
{
|
||||
public static Void main ()
|
||||
{
|
||||
a := A()
|
||||
// note the dynamic dispatch
|
||||
a->doit (1)
|
||||
a->methodName (1, 2, 3)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
include FMS-SI.f
|
||||
include FMS-SILib.f
|
||||
|
||||
var x \ instantiate a class var object named x
|
||||
x add: \ => "aborted: message not understood"
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type example struct{}
|
||||
|
||||
func (example) Foo() int {
|
||||
return 42
|
||||
}
|
||||
|
||||
// a method to call another method by name
|
||||
func (e example) CallMethod(n string) int {
|
||||
if m := reflect.ValueOf(e).MethodByName(n); m.IsValid() {
|
||||
// it's known. call it.
|
||||
return int(m.Call(nil)[0].Int())
|
||||
}
|
||||
// otherwise it's unknown. handle as needed.
|
||||
fmt.Println("Unknown method:", n)
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
var e example
|
||||
fmt.Println(e.CallMethod("Foo"))
|
||||
fmt.Println(e.CallMethod("Bar"))
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
class MyObject {
|
||||
def foo() {
|
||||
println 'Invoked foo'
|
||||
}
|
||||
def methodMissing(String name, args) {
|
||||
println "Invoked missing method $name$args"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
def o = new MyObject()
|
||||
o.foo()
|
||||
o.bar()
|
||||
o.bar(1, 2, 'Test')
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
procedure DynMethod(obj,meth,arglist[])
|
||||
local m
|
||||
|
||||
if not (type(obj) ? ( tab(find("__")), ="__state", pos(0))) then
|
||||
runerr(205,obj) # invalid value - not an object
|
||||
|
||||
if meth == ("initially"|"UndefinedMethod") then fail # avoid protected
|
||||
|
||||
m := obj.__m # get methods list
|
||||
if fieldnames(m) == meth then # method exists?
|
||||
return m[meth]!push(copy(arglist),obj) # ... call it
|
||||
else
|
||||
if fieldnames(m) == "UndefinedMethod" then # handler exists?
|
||||
return obj.UndefinedMethod!arglist # ... call it
|
||||
else runerr(207,obj) # error invalid method (i.e. field)
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
procedure main()
|
||||
x := foo()
|
||||
y := foo2()
|
||||
|
||||
x.a() # example of normal method call
|
||||
DynMethod(x,"a") # using DynMethod
|
||||
DynMethod(x,"simplydoesntexist") # results in error
|
||||
DynMethod(y,"simplydoesntexist") # catches error
|
||||
DynMethod(y,"simplydoesntexist",1,2,3,4,5) # with parameters
|
||||
end
|
||||
|
||||
class foo(A) # sample class and methods
|
||||
method a(p1)
|
||||
l1 := p1
|
||||
return
|
||||
end
|
||||
method b(p2)
|
||||
l2 := p2
|
||||
return
|
||||
end
|
||||
initially
|
||||
i1 := 0
|
||||
return
|
||||
end
|
||||
|
||||
class foo2 : foo (A)
|
||||
method UndefinedMethod(x[]) # Undefined Method handler
|
||||
write(&errout,"You called an undefinded method of this object.")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
Example := Object clone do(
|
||||
foo := method(writeln("this is foo"))
|
||||
bar := method(writeln("this is bar"))
|
||||
forward := method(
|
||||
writeln("tried to handle unknown method ",call message name)
|
||||
if( call hasArgs,
|
||||
writeln("it had arguments: ",call evalArgs)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
example := Example clone
|
||||
|
||||
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: list("dong")"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
example=:3 :0
|
||||
doSomething_z_=: assert&0 bind 'doSomething was not implemented'
|
||||
doSomething__y ''
|
||||
)
|
||||
|
||||
doSomething_adhoc1_=: smoutput bind 'hello world'
|
||||
dSomethingElse_adhoc2_=: smoutput bind 'hello world'
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
example <'adhoc1'
|
||||
hello world
|
||||
example<'adhoc2'
|
||||
|doSomething was not implemented: assert
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
obj = new Proxy({},
|
||||
{ get : function(target, prop)
|
||||
{
|
||||
if(target[prop] === undefined)
|
||||
return function() {
|
||||
console.log('an otherwise undefined function!!');
|
||||
};
|
||||
else
|
||||
return target[prop];
|
||||
}
|
||||
});
|
||||
obj.f() ///'an otherwise undefined function!!'
|
||||
obj.l = function() {console.log(45);};
|
||||
obj.l(); ///45
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
var example = new Object;
|
||||
example.foo = function () {
|
||||
alert("this is foo");
|
||||
}
|
||||
example.bar = function () {
|
||||
alert("this is bar");
|
||||
}
|
||||
example.__noSuchMethod__ = function (id, args) {
|
||||
alert("tried to handle unknown method " + id);
|
||||
if (args.length != 0)
|
||||
alert("it had arguments: " + args);
|
||||
}
|
||||
|
||||
example.foo(); // alerts "this is foo"
|
||||
example.bar(); // alerts "this is bar"
|
||||
example.grill(); // alerts "tried to handle unknown method grill"
|
||||
example.ding("dong"); // alerts "tried to handle unknown method ding"
|
||||
// alerts "it had arguments: dong
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
function add(a, b)
|
||||
try
|
||||
a + b
|
||||
catch
|
||||
println("caught exception")
|
||||
a * b
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
println(add(2, 6))
|
||||
println(add(1//2, 1//2))
|
||||
println(add("Hello ", "world"))
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// Kotlin JS version 1.2.0 (Firefox 43)
|
||||
|
||||
class C {
|
||||
// this method prevents a TypeError being thrown if an unknown method is called
|
||||
fun __noSuchMethod__(id: String, args: Array<Any>) {
|
||||
println("Class C does not have a method called $id")
|
||||
if (args.size > 0) println("which takes arguments: ${args.asList()}")
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val c: dynamic = C() // 'dynamic' turns off compile time checks
|
||||
c.foo() // the compiler now allows this call even though foo() is undefined
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
define exampletype => type {
|
||||
public foo() => {
|
||||
return 'this is foo\r'
|
||||
}
|
||||
public bar() => {
|
||||
return 'this is bar\r'
|
||||
}
|
||||
public _unknownTag(...) => {
|
||||
local(n = method_name->asString)
|
||||
return 'tried to handle unknown method called "'+#n+'"'+
|
||||
(#rest->size ? ' with args: "'+#rest->join(',')+'"')+'\r'
|
||||
}
|
||||
}
|
||||
|
||||
local(e = exampletype)
|
||||
|
||||
#e->foo()
|
||||
// outputs 'this is foo'
|
||||
|
||||
#e->bar()
|
||||
// outputs 'this is bar'
|
||||
|
||||
#e->stuff()
|
||||
// outputs 'tried to handle unknown method called "stuff"'
|
||||
|
||||
#e->dothis('here',12,'there','nowhere')
|
||||
// outputs 'tried to handle unknown method called "dothis" with args: "here,12,there,nowhere"'
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
:- object(foo).
|
||||
|
||||
:- public(try/0).
|
||||
try :-
|
||||
catch(bar::message, Error, handler(Error)).
|
||||
|
||||
handler(error(existence_error(predicate_declaration,message/0),_)) :-
|
||||
% handle the unknown message
|
||||
...
|
||||
|
||||
:- end_object.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
:- object(foo,
|
||||
implements(forwarding)).
|
||||
|
||||
forward(Message) :-
|
||||
% handle the unknown message
|
||||
...
|
||||
|
||||
:- end_object.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
local object={print=print}
|
||||
setmetatable(object,{__index=function(t,k)return function() print("You called the method",k)end end})
|
||||
object.print("Hi") -->Hi
|
||||
object.hello() -->You called the method hello
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
module checkit {
|
||||
|
||||
Class Alfa {
|
||||
k=1000
|
||||
module a (x, y) {
|
||||
Print x, y
|
||||
}
|
||||
module NoParam {
|
||||
Print "ok"
|
||||
}
|
||||
Function Sqr(x) {
|
||||
=Sqrt(x)
|
||||
}
|
||||
Function NoParam {
|
||||
=.k
|
||||
}
|
||||
Function Sqr$(x) {
|
||||
=Str$(Sqrt(x),1033) ' using locale 1033, no leading space for positive
|
||||
}
|
||||
}
|
||||
\\ modules, functions numeric and string, and variables can use same name
|
||||
\\ here we have module invoke, function invoke, and function invoke$
|
||||
Module invoke (&a, method$) {
|
||||
param=(,)
|
||||
Read ? param
|
||||
Function Check(&a, method$) {
|
||||
group b type "module "+method$+" {}"
|
||||
=valid(@a as b)
|
||||
}
|
||||
if check(&a, method$) then {
|
||||
for a {
|
||||
\\ we call this.methodname
|
||||
call "."+method$, !param
|
||||
}
|
||||
} else Flush : Error "unknown method "+method$ ' flush empty the stack
|
||||
}
|
||||
Function invoke (&a, method$) {
|
||||
\\ functions have own stack of values
|
||||
Function Check(&a, method$) {
|
||||
group b type "Function "+filter$(method$, "()")+" {}"
|
||||
=valid(@a as b)
|
||||
}
|
||||
if check(&a, method$) then {
|
||||
for a {
|
||||
=Function("."+method$, ![])
|
||||
}
|
||||
} else Error "unknown Function "+method$
|
||||
}
|
||||
\\ invoke string functions
|
||||
Function invoke$ (&a, method$) {
|
||||
\\ functions have own stack of values
|
||||
Function Check(&a, method$) {
|
||||
group b type "Function "+filter$(method$, "()")+" {}"
|
||||
=valid(@a as b)
|
||||
}
|
||||
if check(&a, method$) then {
|
||||
for a {
|
||||
\\ [] is a function which return current stack as a stack object, and pass to current stack a new stack object.
|
||||
=Function$("."+method$, ![])
|
||||
}
|
||||
} else Error "unknown Function "+method$
|
||||
}
|
||||
|
||||
Module obj.alfa {
|
||||
Flush 'empty stack
|
||||
Print "this is a fake module, is not part of obj"
|
||||
}
|
||||
Function obj.alfa {
|
||||
Print "this is a fake function, is not part of obj"
|
||||
}
|
||||
Obj=Alfa()
|
||||
\\ normal invoke, interpreter not know that this is an object method
|
||||
\\ this method has a weak reference to obj, so anytime we use This. or just dot, this weak reference make the real name to execute
|
||||
Obj.a 10,20
|
||||
\\ call the fake method (can't access object methods and properties), has empty weak reference to object
|
||||
obj.alfa 10, 20
|
||||
|
||||
\\ check before call using custom invoke
|
||||
\\ to check if a method (module) exist, we have to compare this object with other temporary object
|
||||
\\ we make one with the method name and empty definition, and then check if obj has anything this temp object has
|
||||
\\ arguments passed in a tuple (optional), so we didn't leave stack with unused items, if we have an unknown method.
|
||||
invoke &obj, "a", (10, 20)
|
||||
invoke &obj, "NoParam"
|
||||
\\ now with an unknown method, using alfa
|
||||
Try ok {
|
||||
invoke &obj, "Alfa", (10, 20)
|
||||
}
|
||||
If Error Then Print Error$
|
||||
\\ we can use invoke for functions
|
||||
Print Invoke(&obj, "Sqr()", 4), Invoke(&obj, "NoParam()")
|
||||
Print Invoke$(&obj, "Sqr$()",2)
|
||||
\ without custom invoke
|
||||
Print obj.Sqr(4), obj.Noparam(), obj.Sqr$(2)
|
||||
\\ so now we try to call Alfa() and Alfa$() (unknown functions)
|
||||
Try ok {
|
||||
Print Invoke(&obj, "Alfa()")
|
||||
}
|
||||
If Error Then Print Error$
|
||||
Try ok {
|
||||
Print Invoke$(&obj, "Alfa$()")
|
||||
}
|
||||
If Error Then Print Error$
|
||||
|
||||
|
||||
\\ so now lets copy obj to obj2
|
||||
\\ fake method didn't passed to new object
|
||||
obj2=obj
|
||||
Try ok {
|
||||
invoke &obj2, "alfa", (10, 20)
|
||||
}
|
||||
If Error Then Print Error$
|
||||
|
||||
p->obj2
|
||||
\\ if p is a pointer to named group we can pass it as is
|
||||
invoke &p, "a", (10, 20)
|
||||
\\ normal called
|
||||
p=>a 10,20
|
||||
|
||||
For p {
|
||||
invoke &this, "a", (10, 20)
|
||||
Try ok {
|
||||
invoke &this, "alfa", (10, 20)
|
||||
}
|
||||
If Error Then Print Error$
|
||||
}
|
||||
|
||||
p->(obj2) ' p point to a copy of obj2 (an unnamed group)
|
||||
For p {
|
||||
invoke &this, "a", (10, 20)
|
||||
\\ normal called
|
||||
p=>a 10, 20
|
||||
Try ok {
|
||||
invoke &this, "alfa", (10, 20)
|
||||
}
|
||||
If Error Then Print Error$
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
checkit
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
obj[foo] = "This is foo.";
|
||||
obj[bar] = "This is bar.";
|
||||
obj[f_Symbol] := "What is " <> SymbolName[f] <> "?";
|
||||
Print[obj@foo];
|
||||
Print[obj@bar];
|
||||
Print[obj@baz];
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{.experimental:"dotOperators".}
|
||||
from strutils import join
|
||||
|
||||
type Foo = object
|
||||
|
||||
proc qux(f:Foo) = echo "called qux"
|
||||
|
||||
#for nicer output
|
||||
func quoteStrings[T](x:T):string = (when T is string: "\"" & x & "\"" else: $x)
|
||||
|
||||
#dot operator catches all unmatched calls on Foo
|
||||
template `.()`(f:Foo,field:untyped,args:varargs[string,quoteStrings]):untyped =
|
||||
echo "tried to call method '" & astToStr(`field`) & (if `args`.len > 0: "' with args: " & args.join(", ") else: "'")
|
||||
|
||||
let f = Foo()
|
||||
f.bar()
|
||||
#f.bar #error: undeclared field
|
||||
f.baz("hi",5)
|
||||
f.qux()
|
||||
f.qux("nope")
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
unit MyObjDef;
|
||||
{$mode objfpc}{$h+}
|
||||
interface
|
||||
|
||||
uses
|
||||
SysUtils, Variants;
|
||||
|
||||
function MyObjCreate: Variant;
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
MyObjType: TInvokeableVariantType;
|
||||
|
||||
type
|
||||
TMyObjType = class(TInvokeableVariantType)
|
||||
procedure Clear(var V: TVarData); override;
|
||||
procedure Copy(var aDst: TVarData; const aSrc: TVarData; const Indir: Boolean); override;
|
||||
function GetProperty(var aDst: TVarData; const aData: TVarData; const aName: string): Boolean; override;
|
||||
end;
|
||||
|
||||
function MyObjCreate: Variant;
|
||||
begin
|
||||
Result := Unassigned;
|
||||
TVarData(Result).VType := MyObjType.VarType;
|
||||
end;
|
||||
|
||||
procedure TMyObjType.Clear(var V: TVarData);
|
||||
begin
|
||||
V.VType := varEmpty;
|
||||
end;
|
||||
|
||||
procedure TMyObjType.Copy(var aDst: TVarData; const aSrc: TVarData; const Indir: Boolean);
|
||||
begin
|
||||
VarClear(Variant(aDst));
|
||||
aDst := aSrc;
|
||||
end;
|
||||
|
||||
function TMyObjType.GetProperty(var aDst: TVarData; const aData: TVarData; const aName: string): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
case LowerCase(aName) of
|
||||
'bark': Variant(aDst) := 'WOF WOF!';
|
||||
'moo': Variant(aDst) := 'Mooo!';
|
||||
else
|
||||
Variant(aDst) := Format('Sorry, what is "%s"?', [aName]);
|
||||
end;
|
||||
end;
|
||||
|
||||
initialization
|
||||
MyObjType := TMyObjType.Create;
|
||||
finalization
|
||||
MyObjType.Free;
|
||||
end.
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
program Test;
|
||||
{$mode objfpc}{$h+}
|
||||
uses
|
||||
MyObjDef;
|
||||
|
||||
var
|
||||
MyObj: Variant;
|
||||
|
||||
begin
|
||||
MyObj := MyObjCreate;
|
||||
WriteLn(MyObj.Bark);
|
||||
WriteLn(MyObj.Moo);
|
||||
WriteLn(MyObj.Meow);
|
||||
end.
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
#include <Foundation/Foundation.h>
|
||||
|
||||
// The methods need to be declared somewhere
|
||||
@interface Dummy : NSObject
|
||||
- (void)grill;
|
||||
- (void)ding:(NSString *)s;
|
||||
@end
|
||||
|
||||
@interface Example : NSObject
|
||||
- (void)foo;
|
||||
- (void)bar;
|
||||
@end
|
||||
|
||||
@implementation Example
|
||||
- (void)foo {
|
||||
NSLog(@"this is foo");
|
||||
}
|
||||
|
||||
- (void)bar {
|
||||
NSLog(@"this is bar");
|
||||
}
|
||||
|
||||
- (void)forwardInvocation:(NSInvocation *)inv {
|
||||
NSLog(@"tried to handle unknown method %@", NSStringFromSelector([inv selector]));
|
||||
NSUInteger n = [[inv methodSignature] numberOfArguments];
|
||||
for (NSUInteger i = 0; i < n-2; i++) { // First two arguments are the object and selector.
|
||||
id __unsafe_unretained arg; // We assume that all arguments are objects.
|
||||
// getArguments: is type-agnostic and does not perform memory management,
|
||||
// therefore we must pass it a pointer to an unretained type
|
||||
[inv getArgument:&arg atIndex:i+2];
|
||||
NSLog(@"argument #%lu: %@", i, arg);
|
||||
}
|
||||
}
|
||||
|
||||
// forwardInvocation: does not work without methodSignatureForSelector:
|
||||
// The runtime uses the signature returned here to construct the invocation.
|
||||
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
|
||||
int numArgs = [[NSStringFromSelector(aSelector) componentsSeparatedByString:@":"] count] - 1;
|
||||
// we assume that all arguments are objects
|
||||
// The type encoding is "v@:@@@...", where "v" is the return type, void
|
||||
// "@" is the receiver, object type; ":" is the selector of the current method;
|
||||
// and each "@" after corresponds to an object argument
|
||||
return [NSMethodSignature signatureWithObjCTypes:
|
||||
[[@"v@:" stringByPaddingToLength:numArgs+3 withString:@"@" startingAtIndex:0] UTF8String]];
|
||||
}
|
||||
@end
|
||||
|
||||
int main()
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
id example = [[Example alloc] init];
|
||||
|
||||
[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 "argument #0: dong"
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
1 first
|
||||
[1:interpreter] ExRuntime : 1 does not understand method <#first>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
1 "first" asMethod perform
|
||||
[1:interpreter] ExRuntime : 1 does not understand method <#first>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
1 "unknow_method" asMethod perform
|
||||
[1:interpreter] ExRuntime : null does not understand method <#perform>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Object Class new: MyClass
|
||||
MyClass method: doesNotUnderstand(m)
|
||||
"Well, sorry, I don't understand " print m println ;
|
||||
|
||||
MyClass new first
|
||||
Well, sorry, I don't understand #first
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
u = .unknown~new
|
||||
u~foo(1, 2, 3)
|
||||
|
||||
::class unknown
|
||||
::method unknown
|
||||
use arg name, args
|
||||
say "Unknown method" name "invoked with arguments:" args~tostring('l',', ')
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
declare
|
||||
class Example
|
||||
meth init skip end
|
||||
|
||||
meth foo {System.showInfo foo} end
|
||||
|
||||
meth bar {System.showInfo bar} end
|
||||
|
||||
meth otherwise(Msg)
|
||||
{System.showInfo "Unknown method "#{Label Msg}}
|
||||
if {Width Msg} > 0 then
|
||||
{System.printInfo "Arguments: "}
|
||||
{System.show {Record.toListInd Msg}}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Object = {New Example init}
|
||||
in
|
||||
{Object foo}
|
||||
{Object bar}
|
||||
{Object grill}
|
||||
{Object ding(dong)}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
class Example {
|
||||
function foo() {
|
||||
echo "this is foo\n";
|
||||
}
|
||||
function bar() {
|
||||
echo "this is bar\n";
|
||||
}
|
||||
function __call($name, $args) {
|
||||
echo "tried to handle unknown method $name\n";
|
||||
if ($args)
|
||||
echo "it had arguments: ", implode(', ', $args), "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$example = new 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
|
||||
?>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package Example;
|
||||
sub new {
|
||||
bless {}
|
||||
}
|
||||
sub foo {
|
||||
print "this is foo\n";
|
||||
}
|
||||
sub bar {
|
||||
print "this is bar\n";
|
||||
}
|
||||
sub AUTOLOAD {
|
||||
my $name = $Example::AUTOLOAD;
|
||||
my ($self, @args) = @_;
|
||||
print "tried to handle unknown method $name\n";
|
||||
if (@args) {
|
||||
print "it had arguments: @args\n";
|
||||
}
|
||||
}
|
||||
sub DESTROY {} # dummy method to prevent AUTOLOAD from
|
||||
# being triggered when an Example is
|
||||
# destroyed
|
||||
|
||||
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"
|
||||
# and "it had arguments: dong"
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">enum</span> <span style="color: #000000;">METHODS</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">invoke</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">name</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">args</span><span style="color: #0000FF;">={})</span>
|
||||
<span style="color: #000080;font-style:italic;">--(this works on any class, for any function, with any number or type of parameters)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">mdict</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">[</span><span style="color: #000000;">METHODS</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">node</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">name</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mdict</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">call_func</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">getd_by_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mdict</span><span style="color: #0000FF;">),</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #008000;">"no such method"</span> <span style="color: #000080;font-style:italic;">-- or throw(), fatal(), etc</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">--class X: Xmethods emulates a vtable</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">Xmethods</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">()</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">exists</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #008000;">"exists"</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"exists"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"exists"</span><span style="color: #0000FF;">),</span><span style="color: #000000;">Xmethods</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">--class X: create new instances</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">newX</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">Xmethods</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">newX</span><span style="color: #0000FF;">()</span>
|
||||
|
||||
<span style="color: #0000FF;">?</span><span style="color: #000000;">invoke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"exists"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #0000FF;">?</span><span style="color: #000000;">invoke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"non_existent_method"</span><span style="color: #0000FF;">)</span>
|
||||
<!--
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
(redef send (Msg Obj . @)
|
||||
(or
|
||||
(pass try Msg Obj)
|
||||
(pass 'no-applicable-method> Obj Msg) ) )
|
||||
|
||||
(de no-applicable-method> (This Msg)
|
||||
(pack "No method for " Msg " on " This) )
|
||||
|
||||
(class +A)
|
||||
|
||||
(dm do-something> ()
|
||||
(pack "Do something to " This) )
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
: (object 'A '(+A))
|
||||
-> A
|
||||
: (object 'B '(+B))
|
||||
-> B
|
||||
: (list (send 'do-something> 'A) (send 'do-something> 'B))
|
||||
-> ("Do something to A" "No method for do-something> on B")
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
class CatchAll
|
||||
{
|
||||
mixed `->(string name)
|
||||
{
|
||||
return lambda(int arg){ write("you are calling %s(%d);\n", name, arg); };
|
||||
}
|
||||
}
|
||||
|
||||
> CatchAll()->hello(5);
|
||||
you are calling hello(5);
|
||||
> CatchAll()->something(99);
|
||||
you are calling something(99);
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
class Example(object):
|
||||
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',)”
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#lang racket
|
||||
|
||||
(require racket/class)
|
||||
|
||||
(define-syntax-rule (send~ obj method x ...)
|
||||
;; note: this is a naive macro, a real one should avoid evaluating `obj' and
|
||||
;; the `xs' more than once
|
||||
(with-handlers ([(λ(e) (and (exn:fail:object? e)
|
||||
;; only do this if there *is* an `unknown-method'
|
||||
(memq 'unknown-method (interface->method-names
|
||||
(object-interface o)))))
|
||||
(λ(e) (send obj unknown-method 'method x ...))])
|
||||
(send obj method x ...)))
|
||||
|
||||
(define foo%
|
||||
(class object%
|
||||
(define/public (foo x)
|
||||
(printf "foo: ~s\n" x))
|
||||
(define/public (unknown-method name . xs)
|
||||
(printf "Unknown method ~s: ~s\n" name xs))
|
||||
(super-new)))
|
||||
|
||||
(define o (new foo%))
|
||||
(send~ o foo 1) ; => foo: 1
|
||||
(send~ o whatever 1) ; Unknown method whatever: (1)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#lang swindle
|
||||
|
||||
(defgeneric (foo x))
|
||||
(defmethod (no-applicable-method [m (singleton foo)] xs)
|
||||
(echo "No method in" m "for" :w xs))
|
||||
(defmethod (foo [x <integer>]) (echo "It's an integer"))
|
||||
|
||||
(foo 1)
|
||||
;; => It's an integer
|
||||
|
||||
(foo "one")
|
||||
;; => No method in #<generic:foo> for "one"
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
class Farragut {
|
||||
method FALLBACK ($name, *@rest) {
|
||||
say "{self.WHAT.raku}: $name.tc() the @rest[], full speed ahead!";
|
||||
}
|
||||
}
|
||||
|
||||
class Sparrow is Farragut { }
|
||||
|
||||
Farragut.damn: 'torpedoes';
|
||||
Sparrow.hoist: <Jolly Roger mateys>;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
class L-Value {
|
||||
our $.value = 10;
|
||||
method FALLBACK($name, |c) is rw { $.value }
|
||||
}
|
||||
|
||||
my $l = L-Value.new;
|
||||
say $l.any-odd-name; # 10
|
||||
$l.some-other-name = 42;
|
||||
say $l.i-dont-know; # 42
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
load "stdlibcore.ring"
|
||||
|
||||
new test {
|
||||
anyMethodThatDoesNotExist() # Define and call the new method
|
||||
anyMethodThatDoesNotExist() # Call the new method
|
||||
}
|
||||
|
||||
class test
|
||||
func braceerror
|
||||
if substr(cCatchError,"Error (R3)")
|
||||
? "You are calling a method that doesn't exist!"
|
||||
aError = Split(cCatchError," ")
|
||||
cMethodName = aError[len(aError)]
|
||||
? "The Method Name: " + cMethodName
|
||||
AddMethod(self,cMethodName,func {
|
||||
? "Hello from the new method!"
|
||||
})
|
||||
? "We defined the new method!"
|
||||
call cMethodName()
|
||||
ok
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
class Example
|
||||
def foo
|
||||
puts "this is foo"
|
||||
end
|
||||
def bar
|
||||
puts "this is bar"
|
||||
end
|
||||
def method_missing(name, *args, &block)
|
||||
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"]”
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
class DynamicTest extends Dynamic
|
||||
{
|
||||
def foo()=println("this is foo")
|
||||
def bar()=println("this is bar")
|
||||
def applyDynamic(name: String)(args: Any*)={
|
||||
println("tried to handle unknown method "+name)
|
||||
if(!args.isEmpty)
|
||||
println(" it had arguments: "+args.mkString(","))
|
||||
}
|
||||
}
|
||||
|
||||
object DynamicTest {
|
||||
def main(args: Array[String]): Unit = {
|
||||
val d=new DynamicTest()
|
||||
d.foo()
|
||||
d.bar()
|
||||
d.grill()
|
||||
d.ding("dong")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
class Example {
|
||||
method foo {
|
||||
say "this is foo"
|
||||
}
|
||||
method bar {
|
||||
say "this is bar"
|
||||
}
|
||||
method AUTOLOAD(_, name, *args) {
|
||||
say ("tried to handle unknown method %s" % name);
|
||||
if (args.len > 0) {
|
||||
say ("it had arguments: %s" % args.join(', '));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var 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”
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
define: #shell &builder: [lobby newSubSpace].
|
||||
|
||||
_@shell didNotUnderstand: message at: position
|
||||
"Form a command string and execute it."
|
||||
[
|
||||
position > 0
|
||||
ifTrue: [resend]
|
||||
ifFalse:
|
||||
[([| :command |
|
||||
message selector isUnarySelector ifTrue:
|
||||
[command ; message selector.
|
||||
message optionals pairsDo:
|
||||
[| :key :value |
|
||||
command ; ' -' ; (key as: String) allButFirst allButLast ; ' ' ; (value as: String)]].
|
||||
message selector isKeywordSelector ifTrue:
|
||||
[| keywords args |
|
||||
keywords: ((message selector as: String) splitWith: $:).
|
||||
command ; keywords first.
|
||||
keywords size = 1 ifTrue: "Read a string or array of arguments."
|
||||
[args: message arguments second.
|
||||
(args is: String) ifTrue: [command ; ' ' ; args]
|
||||
ifFalse: [args do: [| :arg | command ; ' ' ; arg]]]]] writingAs: String)
|
||||
ifNil: [resend] ifNotNilDo: [| :cmd | [Platform run: cmd]]]
|
||||
].
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
slate[1]> shell ls: '*.image'.
|
||||
kernel.new.little.64.1244260494374694.image slate2.image
|
||||
net.image slate.image
|
||||
True
|
||||
slate[2]>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
Object subclass: CatchThemAll [
|
||||
foo [ 'foo received' displayNl ]
|
||||
|
||||
bar [ 'bar received' displayNl ]
|
||||
|
||||
doesNotUnderstand: aMessage [
|
||||
('message "' , (aMessage selector asString) , '"') displayNl.
|
||||
(aMessage arguments) do: [ :a |
|
||||
'argument: ' display. a printNl.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|a| a := CatchThemAll new.
|
||||
a foo.
|
||||
a bar.
|
||||
a weCanDoIt.
|
||||
a theyCanToo: 'eat' and: 'walk'.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[
|
||||
bla := someObject fooBar.
|
||||
foo := bla.
|
||||
] on: MessageNotUnderstood do:[:ex |
|
||||
ex return: 'fortyTwo'
|
||||
]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[
|
||||
bla := someObject fooBar.
|
||||
foo := bla.
|
||||
] on: MessageNotUnderstood do:[:ex |
|
||||
((ex message selector == #fooBar) and: [ ex message receiver == someObject])
|
||||
ifTrue:[
|
||||
ex return: 'fortyTwo'
|
||||
] ifFalse:[
|
||||
ex reject
|
||||
]
|
||||
]
|
||||
|
|
@ -0,0 +1 @@
|
|||
anObject perform:#fooBar ifNotUnderstood:[ ...some alternative code and return value... ].
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
Ingorabilis {
|
||||
|
||||
tell {
|
||||
"I told you so".postln;
|
||||
}
|
||||
|
||||
find {
|
||||
"I found nothing".postln
|
||||
}
|
||||
|
||||
doesNotUnderstand { |selector ... args|
|
||||
"Method selector '%' not understood by %\n".postf(selector, this.class);
|
||||
"Giving you some good arguments in the following".postln;
|
||||
args.do { |x| x.postln };
|
||||
"And now I delegate the method to my respected superclass".postln;
|
||||
super.doesNotUnderstand(selector, args)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
i = Ingorabilis.new;
|
||||
i.tell; // prints "I told you so"
|
||||
i.find; // prints ""I found nothing"
|
||||
i.think(1, 3, 4, 7);
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
Method selector 'think' not understood by Ingorabilis
|
||||
Giving you some good arguments in the following
|
||||
1
|
||||
3
|
||||
4
|
||||
7
|
||||
And now I delegate the method to my respected superclass
|
||||
ERROR: Message 'think' not understood.
|
||||
RECEIVER:
|
||||
Instance of Ingorabilis { (0x1817b1398, gc=D4, fmt=00, flg=00, set=00)
|
||||
instance variables [0]
|
||||
}
|
||||
<...>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
i = Ingorabilis.new
|
||||
try { i.think } { "We are not delegating to super, because I don't want it".postln };
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package require TclOO
|
||||
# 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
|
||||
|
||||
# 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 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”
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
function handle_error {
|
||||
status=$?
|
||||
|
||||
# 127 is: command not found
|
||||
if [[ $status -ne 127 ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
lastcmd=$(history | tail -1 | sed 's/^ *[0-9]* *//')
|
||||
|
||||
read cmd args <<< "$lastcmd"
|
||||
|
||||
echo "you tried to call $cmd"
|
||||
}
|
||||
|
||||
# Trap errors.
|
||||
trap 'handle_error' ERR
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import "io" for Stdin, Stdout
|
||||
|
||||
class Test {
|
||||
construct new() {}
|
||||
|
||||
foo() { System.print("Foo called.") }
|
||||
|
||||
bar() { System.print("Bar called.") }
|
||||
|
||||
missingMethod(m) {
|
||||
System.print(m)
|
||||
System.write("Try and continue anyway y/n ? ")
|
||||
Stdout.flush()
|
||||
var reply = Stdin.readLine()
|
||||
if (reply != "y" && reply != "Y") {
|
||||
Fiber.abort("Decided to abort due to missing method.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var test = Test.new()
|
||||
var f = Fiber.new {
|
||||
test.foo()
|
||||
test.bar()
|
||||
test.baz()
|
||||
}
|
||||
f.try()
|
||||
var err = f.error
|
||||
if (err) {
|
||||
if (err.startsWith("Test does not implement")) {
|
||||
test.missingMethod(err)
|
||||
} else {
|
||||
Fiber.abort(err) // rethrow other errors
|
||||
}
|
||||
}
|
||||
System.print("OK, continuing.")
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
class C{ fcn __notFound(name){println(name," not in ",self); bar}
|
||||
fcn bar{vm.arglist.println("***")}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue