🦋 Welcome to the MAIN() IRC channel of the Raku Programming Language (raku.org). This channel is logged for the purpose of keeping a history about its development | evalbot usage: 'm: say 3;' or /msg camelia m: ... | Log inspection is getting closer to beta. If you're a beginner, you can also check out the #raku-beginner channel!
Set by lizmat on 25 August 2021.
Geth doc: 924afafd02 | (Stoned Elipot)++ | doc/Language/subscripts.pod6
whitespace fix
04:07
linkable6 Link: docs.raku.org/language/subscripts
lizmat PSA: the Rakudo Weekly News will be published on Tuesday this week due to circumstances 08:57
sjn happy circumstances, I hope 09:18
lizmat indeed :-)
sjn good to know :) 09:33
samebchase9 How do I ensure that a command that has colorized output, does the same when called inside a qqx{} block? 09:35
dakkar samebchase: it depends on the command 09:45
some commands (e.g. `ls`) accept options to force colours (`ls --color=always`) 09:46
some only produce colour output when their stdout is a tty (`qqx` sets the sub-process's stdout to a pipe)
(I haven't seen a raku module to set up a tty/pty) 09:47
oh, of course it also depends if you're on windows or not (as usual, windows is different)
samebchase dakkar: okay, I was trying to get `git show` to force colorized output 09:48
let me try with `ls --color=always` and see if that has any impact 09:49
or perhaps if there is some env variable that could be set
dakkar `git show --color=always` should work, according to the man page 09:51
remember that there's no general standard, every command is different
samebchase thanks so much dakkar! 09:54
I was searching for 'escape' in the `git show` man page, I guess I should have searched for `--color=always`
Anton Antonov "PSA: the Rakudo Weekly News will be published on Tuesday this week due to circumstances" -- FYI : it is usually published on Monday. (Well, the last dozen times at least...) 12:17
lizmat yeah... doing other stuff today 12:20
Anton Antonov @lizmat Good luck! 12:25
Tirifto Is there a way I can have code or variables interpolated into a string dynamically (at runtime) that does not involve EVAL? 13:21
Altreus What are you trying to do that "{ this }" doesn't do? 13:22
[Coke] m: say "{3**2}" 13:28
camelia 9
Tirifto I found a way that sort of allows me to do what I want, with caveats… I’ll try and explain my intent as well as I can. 13:39
Tirifto I have a class, and I want every one of its object to return a custom string with custom variations based on the object’s state. In other words, when the object is asked for the string, I want it to be able to read its own attributes and decide what string to build based on that; but what attributes it checks and how they affect the string should be customisable for every object. The most elegant (hypothetical) way to do this tha 13:54
t I thought of was giving each object a custom block which returns a string that holds interpolated pieces of code which check for the object’s internal state. (E.g. { $!money > 10 ?? “This person is also rich.” !! “” }.) But it seems I can’t access those or ‘self’ directly outside of the class declaration. I can refer to the variable that holds the object instead, which works provided the variable doesn’t change, bu
t doesn’t feel nearly as neat.
What also works (and feels neater) is mixing an anonymous role into each object that overrides the appropriate method with one that builds a custom string for the given object. The role’s method can’t access attributes directly, but can refer to ‘self’ and call methods on it, which is good enough. But it doesn’t feel as elegant as just passing a string (or a block with a string) to &new would, when creating new objects. 13:56
Tirifto To summarise, $!attribute and self.attribute both work in class declaration, but I want to do something different for every object. Giving the class a code block attribute and passing different code blocks to every object doesn’t work because I can use neither $!attribute nor self.attribute in those blocks. (I can do $object.attribute, though.) Role mixins work because I can do self.attribute in them. 14:04
So really I guess my question should be: Is there any way I can make a string with {$!attribute} outside of a class declaration, but have it interpolated later, inside of that class’s object? 14:05
Altreus Tirifto: are you running that code block like $code()? 14:06
Tirifto: You can do self.$code and now it's got a self inside it
m: class B { has $.cat = "cat"; has $!format = { "{ .cat }" }; method format { self.$!format } }; my B $b .= new; $b.format 14:07
camelia ( no output )
Altreus er that worked for me!
m: class B { has $.cat = "cat"; has $!format = { "{ .cat }" }; method format { self.$!format } }; my B $b .= new; say $b.format 14:08
camelia cat
Altreus the REPL auto-says :)
Tirifto: does that fit your situation?
Tirifto Mmm… I don’t think so; I’ll try to write a representative example. 14:11
Altreus: All right, here is an example that does not work (as stated above), but should illustrate the use case. 14:21
m: class Cat { has $.flea is rw; has $!description; }; my Cat $felix .=new(description => “This is Felix, a handsome bicolor cat. {$!flea ~~ “Amelia” ?? “He is now carrying Amelia, his best friend.” !! “”}”);
camelia 5===SORRY!5=== Error while compiling <tmp>
Variable $!flea used where no 'self' is available
at <tmp>:1
------> 3s Felix, a handsome bicolor cat. {$!flea7⏏5 ~~ “Amelia” ?? “He is now carrying Amel
Tirifto Err, in this case, it should have been $.description (read allowed), because it’s a string. 14:22
Altreus Ah! 14:24
Well, what you could do is accept a code for description, and in TWEAK, if description is a code, run it on self and set the real value to that
Tirifto Making $!description code was my next step, but I haven’t messed around with TWEAK! 14:25
That said, what I really want is for the description to be dynamic: for the string to be rebuilt/re-interpolated every time it’s being asked for. 14:26
Altreus hrm it won't let me
it complains about $!flea even though it's in a block and isn't being run yet 14:27
Tirifto In this example, Felix could be carrying Amelia at one moment, but later on, Amelia might hop off. So the description should always reflect the actual state of the cat.
Altreus ah, in that case you should definitely have method description, and has Callable $!describer
seems like the simplest way 14:29
basically a format method, and a formatter property, just like DateTime
(ish
)
Tirifto Hmm… how would that work in practice? The method &description gets its string $!describer, which holds the actual logic? 14:32
Altreus yeah basically ... method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } 14:33
This way you don't have to wrap a static string in a block :)
I guess the other way is to have « has Callable $!describer » and in TWEAK (or something) turn a raw string into a callable 14:34
oh it would probably have to be BUILD cos it'll already be wrong by TWEAK time
Tirifto Hmm… but will that stop Raku from interpolating the string when I pass it to &new? 14:36
For the record, here is an example showing the anonymous role solution: 14:38
m: class Cat { has $.flea is rw; }; my Cat $felix = Cat.new() but role { method description() {“This is Felix, a handsome bicolor cat. {self.flea ~~ “Amelia” ?? “He is now carrying Amelia, his best friend.” !! “”}”} }; $felix.description.say;
camelia This is Felix, a handsome bicolor cat.
Tirifto Or better yet, showing the dynamic side: 14:40
Altreus m: role Describable { has Callable $!describer; method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Bono", describer => -> { "This is Felix, a handsome bicolor cat. {self.flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! ""}" }); $c.description
Tirifto m: class Cat { has $.flea is rw; }; my Cat $felix = Cat.new() but role { method description() {“This is Felix, a handsome bicolor cat. {self.flea ~~ “Amelia” ?? “He is now carrying Amelia, his best friend.” !! “”}”} }; $felix.description.say; $felix.flea = “Amelia”; $felix.description.say;
camelia This is Felix, a handsome bicolor cat.
This is Felix, a handsome bicolor cat. He is now carrying Amelia, his best friend.
5===SORRY!5=== Error while compiling <tmp>
'self' used where no object is available
at <tmp>:1
------> 3This is Felix, a handsome bicolor cat. {7⏏5self.flea ~~ "Amelia" ?? "He is now carr
expecting any of:
term
Altreus again
I need a grownup 14:41
oh wait
m: role Describable { has Callable $!describer; method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Bono", describer => -> { "This is Felix, a handsome bicolor cat. { .flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! "" }" }); $c.description
camelia Impossible coercion from 'Cat' into 'Callable': no acceptable coercion method found
in method description at <tmp> line 1
in block <unit> at <tmp> line 1
Altreus m: role Describable { has Callable $!describer; method description { self.$!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Bono", describer => -> { "This is Felix, a handsome bicolor cat. { .flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! "" }" }); $c.description 14:42
camelia Impossible coercion from 'Cat' into 'Callable': no acceptable coercion method found
in method description at <tmp> line 1
in block <unit> at <tmp> line 1
Tirifto # Maybe we should have used a Dog; they usually respond to calls a bit better. :-) 14:44
Altreus why did this work? class B { has $.cat = "cat"; has $!format = { "{ .cat }" }; method format { self.$!format } }; 14:48
oh! 14:49
private properties need 'is built' :D
Tirifto Ohh! 14:50
Altreus yeah it works if you do that xD 14:51
role Describable { has Callable $!describer is built; method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Bono", describer => -> { "This is Felix, a handsome bicolor cat. {self.flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! ""}" }); $c.description;
oh I need a say I think
role Describable { has Callable $!describer is built; method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Bono", describer => -> { "This is Felix, a handsome bicolor cat. {self.flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! ""}" }); say $c.description;
and an m ... sorry for spam :( 14:52
m: role Describable { has Callable $!describer is built; method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Bono", describer => -> { "This is Felix, a handsome bicolor cat. {self.flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! ""}" }); say $c.description;
camelia 5===SORRY!5=== Error while compiling <tmp>
'self' used where no object is available
at <tmp>:1
------> 3This is Felix, a handsome bicolor cat. {7⏏5self.flea ~~ "Amelia" ?? "He is now carr
expecting any of:
term
Altreus m: role Describable { has Callable $!describer is built; method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Bono", describer => { "This is Felix, a handsome bicolor cat. {.flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! ""}" }); say $c.description;
camelia This is Felix, a handsome bicolor cat.
Altreus m: role Describable { has Callable $!describer is built; method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Amelia", describer => { "This is Felix, a handsome bicolor cat. {.flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! ""}" }); say $c.description;
camelia This is Felix, a handsome bicolor cat. He is now carrying Amelia, his best friend.
Altreus these things were needed: 1. is built; 2. don't use -> 14:53
3. use .flea not self.flea nor $!flea
Tirifto Altreus: Seems to work! Now I just need to read it over more carefully to grasp it. xP 14:56
Altreus self.&code is a useful trick that works in Perl5 too :) 15:03
Tirifto Altreus: Okay, so I’m still far from wrapping my head around all of this, but this has definitely answered my question and taught me something new; thanks a lot! 15:10
The way this works is that the code (describer) gets called on the object as a method, so the object becomes an argument and implicitly falls into $_, so the .flea gets called on it… did I get that right? 15:14
Altreus Ah that's where it's unclear to me, because I can't tell whether it goes into $_ or what 15:22
But yes, however it ends up there, it basically acts as a pseudo-method 15:23
SmokeMachine yes, that's it... `$obj.&func` is the same as calling `func($obj)` the same for `self.&!describer` being the same as `&!describer(self)` 15:51
m: role Describable { has &!describer is built; method description { &!describer(self) } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Amelia", describer => { "This is Felix, a handsome bicolor cat. {"He is now carrying Amelia, his best friend." if .flea ~~ "Amelia"}" }); say $c.description; # for example
camelia This is Felix, a handsome bicolor cat. He is now carrying Amelia, his best friend.
Altreus SmokeMachine: but that means it's passed as the first argument, and not that special `self` that normal methods get? 15:53
SmokeMachine: that is to say, it looks like code($_) rather than code(Any:)
that explains why -> broke it; it needs to be -> $obj for that to work
SmokeMachine that's not self, that's `$_` 15:59
m: sub bla($_) { .say }; 42.&bla 16:00
camelia 42
SmokeMachine m: &bla = { .say }; 42.&bla; bla(42) 16:02
camelia 5===SORRY!5=== Error while compiling <tmp>
Undeclared routine:
bla used at line 1
SmokeMachine m: my &bla = { .say }; 42.&bla; bla(42) 16:03
camelia 42
42
SmokeMachine m: my &bla = { MY::.say }; 42.bla 16:04
camelia No such method 'bla' for invocant of type 'Int'
in block <unit> at <tmp> line 1
SmokeMachine m: my &bla = { MY::.say }; 42.&bla
camelia PseudoStash.new(($_ => 42))
SmokeMachine Altreus: ^^ 16:05
melezhik . 16:06
SmokeMachine m: my &bla = { MY::.say }; bla; sub ble { MY::.say }; my &bli = -> { MY::.say }; bli
camelia PseudoStash.new(($_ => (Any)))
PseudoStash.new(($_ => (Any)))
SmokeMachine m: my &bla = { MY::.say }; bla; sub ble { MY::.say }; ble; my &bli = -> { MY::.say }; bli 16:07
camelia PseudoStash.new(($_ => (Any)))
PseudoStash.new(($! => Nil, $/ => Nil, $_ => (Any), $¢ => Nil))
PseudoStash.new(($_ => (Any)))
SmokeMachine m: my &bla = { MY::.say }; bla 42; sub ble { MY::.say }; ble 42; my &bli = -> { MY::.say }; bli 42
camelia 5===SORRY!5=== Error while compiling <tmp>
Calling ble(Int) will never work with declared signature ()
at <tmp>:1
------> 3::.say }; bla 42; sub ble { MY::.say }; 7⏏5ble 42; my &bli = -> { MY::.say }; bli 4
SmokeMachine m: my &bla = { MY::.say }; bla 42; sub ble { MY::.say }; ble; my &bli = -> { MY::.say }; bli 42
camelia PseudoStash.new(($_ => 42))
Too many positionals passed; expected 0 arguments but got 1
in block <unit> at <tmp> line 1

PseudoStash.new(($! => Nil, $/ => Nil, $_ => (Any), $¢ => Nil))
SmokeMachine m: my &bla = { MY::.say }; bla 42; sub ble { MY::.say }; ble; my &bli = -> { MY::.say }; bli
camelia PseudoStash.new(($_ => 42))
PseudoStash.new(($! => Nil, $/ => Nil, $_ => (Any), $¢ => Nil))
PseudoStash.new(($_ => (Any)))
raydiak note that self does work if you use a method as the callable: 16:35
m: role Describable { has Callable $!describer is built; method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Amelia", describer => method { "This is Felix, a handsome bicolor cat. {self.flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! ""}" }); say $c.description;
camelia This is Felix, a handsome bicolor cat. He is now carrying Amelia, his best friend.
Tirifto Thank you, SmokeMachine & raydiak; 16:48
Altreus raydiak: oh that's neat, I wondered how to do that! 16:49
Tirifto I guess that also makes intuitive sense, since you can have an attribute (that you can set) that literally is a method. :-) 16:51
raydiak we have first-class anonymous methods, detached from any class. you can pass them around, put them into a my variable or whatever just like anonymous subs 16:53
m: my &m = method { .say }; 42.&m
camelia (Any)
raydiak m: my &m = method { self.say }; 42.&m
camelia 42
Tirifto Raku is like the wings of Camelia: beautiful and elaborate. 16:55
raydiak glad you like it :) 16:56
raydiak personally I think the block how you had it was a bit more readable than an anonymous method, but just wanted to throw it out there for educational purposes 16:56
SmokeMachine m: my &m = method { self.say }; m 42 16:57
camelia 42
Altreus I did play with sub x(Any:) but it complained - now I know why
SmokeMachine It also works the same way ^^
raydiak heh nice SmokeMachine, I never thought to try that 16:58
Tirifto So the reason I can’t use $!attribute or self.attribute in an ordinary block is not that Raku is trying to interpolate them on sight (it apparently doesn’t), but rather that self and the $! twigil are special and it only allows them to appear in the appropriate context (e.g. class definition or method)? 17:02
(Or evaluate, rather. I was thinking of blocks in strings in blocks, but I guess it goes for any block.) 17:04
raydiak correct 17:08
Tirifto Thanks again! ^ ^ 17:09
raydiak you're welcome of course, happy to help :)
SmokeMachine 17:35 <raydiak> m: role Describable { has Callable $!describer is built; method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Amelia", describer => method { "This is Felix, a handsome bicolor cat. {$.flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! ""}" }); say $c.description; 17:11
m: role Describable { has Callable $!describer is built; method description { $!describer ~~ Callable ?? self.$!describer !! $!describer } }; class Cat does Describable { has $.flea is rw }; my Cat $c .= new( flea => "Amelia", describer => method { "This is Felix, a handsome bicolor cat. {$.flea ~~ "Amelia" ?? "He is now carrying Amelia, his best friend." !! ""}" }); say $c.description; 17:12
camelia This is Felix, a handsome bicolor cat. He is now carrying Amelia, his best friend.
SmokeMachine You can use $.attr instead of self.attr
Tirifto Ah right, that also works with the method method. Can ‘$.attr’ be regarded as a (perhaps a slightly more descriptive) alias for ‘self.attr’? 17:15
raydiak I believe that's correct. technically it doesn't even have to be an attribute: 17:36
m: class { method a { 42 }; method m { say $.a } }.m
camelia 42
casaca CIAvash: thanks for `Curry`! 18:52
CIAvash casaca: you're welcome! 19:02
casaca hope it's included in core someday 19:08
Geth Raku-Steering-Council/main: ad0130ccd5 | (Geoffrey Broadwell)++ | minutes/20211002.md
Add RSC meeting minutes for 2021-10-02
20:52
Geth Raku-Steering-Council/main: 5 commits pushed by (Vadim Belman)++ 21:30