🦋 Welcome to the MAIN() IRC channel of the Raku Programming Language (raku.org). Log available at irclogs.raku.org/raku/live.html . If you're a beginner, you can also check out the #raku-beginner channel!
Set by lizmat on 6 September 2022.
Nemokosch the final nail in the coffin of the "worry" message of smartmatching to S/// has arrived: 11:41
Nemokosch m: no worries; '1' ~~ S/1/2/; say $/; 11:43
camelia 「1」
Nemokosch it even sets the match variable so all reasoning that applies to $foo ~~ /regex/ applies to $foo ~~ S/regex/new/ as well 11:44
lizmat m: no worries; say '1' ~~ S/1/2/; say $/; 11:49
camelia 2
「1」
Nemokosch Since the imo undesirable behavior is noted on the docs site as well, I will open a problem-solving issue for this
lizmat sounds like a plan 11:50
Nemokosch Fortunately this is an extended weekend until wednesday and I want to start with my pending $dayjob duties (plus a little Ddt :speak-no-evil: ) so maybe it won't happen until monday or tuesday 11:51
lizmat and on Sunday, the day will be 25 hours! :-) 11:52
Nemokosch But I took notes in Obsidian
Oh you are right, that will probably turn into sleep :D
Nemokosch Hm, I have a question because this might be hard to figure out out the hard way 12:04
I have a role that provides some multi candidates for new 12:06
This role, to be precise: github.com/kalkin/License-Software...stract.pm6
I want to write a class that does this role, and has some properties that I'd like to take from new 12:06
lizmat you'd probably want to stick a proto in there 12:07
Nemokosch will a new candidate be generated, and if so, how? if not, how can I handle my properties and then pass the handling to the inherited new? 12:08
yes, well, in the long term, it would be good to adopt License::Software as well, but for now I'd like to get around its interface from Ddt
I've started playing around and it seems to me I do get a new candidate that can only fill the properties but doesn't really pass anything to the inherited method 12:39
can I somehow say "call the inherited new method"? 13:59
Nemokosch Best Raku error message delivered yet is coming, pay attention 14:16
m: sub demo(|c, :$name) { say c; say $name; }; demo(1);
camelia Too many positionals passed to 'demo'; expected 1 argument but got 1
in sub demo at <tmp> line 1
in block <unit> at <tmp> line 1
Nemokosch expected 1 but got 1... oh well 14:17
The lie lies (haha) in the "expected 1 argument" part 14:19
It actually expects 0 positional arguments. I don't know how all this works, honestly. I just wanted to capture one of the named arguments, called "name"
oh it works in reverse order 14:28
still, the error message (and possibly the behavior?) is very much LTA...
Nemokosch How can I git rid of the default constructor? 14:54
Nemokosch m: class Demo { method new(:$name!) { say $name; } } 14:54
camelia ( no output )
Nemokosch maybe another REPL weirdness... 14:55
lizmat m: sub demo(:$name, |c) { say c; say $name; }; demo(1); 15:30
camelia \(1)
(Any)
lizmat I think it should actually complain about having a named argument *after* a |c 15:31
at compile time
Nemokosch Fine by me, I don't really know how it should work 15:41
however, the default constructor is getting on my nerves
is there really no way to get rid of it if I'm overriding the shown multi-only role? 15:42
> Default constructor for 'Ddt::License' only takes named arguments 15:50
I don't want to have any default constructors :@
I didn't ask for this
lizmat make an "only method new" 15:51
give a class its own proto method new 15:52
Nemokosch with only, it doesn't complain because I inherit from that role with the multis 15:52
At least that's how I understood the error 15:53
With proto, it did the same thing as with multi - still complained about "the default method" wanting to do something
lizmat ok, do we have a gist somewhere ? 15:56
Nemokosch moment
gist.github.com/2colours/b6f52cc16...36917608b9 15:59
you can try for yourself I think, with little modifications
the only version throws a compile-time error, by the way
lizmat yeah, looking at it now 16:02
so what has the Ddt::License module need to do extra? 16:06
Nemokosch: looks like 16:08
multi method new(Ddt::License:) {...}
works?
Nemokosch moment, I need time to integrate the knowledge :DD 16:10
By the way, don't overestimate my knowledge with Raku OO because it's nearly zero 16:13
lizmat ok... 16:14
so by adding Ddt::License: to the signature, you're saying that this multi candidate will be called whenever it is called as a class or instance method on the Ddt::License class 16:15
Nemokosch No, it didn't help, by the way 16:16
> Default constructor for 'Ddt::License' only takes named arguments
lizmat you could add :U for class method only, or :D for instance method
the gist doesn't contain a call to the class: how do you call it ?
Nemokosch Hmm, this is a reasonable question actually... do I in fact overestimate how many ways there are to call the underlying method, I wonder 16:17
Ddt::License.new: 'sajt' # does work, for example
Ddt::License.new: 'sajt', 'víz' # produces this bizarre error but the fact that it's an error is probably fair 16:18
lizmat yeah, if your candidate fails to match, then it falls back to the one provided by Any, and that one will complain 16:19
Nemokosch now I'm going to try to add the named argument to the Ddt::License new 16:20
lizmat make sure the |c is the last one
Nemokosch Oh right
Almost forgot 16:21
So yeah, in simple terms, my goal is to handle this one named argument separately while the rest is just provided to the underlying License::Software::Abstract method 16:22
lizmat multi method new(Ddt::License: :$foo, |c) { 16:27
my $base-constructed = self.bless(|c); 16:28
Nemokosch What does specifying Ddt::License: serve here? 16:29
lizmat [18:15:50] <lizmat>so by adding Ddt::License: to the signature, you're saying that this multi candidate will be called whenever it is called as a class or instance method on the Ddt::License class 16:30
Nemokosch Oh right, I was busy checking the behavior at that moment 16:36
but it did not help unfortunately, still
Ddt::License.new: name => 'GO' # Stub code executed 16:37
despite the `multi method new(:$name!, |) {` candidate
do I need Ddt::License: there as well?
lizmat i'd say so ?
hmmm 16:38
Nemokosch I still don't fully grasp the relevance of that. I define the candidates in that class, it shouldn't get mixed with the underlying role.
And I have no derived classes, nor do I plan to
it could be a "final class"
lizmat then add a:proto method new(|) {*} 16:39
then add a
proto method new(|) {*}
to Ddt::License 16:40
Nemokosch instead of the stub?
lizmat do you understand the function of proto ?
docs.raku.org/syntax/proto
Nemokosch I wouldn't have asked if I didn't at least think I understood proto :) 16:41
And based on my understanding, I would have expected the "default constructor" to go away by the sole presence of a proto
To be honest, it's more that I feel the language is gaslighting me with the apparent lack of consistency 16:43
lizmat it does go away with a proto
dinner&
Nemokosch That's what I thought until an error message disproved me... 16:44
By the way, thanks for all the help, I don't want to appear thankless to the effort you are putting into helping me 16:46
However, all this code got us nowhere. The behavior is exactly the same as without any overloading of new 16:48
That is, either the positional is in effect, or :$name, but not both 16:49
Nemokosch > proto method new(Ddt::License: :$name!, |c) { 16:56
Ddt::License.new: name => 'FASZ', 'LOL'
> Default constructor for 'Ddt::License' only takes named arguments
Enough of the lies :@
my problem, to be honest, is that I don't want to use the usual multi dispatch mechanism. I want to call the inherited method with the same arguments. That's a different thing. 17:08
lizmat Nemokosch: I don't think you understand what proto is about 17:24
Voldenet honestly, inheritance is not that useful if you control base class 17:26
Nemokosch To be honest, I reached the point where I just want a solution.
Voldenet just use role and compose it into the class 17:27
lizmat you want an extra named argument to the License::Software::Abstract role
Nemokosch: is that what you want ?
Nemokosch not necessarily extra
lizmat make up das mind :-) 17:28
Nemokosch I just want it to be handled in a special way; it can still be passed to the base class
I think it makes more sense if it gets passed through
lizmat ok, please provide a piece of (pseudo) code with input / requested output 17:29
Nemokosch > Ddt::License.new: 'ASD' # Ddt::License.new(name => Str, works-name => "This program", holders => [License::Software::Holder.new(name => "ASD", year => 2022)]) 17:31
> Ddt::License.new: name => 'Proprietary' # Ddt::License.new(name => "Proprietary", works-name => "This program", holders => [])
Ddt::License.new: 'ASD', name => 'Proprietary' # Ddt::License.new(name => 'Proprietary', works-name => "This program", holders => [License::Software::Holder.new(name => "ASD", year => 2022)]) 17:32
the first two I get for free
I want the third one to also work, without hardcoding the whole interface of License::Software
Nemokosch This would be painfully simple with a super/inherited/License::Software::method call 17:35
That's really all it would take. "Handle this one as the concrete class needs, pass all the arguments to the inherited method"
lizmat so the first positional is the name, but only if :name is not specified? 17:46
in that case, what is the meaning of the first positional then ? 17:47
Nemokosch The order of the parameters is not a constrain; the user (so mostly me) will use them in the prescribed order 17:51
The important thing is that I pick the existing interface of License::Software and handle one (otherwise irrelevant) part of it (:$name) specifically in the implementing class 17:52
For the rest, it should behave all accordingly to the inherited new methods 17:53
lizmat multi method new(Ddt::License: :$name, |c) { 17:54
self.bless(:name($name.uc), |c);
uc-ing the name to prove it was changed 17:55
Nemokosch so does bless automagically call the inherited new?
lizmat no, the inherited new calls bless under the hood normally 17:56
lizmat you're bypassing that by calling bless yourself 17:57
docs.raku.org/routine/bless
Nemokosch yes but then how do I make sure all other arguments are handled the way License::Software handles them?
that's why I was trying to call its new
lizmat you don't need to, bless will take care of that
Nemokosch You have seen the new methods of License::Software, right? Just to make sure, because I'm really not sure we are on a common ground. 17:58
lizmat ah, ok :-) sorry 18:01
ok, get rid of the "method new" altogether, and add: 18:03
submethod TWEAK(:$name) { $!name = $name }
submethod TWEAK(:$name) { $!name = $name.uc } # uc to prove it changed 18:04
Nemokosch ohhh 18:05
Nemokosch I have to try this before saying anything that's for sure 18:08
Ddt::License.new: 'ASD', name => 'LMAO' # Type check failed in assignment to $!name; expected Str but got Any (Any) 18:09
lizmat confirmed... looking into it 18:13
lizmat method !set-name($!name) { self } 18:25
multi method new(Ddt::License: Str:D $foo, :$name!) {
self.new($foo, |%_)!set-name($name)
}
multi method new(Ddt::License: :$name!) {
self.new(|%_)!set-name($name)
}
you will need 2 candidates 18:26
and a private method to set $!name
Nemokosch How does this not break the interface of License::Software? :( 18:32
I mean, I agree that this is very unfortunate design but new is a part of the API of License::Software 18:33
Voldenet actually, if you ignore conventions, you can do that quite easily 18:46
ix.io/4eps
or even ix.io/4ept 18:47
Nemokosch I only noticed now how weird that "submethod url..." is. Whatever, checking your code... 18:56
Voldenet discarding .new is a leap of faith here 18:57
Nemokosch I mean yeah... I don't consider this a solution. If it's a part of the API then it shouldn't be replaced by a method with a different name 18:58
Voldenet it stops being the part of this api once the inheriting class doesn't even know all constructors 18:59
meaning that what specifies Ddt::License's behaviour is the version of the imported role 19:01
Nemokosch I mean yeah, same with any extension to any API 19:02
Voldenet So, imo you either have to maintain all the constructors you use (I recommend that, btw) or create a separate creation method
if License::Software::Abstract gets a :name parameter in its api bad things might happen 19:03
Nemokosch You know, the bad thing is that License::Software::Abstract doesn't even get *maintenance*
Voldenet Probably :)
Nemokosch Perhaps you don't know the context. I'm planning to create an update for the Ddt module so that I can claim maintenance of that module. 19:05
The same author created License::Software but I didn't want the burden to start things over for that module as well.
As something that seemed useful to me personally, I wanted to allow licenses that are really just a name and minimal description; that's enough for internal modules at work. 19:06
Voldenet …ah, that's why the requirement of keeping the api
Nemokosch that's why I created the Ddt::License class which is really a dummy implementation of the role provided by the license module 19:07
so that at other places in Ddt, I can say "if identification of the license failed, fall back to this dummy"
Nemokosch unfortunately, an integral part of the License::Software API revolves around type objects and constructors 19:08
so I wanted to make Ddt::License as much "drop-in" as possible 19:09
and the truth is, if Raku had proper inherited (Pascal), super (Java, Javascript, Python) or scope-based module resolution (C++), this would be trivial
Voldenet in that case adding new `new` constructors for every case feels like the sanest solution
Nemokosch s/module/method 19:10
and perhaps s/scope/namespace
Voldenet Actually in java you'd have to always write down constructors for every case 19:11
in inherited class
Nemokosch if you cannot pass the same arguments without naming them, sure
but that's actually not the issue for Raku 19:12
the issue is that I don't seem to be able to just say "call the inherited method"
multi candidates are not even conceptually similar to inheritance
my final shot is to mess around with MOP, I just cannot accept that something like this can fail on arguably the easiest step 19:13
not the argument list, not the object construction but the lookup of inherited methods 19:14
Voldenet Nemokosch: true Enterprise Java Coder would just create something like this (except with more `new` methods, obviously) ix.io/4epH 19:28
hmm, true java coder would've put $.name before the new 19:29
lizmat sorry, was in a meeting 19:32
why does my solution break the API ? 19:33
Voldenet …it doesn't, because Ddt::License defines its own new api and it can define any candidates for `new` 19:34
btw, in ` multi method new(Ddt::License: Str:D $foo, :$name!) {`, is it really necessary to have the `Ddt::License`? 19:35
`Ddt::License.^find_method('new').candidates.map(*.signature).say;` tells me that signatures define that either way when composing the role into the class 19:36
Nemokosch That's what I also asked 20:18
lizmat: oh sorry, perhaps I misread 20:19
I was also trying to play with MOP, ^.roles and all... 20:20
Xliff japhb: Around? 21:15
tellable6 hey Xliff, you have a message: gist.github.com/38ffce85fa6bfd0cc6...6e72549693
Xliff .tell japhb Would like your help on something. What's the best way to redirect $*OUT to a Terminal::Widget window? I haven't had a chance to look at the examples yet. I thought I'd ask you for quick help first. TIA. 21:16
tellable6 Xliff, I'll pass your message to japhb
Xliff .tell japhb OK, thanks. Was just wondering what the proper interface to the decoded-output was in Terminal::ANSIParser. I'll take another gander and look more closely. Thanks. 21:17
tellable6 Xliff, I'll pass your message to japhb
Nemokosch uh oh, now I remember what I didn't like about lizmat's solution 21:31
the hardcoding of the positional ($foo in the snippet)
I think it might be sufficient because Ddt::License isn't supposed to be really public, and inside Ddt, I know which License::Software.new call I will be making 21:34
lizmat: It does work, thank you. I wish there was a straightforward and elegant way but the underlying ad-hoc interface also didn't help to make it nice and clean. 21:39
japhb . 21:52
tellable6 2022-10-29T21:16:17Z #raku <Xliff> japhb Would like your help on something. What's the best way to redirect $*OUT to a Terminal::Widget window? I haven't had a chance to look at the examples yet. I thought I'd ask you for quick help first. TIA.
2022-10-29T21:17:15Z #raku <Xliff> japhb OK, thanks. Was just wondering what the proper interface to the decoded-output was in Terminal::ANSIParser. I'll take another gander and look more closely. Thanks.
japhb Xliff: Around now. Still need help?
Geth Raku-Steering-Council/main: 1fc4e21cd5 | (Nick Logan)++ (committed using GitHub Web editor) | minutes/20221029.md
Add RSC meeting minutes for 2022-10-29
22:20
Xliff . 23:44
japhb: Wasn't then. Am now. 23:45
japhb Heh 23:49