"is copy" is what I wanted to allow modifying MAIN's passed-in values. "is rw" correctly rejects constants.
sub MAIN(Int $value is copy where ($value .= Int) ∈ (1,2,4,8,16)) {say "\$value.perl = ",$value.perl } # says $value.perl = 4 -y On Sun, May 12, 2019 at 5:02 PM yary <not....@gmail.com> wrote: > On #perl6 <timotimo> Int(IntStr) will not coerce because IntStr is > already an Int; coercions will only fire if the type doesn't match, like > with Array and Hash for example > > IntStr is a subclass of Int thus no coercion needed to set $value. A > catch-22 if each right side element is Int as opposed to IntStr, because > Main gets an IntStr $value and the set-matching operation ∈ needs an exact > class match. There is a work-around: > > # Be sure we are comparing with Int > sub MAIN(Int $value where Int($value) ∈ (1,2,4,8,16)) {say "\$value.perl = > ",$value.perl } > # says *$value.perl = IntStr.new(4, "4")* > > As an alternate workaround, I tried converting $value to Int while > comparing. That means $value needs to be writable, but the above plus > "$value is rw", fails: > > sub MAIN(Int $value is rw where Int($value) ∈ (1,2,4,8,16)) {say > "\$value.perl = ",$value.perl } > # 6.c says *Cannot find method 'Int' on object of type NQPMu* > *# *6.d says Usage: <tmp> <value> > > Without "$value is rw" working, the following also break. > > sub MAIN(Int $value is rw where ($value += 0) ∈ (1,2,4,8,16)) {say > "\$value.perl = ",$value.perl } > sub MAIN(Int $value is rw where ($value = Int($value)) ∈ (1,2,4,8,16)) > {say "\$value.perl = ",$value.perl } > > -y > > > On Sun, May 12, 2019 at 3:55 PM yary <not....@gmail.com> wrote: > >> Side note, using the angle brackets creates IntStr objects, which in some >> cases is harmless, sometimes necessary. >> >> > say <1 2 4 8 16 >.perl >> >> (IntStr.new(1, "1"), IntStr.new(2, "2"), IntStr.new(4, "4"), >> IntStr.new(8, "8"), IntStr.new(16, "16")) >> >> > say (1,2,4,8,16).perl >> >> (1, 2, 4, 8, 16) >> >> That's thanks to allomorphs from quote-word - >> https://docs.perl6.org/language/glossary#index-entry-Allomorph* "**Keep >> in mind that certain constructs, such as sets, bags, and mixes care about >> object identity, and so will not accept an allomorph as equivalent of its >> components alone."* >> >> I usually save angle brackets for strings but in this case, MAIN is >> getting IntStr, so we have to also have IntStr for the Set operator >> element-of: >> >> sub MAIN(Int $value where $value ∈ <1 2 4 8 16>) { say "\$value.perl = >> ",$value.perl } >> perl6 main.p6 4 >> *says $value.perl = IntStr.new(4, "4")* >> >> sub MAIN(Int $value where $value ∈ (1,2,4,8,16)) {say "\$value.perl = >> ",$value.perl } >> perl6 main.p6 4 >> *says Type check failed in binding to parameter '<anon>'; expected Any >> but got Mu (Mu)* >> * in block <unit> at main.p6 line 1* >> >> Which brings up another question- how to coerce $value to Int? These >> don't work, even though IntStr has an Int() method. >> >> sub MAIN(Int(IntStr) $value where $value ∈ (1,2,4,8,16)) {say >> "\$value.perl = ",$value.perl } >> sub MAIN(Int() $value where $value ∈ (1,2,4,8,16)) {say "\$value.perl = >> ",$value.perl } >> >> >> -y >> >> >> On Thu, Apr 18, 2019 at 5:31 PM mimosinnet <mimosin...@gmail.com> wrote: >> >>> El Sunday, 03 de March del 2019 a les 02:09, ToddAndMargo via >>> perl6-users va escriure: >>> >>> >I want to pass an integer to a sub. The only >>> >valid values of the integer are 1, 2, 4, 8, and 16. >>> > >>> >Other than using "if" to test their values, is >>> >there a way to state that an integer can only >>> >have certain predefined values? >>> >>> I like this syntax: >>> >>> sub MAIN(Int $value where $value ∈ <1 2 4 8 16 >) { >>> .... >>> } >>> >>> It is readable and I really like to use the '∈' symbol :D. >>> >>> Cheers! >>> >>> -- >>> (≧∇≦) Mimosinnet (Linux User: #463211) >>> >>