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) >> >