Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading operators for a class

Let's say I have the following class:

class A {
    has $.val;

    method Str { $!val ~ 'µ'  }  
}

# Is this the right way of doing it?
multi infix:<~>(A:D $lhs, A:D $rhs) {
    ('(', $lhs.val, ',', $rhs.val, ')', 'µ').join;
}

How would I overload an operator (e.g., +) for a class in the same manner as Str in the previous class?

I guess this only works for methods that are invoked on an instance object and using the multi operator-type:<OP>(T $lhs, T $rhs) { } syntax for operators is the right way to go about it but I'm unsure.

For instance, in Python there seems to be a correspondence between special methods named after the operators (e.g., operator.__add__) and the operators (e.g., +). Furthermore, any operator overloading for a custom class is done inside the class.

like image 813
Luis F. Uceta Avatar asked Apr 23 '19 14:04

Luis F. Uceta


People also ask

What is the sentence of overloading operator for class A?

This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading. For example, we can overload an operator '+' in a class like String so that we can concatenate two strings by just using +.

Which operators are used for overloading?

In the above syntax Return_Type is value type to be returned to another object, operator op is the function where the operator is a keyword and op is the operator to be overloaded. Operator function must be either non-static (member function) or friend function. Overloading unary operator.

What is operator overloading in C++?

It's a type of polymorphism in which an operator is overloaded to give it the user-defined meaning. C++ allows us to specify more than one definition for a function name or an operator in the same scope, which is called function overloading and operator overloading, respectively.

What is operator overloading in OOP?

Physical Data Design Considerations. Polymorphism: Polymorphism (or operator overloading) is a manner in which OO systems allow the same operator name or symbol to be used for multiple operations. That is, it allows the operator symbol or name to be bound to more than one implementation of the operator.


2 Answers

In Perl 6, operators are considered part of the current language. All things that relate to the current language are defined lexically (that is, my-scoped). Therefore, a multi sub is the correct thing to use.

If putting this code in a module, you would probably also want to mark the multi for the operator with is export:

multi infix:<~>(A:D $lhs, A:D $rhs) is export {
    ('(', $lhs.val, ',', $rhs.val, ')', 'µ').join;
}

So that it will be available to users who use or import the module (use is in fact defined in terms of import, and import imports symbols into the lexical scope).

While there are some operators that by default delegate to methods (for example, prefix:<+> calls Numeric), there's no 1:1 relation between the two, and for most operators their implementation is directly in the operator sub (or spread over many multi subs).

Further, the set of operators is open, so one is not restricted to overloading existing operators, but can also introduce new ones. This is encouraged when the new meaning for the operator is not clearly related to the normal semantics of the symbol used; for example, overloading + to do matrix addition would be sensible, but for something that couldn't possibly be considered a kind of addition, a new operator would be a better choice.

like image 77
Jonathan Worthington Avatar answered Oct 07 '22 15:10

Jonathan Worthington


class A {
    has $.val;

    method Str { $!val ~ 'µ'  }
}

multi infix:<~>(A:D $lhs, A:D $rhs) {
    ('(', $lhs.val, ',', $rhs.val, ')', 'µ').join;
}

dd A.new(val => "A") ~ A.new(val  => "B"); # "(A,B)µ"

So yes, that is the correct way. If you want to override +, then the name of the sub to create is infix:<+>.

You can also provide the case for type objects by using the :U "type smiley", e.g.:

multi infix:<~>(A:U $lhs, A:U $rhs) {
    'µ'
}

Hope this answers your question.

like image 32
Elizabeth Mattijsen Avatar answered Oct 07 '22 17:10

Elizabeth Mattijsen