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

Reply via email to