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

Reply via email to