> On Apr 30, 2018, at 8:04 AM, ToddAndMargo <toddandma...@zoho.com> wrote: > > Hi All, > > I am confused. > > With this sub: > > sub odd( $Num ) { return $Num % 2; } > > > Why does this work: > > if odd $LineNum > { $PartsStr ~= '<font color="#006600">'; } # Green > else { $PartsStr ~= '<font color="#663366">'; } # Purple > > And this one throw an error: > > if $LineNum.odd > { $PartsStr ~= '<font color="#006600">'; } # Green > else { $PartsStr ~= '<font color="#663366">'; } # PurpleNo > > No such method 'odd' for invocant of type 'Int'. Did > you mean 'ord'? > > What is my misunderstanding? > > > Many thanks, > -T
Short answer: Defining a sub does not define a method. There is a work-around, though: `.&` (Simple primer: A `sub` is named code that can be called on any bits of data you choose as arguments. In OO, a `method` is named code that is part of a class, and can only be called via an object of that class.) Detail: Perl 5 had built-in `functions`, i.e. subs that were provided by the base Perl language: $m = sin $x; $n = abs $y; push @z, 15; See `perldoc perlfunc`, or https://perldoc.perl.org/perlfunc.html . In Perl 6, the equivalent functions are implemented and available as *methods*, but are also exported as subs, to allow for fluidity between procedural and OO styles of programming (and also less stress for the Perl 5 coders wading into the Perl 6 pool): New method form: $m = $x.sin; $n = $y.abs; @z.push(15); @z.push: 15; Old functions still work though: $m = sin($x); $m = sin $x; $n = abs($y); $n = abs $y; push(@z, 15); push @z, 15; Outside of this special case, an OO API that double-provides its methods as subs is usually a bad idea. You *can* do it, using the same trick as the Perl 6 built-ins: add `is export` to your method definitions. (But please don't, unless you are *sure* that the confusion and name-space pollution and collisions are justified by the definite needs of the API users.) The reverse path is not provided for; you cannot define a sub and automatically get the method form. This is quite correct for OO design; to do otherwise implies that you are shoving new methods at run-time into the very top base class (the evil MONKEY-PATCHING)! Not being able to call your sub via method-call-syntax, well, it only looks so glaringly inconvenient from the ground floor of language use. ...which is where most of us are! So, a bit of syntax is provided, as a sop to us who insist that this: say MySumTwister( MyWickedSub( %h.keys.grep(*.so)».sqrt.sum ).abs ); would look better as: say %h.keys.grep(*.so)».sqrt.sum.MyWickedSub.abs.MySumTwister; You *are* allowed to write it in method form (and keep the reader's eyes from having to jump back-and-forth) with `.&` instead of `.` , like so: say %h.keys.grep(*.so)».sqrt.sum.&MyWickedSub.abs.&MySumTwister; This syntax is listed as "postfix .&", and can be found here: https://docs.perl6.org/language/operators#postfix_.& So. `.` calls a method, and `.&` calls a sub as if the sub were a method. -- Hope this helps, Bruce Gray (Util)