From 9011962ce9c5b78a90a89d75b632942a6cc4df9c Mon Sep 17 00:00:00 2001 From: "Zak B. Elep" Date: Sat, 2 Sep 2017 14:51:08 +0800 Subject: [PATCH 1/2] Document invocant in method signature Add documentation on setting invocant in method signatures, using type constraints to define class and object methods, and using multi declarator for defining same-name class and object methods. Fixes #1121. --- doc/Language/objects.pod6 | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/doc/Language/objects.pod6 b/doc/Language/objects.pod6 index 054e7566c..d932a0853 100644 --- a/doc/Language/objects.pod6 +++ b/doc/Language/objects.pod6 @@ -264,6 +264,54 @@ Method names can be resolved at runtime with the C<.""> operator. A.new."$name"().say; # OUTPUT: «(Any)␤» +A method's signature can have an I as its first parameter +followed by a comma, which allows for the method to refer to the object +it was called on. + + class Foo { + method greet($me: $person) { + say "Hi, I am $me.^name(), nice to meet you, $person"; + } + } + Foo.new.greet("Bob"); # OUTPUT: «Hi, I am Foo, nice to meet you, Bob␤» + +Providing an invocant in the method signature also allows for defining +the method as either as a class method, or as an object method, through +the use of L. The +C<::?CLASS> variable can be used to provide the class name at compile +time, combined with either C<:U> (for class methods) or C<:D> (for +instance methods). + + class Pizza { + has $!radius = 42; + has @.ingredients; + + # class method: construct from a list of ingredients + method from-ingredients(::?CLASS:U $pizza: @ingredients) { + $pizza.new( ingredients => @ingredients ); + } + + # instance method + method get-radius(::?CLASS:D:) { $!radius } + } + my $p = Pizza.from-ingredients: + say $p.ingredients; # OUTPUT: «[cheese pepperoni vegetables]␤» + say $p.get-radius; # OUTPUT: «42␤» + say Pizza.get-radius; # This will fail. + CATCH { default { put .^name ~ '--' ~~ .Str } }; + # OUTPUT: «Invocant of method 'get-radius' must be an object instance of type 'Pizza', + # not a type object of type 'Pizza'. Did you forget a '.new'?» + +A method can be both a class and object method by using the +L declarator: + + class C { + multi method f(::?CLASS:U:) { say "class method" } + multi method f(::?CLASS:D:) { say "object method" } + } + C.f; # OUTPUT: «class method␤» + C.new.f; # OUTPUT: «object method␤» + =head2 self Inside a method, the term C is available, which is bound to the invocant From 286c5701362cd8995a1aa1ad8e5ca5c9795973cb Mon Sep 17 00:00:00 2001 From: "Zak B. Elep" Date: Sat, 2 Sep 2017 20:32:06 +0800 Subject: [PATCH 2/2] :lipstick: s/comma/colon/ on method signature invocant description Thanks @moritz! --- doc/Language/objects.pod6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Language/objects.pod6 b/doc/Language/objects.pod6 index d932a0853..a9cd01cb3 100644 --- a/doc/Language/objects.pod6 +++ b/doc/Language/objects.pod6 @@ -265,7 +265,7 @@ Method names can be resolved at runtime with the C<.""> operator. # OUTPUT: «(Any)␤» A method's signature can have an I as its first parameter -followed by a comma, which allows for the method to refer to the object +followed by a colon, which allows for the method to refer to the object it was called on. class Foo {