Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a class that doesn't inherit from any other class?

If you create a class:

class Foo { }

the class will inherit all of its methods from Any, and then Mu.

I want to create a class that doesn't inherit from any other class: it should contain a single FALLBACK method that should catch all method calls to instances of that object.

I've looked through the MetaModel code, but there does not seem to be a simple way to achieve this goal. All suggestions are welcome!

UPDATE: I decided to go the intercept any method call way as described by Jonathan Worthington. This resulted in two new Perl 6 modules on CPAN: InterceptAllMethods and Object::Trampoline.

like image 655
Elizabeth Mattijsen Avatar asked Jun 25 '18 20:06

Elizabeth Mattijsen


People also ask

Can you restrict a class from inheriting another class?

To prevent inheritance, use the keyword "final" when creating the class. The designers of the String class realized that it was not a candidate for inheritance and have prevented it from being extended.

How do you prevent a class from inheriting?

You can prevent a class from being subclassed by using the final keyword in the class's declaration. Similarly, you can prevent a method from being overridden by subclasses by declaring it as a final method.

How should a class be declared to make the classes not inheritable?

you can use final keyword to class can not be inherited.

Is it possible to restrict inheriting a class in Java?

There are 2 ways to stop or prevent inheritance in Java programming. By using final keyword with a class or by using a private constructor in a class.


1 Answers

Here is another idea: You could create a new meta class that inherits from ClassHOW, but overrides the methods that role Perl6::Metamodel::MROBasedMethodDispatch provides with versions that skip all parent classes.

For example, this:

# Maybe this belongs on a role. Also, may be worth memoizing.
method can($obj, $name) {
    my @meths;
    my %smt := self.submethod_table($obj);
    if nqp::existskey(%smt, $name) {
        @meths.push(%smt{$name});
    }
    for self.mro($obj) {
        my %mt := $_.HOW.method_table($_);
        if nqp::existskey(%mt, $name) {
            @meths.push(%mt{$name})
        }
    }
    @meths
}

would become

method can($obj, $name) {
    my @meths;
    my %smt := self.submethod_table($obj);
    if nqp::existskey(%smt, $name) {
        @meths.push(%smt{$name});
    }
    @meths
}

That way you don't run into trouble with code that expects all types to conform to Mu, but you can still avoid accidentally calling methods from Mu.

like image 140
moritz Avatar answered Sep 18 '22 09:09

moritz