This channel is intended for people just starting with the Raku Programming Language (raku.org). Logs are available at irclogs.raku.org/raku-beginner/live.html
Set by lizmat on 8 June 2022.
00:03 Kaiepi left 00:27 MasterDuke joined
zacque What is the relationship between the key and value pair in “provides” field of a META6.json file? 00:57
It seems to me something like “JSON::Fast” : “lib/JSON/Fast.rakumod” is redundant? 01:00
kjp No. The key is the name of the mdule; the value is the file containing it. The names need not correspond. 01:02
zacque Can I map different module name to some other module file? Or can I place multiple modules into one module file?
kjp I believe so.
zacque I see, I’ll try it out. Thanks! 01:03
01:53 MasterDuke left 01:57 frost78 joined
elcaro A simple way to solve this is implement a `.cmp` method on your class. being a method, it has access to private attributes, etc. Then you export `multi sub infix:<cmp>(MyClass $a, MyClass $b) { $a.cmp($b) }` 02:00
zacque Thanks, question: How can I access the private attribute of the passed-in object? 02:28
<@724421839924756480> 02:31
elcaro Ahh, ok, I see your problem... You need access to both objects privates
There is a way to break OO privacy: rosettacode.org/wiki/Break_OO_privacy#Raku 02:38
there might be a smarter way to compare your objects. Is the data truly private? or are you just trying to make it private because the user doesn't need it? Can you perhaps expose some kind of hash of the private data, where you can then compare hashes? 02:39
hashes as in... Digests... not Associative Arrays / Dictionaries
zacque Oh? I thought in ```raku 02:40
class A {
has Int $!a;
submethod BUILD(Int :$!a) { }
method cmp(A $obj2) { $!a cmp $obj2.<!a>; }
}
``` `cmp` has access to the private attribute of `$obj2`.
Oh? I thought in ```raku 02:41
class A {
has Int $!a;
submethod BUILD(Int :$!a) { }
method cmp(A $obj2) { ... }
}
``` `cmp` has access to the private attribute of `$obj2`.
elcaro No... Raku objects are not stored as a hash. You have to hit up the MOP to break into them
zacque Ya, I'm trying to make all attributes private by default, unless direct access is needed
I see, that's unexpected 02:43
elcaro in that case it would be `$obj2.^attributes.first('$!a').get_value($obj2)`, but that's probably overkill if there's no _harm_ in exposing the data.
What is unexpected... that they are not hashes underneath, or that privacy can be broken with the MOP? 02:44
zacque I meant the private attribute of object of the same class cannot be accessed directly
What does the `first('$!a')` do here? 02:46
Does it imply that there might be multiple attributes called `$!a`? 02:48
elcaro Yeah so the distinction is that attributes belong to the instance, not the class. 02:50
It's just occurred to me that objects are like people in that they have self-sovereignty. maybe I'm reading to much into things 😄
zacque Oh, because that's the only method (besides `grep`) to lookup value from a list
I'm still new to the List methods
elcaro yeah, it returns an item, rather than grep which returns a list (of possibly only one item) 02:52
The point is... if someone wants to break into your object, they can... but if they don't need to, they won't bother.
In that case, you are just making it harder on yourself by making it private.
zacque Get it, thanks! In my case, the comparing data is a derived data, so I don't really want to expose it to the public 02:54
The client passes in a string for constructor, but I'm comparing based on derived data from the string, which has different order from comparing the strings directly. 😄
elcaro If the object has access to the passed in value, perhaps it can re-derive it? but at the end of the day, it's your code... do what feels right 02:58
zacque Oh no, the main reason to use the class is to encapsulate derivation and comparison logic
Yup, thanks for your help!
elcaro a downside is the perf hit from constantly looking up a list of attributes and filtering. You could resolve the attribute lookup once. here's a silly trick 03:04
```
class Foo {
has $.pub;
has $!priv;
has $!priv-attr = self.^attributes.first('$!priv');
submethod BUILD(:$!pub, :$!priv) { }
method cmp(::?CLASS $foo) {
$!priv eq $!priv-attr.get_value($foo)
}
}
multi sub infix:<cmp>(Foo $l, Foo $r) { $l.cmp($r) }
my $a = Foo.new(pub => 'a', priv => 'fo0B4R');
my $b = Foo.new(pub => 'b', priv => 'fo0B4R');
my $c = Foo.new(pub => 'c', priv => 'foobar');
say $a cmp $b; # True
say $a cmp $c; # False
```
zacque Huh? What's weird is that a method can access the **private method** of object of the same class, but not its **private attribute** 03:06
See: ```raku 03:07
use v6.d;
class A {
has Int $!a;
submethod BUILD(Int :$!a) { }
method cmp(A $obj2) {
$!a cmp $obj2.^attributes.first('$!a').get_value($obj2)
}
method !foo() { $!a * 2; }
# test private method access
method test-pmthd(A $obj2) { $obj2!foo; }
}
my $foo1 = A.new(:7a); my $foo2 = A.new(:5a);
say $foo1.cmp($foo2);
say $foo1.test-pmthd($foo2);
```
See: ```raku 03:08
use v6.d;
class A {
has Int $!a;
submethod BUILD(Int :$!a) { }
method !foo() { $!a * 2; }
# test private method access
method test-pmthd(A $obj2) { $obj2!foo; }
}
my $foo1 = A.new(:7a); my $foo2 = A.new(:5a);
say $foo1.test-pmthd($foo2);
```
See: ```raku
class A {
has Int $!a;
submethod BUILD(Int :$!a) { }
method !foo() { $!a * 2; }
# test private method access
03:08 discord-raku-bot left 03:09 discord-raku-bot joined
elcaro oh yes, of course! 03:09
as I mentioned, attributes belong to the _instance_, but methods belong to the _class_... so you can just expose the private attribute *via* a private method 03:11
so that other classes can access it
zacque See: ```raku 03:13
class A {
has Int $!a;
submethod BUILD(Int :$!a) { }
method !foo() { $!a }
# test private method access
method test-pmthd(A $obj2) { $obj2!foo; }
}
my $foo1 = A.new(:7a); my $foo2 = A.new(:5a);
say $foo1.test-pmthd($foo2); # Output: 5
```
elcaro so you should just have a `method !a { $!a }`,
then `method cmp($obj) { $!a cmp $obj!a }`
zacque Other classes? I thought only objects of the same class can access to the private method? 03:15
elcaro yes, only same class
I meant... other _instances_
zacque Ya, just thought of that as well, still I think that a bit of weird UX
elcaro so that other ~~classes~~ _instances_ can access it 03:16
zacque But that will solve my problem
Ok 03:17
Thanks!
To sort out my mind, so a method has access to all attributes of the invocant and all methods of the same class 03:21
But for objects passed in as an argument, it has only access to all its methods (be it private or public)
But for objects passed in as an argument, the method has only access to all its methods (be it private or public) 03:22
But only access to all methods for objects of the same class passed in as an argument. (By all, I meant both public and private) 03:25
Only access to public methods for objects of different class
elcaro yes 03:36
It's worth noting that `has $.a` is really just syntax sugar for `has $!a; method a { $!a }`
So the only way to expose an attribute... even a public one, is via a method (under the hood). 03:38
In the same way, a private method can expose an attribute... the difference being private methods are only available to instances of that class
zacque Thx, I'm aware of it 03:40
04:14 Heptite left
That said, there is no name conflict if I do this: ```raku 04:49
class Foo {
has $.a;
method a { 100 } # No name conflict.
}
```
But something like this is illegal: ```raku 04:50
class Bar {
method a { 100 }
method a { 200 } # Error! Same name conflict.
}
```
elcaro Correct. Perhaps it's more correct to say `$!a` creates an accessor method `a`, unless you provide your own method with that name. 05:09
Correct. Perhaps it's more correct to say `$.a` creates an accessor method `a`, unless you provide your own method with that name. 05:46
Nemokosch I remember when learning OO (with C++), it seemed weird that private data can be reached from another instance that just has the same class but otherwise has nothing to do with `this` 😅 06:38
I agree, though, that methods and attributes behave way too differently to be intuitive
zacque Lol, didn't think that much back then 06:57
Nemokosch well we were there to learn 06:59
with one of the best teachers of the university
07:09 Kaiepi joined
zacque That's great! 07:17
New question: How do I define multiple constructors for a class? 07:21
Should I overload the `new` method or the `BUILD` method? 07:23
08:12 dakkar joined
Nemokosch I can very vaguely recall something from Liz that TWEAK is better than BUILD? Anyway, almost sure new should do 08:15
discord.com/channels/5384078799804...5953687652 MasterDuke it was 08:17
Nahita at the BUILD and TWEAK phases the object has been already blessed, so new should be made multiple 08:19
its name need not be new but it's convention and default constructor has that name too. but you can call it `make` and as long as you end up blessing in that, it works
naming it different useful in factory methods like `from-*` etc. 08:21
i sometimes override and possibly abuse CALL-ME to type less
09:28 dakkar left 09:29 dakkar joined 11:33 equinox joined 12:11 equinox36 joined 12:14 equinox left
zacque Hmm, I'm going for `make` as constructor 12:17
Couldn't figure out what's wrong with this: ```raku
class Foo {
has ($!x, $!y);
multi method make(:$x, :$y) {
say "Here x y";
self.bless(:$x, :$y)
}
multi method make(:$z) {
say "Here z: $z";
self.bless(x => ($z div 2), y => ($z % 2))
}
submethod BUILD(:$!x, :$!y) {}
method result { "$!x and $!y" }
}
Foo.make(:2x, :3y).result.say; # Ok
Foo.make(:4z).result.say; # Uninitialised Error
```
It seems like I should be able to pass `:z` into `Foo.make` but it didn't
Very confusing...
Nemokosch as you can see, the first function runs 12:25
making named _optional_ arguments is probably not a good idea if you want to dispatch over named arguments
changed it to :$x! and :$y! and it worked
lizmat indeed: named optional arguments are not being used in dispatch 12:27
zacque Huh? What do you mean by "named optional arguments"? 12:32
From my POV, all arguments are compulsory? 12:33
Nemokosch no, named arguments are optional by default
zacque Huh? I don't get this
Nemokosch why not :c
zacque Oh nooo, I didn't know 😦
Oh... you mean `multi method make(:$x!, :$y!)`? 12:34
Didn't know about that as well, let me look it up 12:35
I found it: rakudocs.github.io/type/Signature#..._arguments 12:37
Thanks, that solves my problem! 12:41
Not sure why these small details keep escaping me 🤦‍♂️ 12:42
12:42 equinox36 left
lizmat well... what if all named arguments were taken into dispatch, it would get a lot more complicated and probably much slower to dispatch 12:48
by making named arguments mandatory, they effectively become positionals as far as dispatch is concerned 12:49
zacque Makes sense... 13:00
13:01 frost78 left 13:02 Newbie21 joined 13:04 jgaz joined
Newbie21 I'm trying to install Rakudo Star under WSL but the instructions seem out of date.  Are there update instructions available?  ( rakudo-star-2022.07-01.tar.gz ) 13:08
*updated 13:09
13:29 equinox joined
Nemokosch if you accept an X-Y solution: you might be better off using rakubrew under WSL, that's what I use myself 13:33
Newbie21 Will look into that. 13:40
14:34 Heptite joined 16:09 razetime joined 16:34 dakkar left 16:46 Heptite left 17:05 m_athias left 17:06 razetime left, camelia left 17:10 m_athias joined 17:12 camelia joined 17:14 m_athias left, camelia left 17:15 m_athias joined 17:23 camelia joined 17:34 Heptite joined 17:59 saint- joined 19:33 jgaz left 20:26 habere-et-disper joined 20:59 Newbie21 left 21:34 habere-et-disper left 21:40 equinox left 23:10 archenoth left 23:17 deoac joined