ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Fund Crystal's development: | GH: | Docs: | Gitter:
jmdaemon has joined #crystal-lang
waleee has quit [Ping timeout: 272 seconds]
waleee has joined #crystal-lang
waleee has quit [Ping timeout: 240 seconds]
waleee has joined #crystal-lang
waleee has quit [Ping timeout: 260 seconds]
jmdaemon has quit [Quit: ZNC 1.8.2 -]
jmdaemon has joined #crystal-lang
waleee has joined #crystal-lang
waleee has quit [Ping timeout: 240 seconds]
waleee has joined #crystal-lang
waleee has quit [Ping timeout: 240 seconds]
avane_ has quit [Ping timeout: 252 seconds]
avane has joined #crystal-lang
jmdaemon has quit [Ping timeout: 252 seconds]
jmdaemon has joined #crystal-lang
oz has quit [Quit: EOF]
ox has joined #crystal-lang
jmdaemon has quit [Ping timeout: 272 seconds]
renich has joined #crystal-lang
renich has quit [Remote host closed the connection]
notzmv has quit [Ping timeout: 252 seconds]
<FromGitter> <backward-crazy-mage-puppy-36> If anyone has figured out how to require amber application in the new crystal interpreter please let me know. Thanks.
notzmv has joined #crystal-lang
jmdaemon has joined #crystal-lang
jmdaemon has quit [Ping timeout: 240 seconds]
HumanG33k has quit [Quit: WeeChat 3.0]
HumanG33k has joined #crystal-lang
<FromGitter> <Blacksmoke16> It's still experimental so doubt it would work
<FromGitter> <domgetter> Woohoo! I've successfully cut the linking step down by a huge factor. Got "hello world" from ~8s to compile down to ~4s by making the linker flag resolution concurrent. My ~6000 LOC project is now ~8s instead of ~12s (non-release).
<FromGitter> <domgetter> There is probably some more optimization to be done there, but that seemed to be the lowest-hanging fruit.
<FromGitter> <Blacksmoke16> 🚀
<FromGitter> <domgetter> The issue and pull request are up if you want to check them out
<FromGitter> <Blacksmoke16> can you add like `Resolves #11888` to the desc so it links correctly?
<FromGitter> <domgetter> done
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <domgetter> If I want to sort an array of tuples, would it be something like `array_of_person_tuples.sort_by {|(name, age)| age}` ?
<SamantazFox> `array_of_person_tuples.sort_by(&.age)`
<SamantazFox> that's shorter ^^
<FromGitter> <Blacksmoke16>
<FromGitter> <Blacksmoke16> wont work, there is no `#age` method
<FromGitter> <Blacksmoke16> since its a tuple
<SamantazFox> Oh, it's not named :x
<FromGitter> <Blacksmoke16> could also use `#sort_by!` if that makes sense in this context
<SamantazFox> my bad
jmdaemon has joined #crystal-lang
ur5us has joined #crystal-lang
ur5us has quit [Quit: Leaving]
ua_ has quit [Quit: Leaving]
<SamantazFox> Hello there!
<SamantazFox> Why am I getting this error?
<SamantazFox> reduced the code as much as possible
ua_ has joined #crystal-lang
<FromGitter> <domgetter> You defined the `format_features` method with `self.` which makes it defined on the `Filters` struct rather than instances of that struct.
<FromGitter> <domgetter> So either make it `[Filters.format_features(@features)]` when you call it, or redefine it to `def format_features(features : Features)`
<SamantazFox> it needs to be static, because it's used outside of an instanciated object
<SamantazFox> And why one has to use the struct/class name inside said class/struct?
<FromGitter> <Blacksmoke16> `self.class.format_features @features`
<FromGitter> <domgetter> `to_iv_params` is an instance method, so you're in an instance of the class inside that method instead of "in the class"
<SamantazFox> yeah, but why the instance doesn't contain all the class methods?
<FromGitter> <domgetter> I guess I'd say from a language design perspective, it's because those method names are in a different scope. One is in "the scope of an instance of a class" and the other is in "the scope of the class"
<FromGitter> <Blacksmoke16> ^
<FromGitter> <domgetter> The reason works and doesn't is because `foo` and `bar` are in the same scope in Test 1. That is, they are both `self.`. Whereas in Test2, `foo` is in one scope, and `bar` is in another.
<FromGitter> <domgetter> So when `Test2#foo` calls `bar`, it doesn't find it, since there is no instance method called `bar` defined on `Test2`. There is just the class method by the same name
<SamantazFox> ok, but why does it work with "new", then?
<FromGitter> <Blacksmoke16> the compiler creates that method for you
<FromGitter> <Blacksmoke16> which is a class method. I.e. the method you call when you do like ``
<SamantazFox> which calls `initialize`, right?
<FromGitter> <Blacksmoke16> yea
<SamantazFox> and `initialize` doesn't have `self.`
<FromGitter> <Blacksmoke16> initialize is an instance method
<FromGitter> <Blacksmoke16> its what initializes the data within the instance
<SamantazFox> that makes sense, but that's weird
<FromGitter> <Blacksmoke16> whats weird about it?
<SamantazFox> that you can't access the class methods from an instance of said class
<SamantazFox> that kinda goes against established OOP logic
<FromGitter> <Blacksmoke16> you deff can, just not w/o a receiver
<FromGitter> <Blacksmoke16> either needs to be like `self.class` or `TheClass`
<SamantazFox> what is `self.class`?
<FromGitter> <Blacksmoke16> essentially the same thing as hard coding the class name, but would support subclasses iirc
<SamantazFox> Ah, ok
<SamantazFox> honnestly, this is super counter-intuitive
<FromGitter> <Blacksmoke16> not really, they'd diff scopes
<FromGitter> <Blacksmoke16> they're*
<SamantazFox> problem is that it's not what the compiler says xD
<FromGitter> <Blacksmoke16> hm?
<SamantazFox> `Error: undefined method 'format_features' for Invidious::Search::Filters`
<SamantazFox> but the (class) method is indeed here
<FromGitter> <Blacksmoke16> right, are calling an instance method that doesnt exist
<FromGitter> <Blacksmoke16>
<FromGitter> <Blacksmoke16> notice in the class scope its `Test.class` not `Test`
<FromGitter> <Blacksmoke16> the latter refers to the instance, while `.class` means its the metaclass of that type
<SamantazFox> yeah, that's not very intuitive...
<FromGitter> <Blacksmoke16> so again, the reason you get that error is there is no *instance* method called `format_features` on that type
<FromGitter> <Blacksmoke16> :shrug: just how things work
<FromGitter> <Blacksmoke16> pretty this is how it works in most languages too no?
<SamantazFox> nope
<SamantazFox> a class is a whole scope. And methods defined as `static` can be acessed from the outside (= without needing to instanciate said class)
<FromGitter> <Blacksmoke16> right, thats how crystal works too
<FromGitter> <> shouldn't this be a more explicit exception? 🤔
<FromGitter> <Blacksmoke16> like what? dont really have something more specific atm
<FromGitter> <Blacksmoke16> related:
<FromGitter> <> well, i had to put if `ex.message == "This HTTP::Client cannot be reconnected"` into my connection pool, that feels wrong
<FromGitter> <> something like This::HTTP::Client::CannotBeReconnected 🤷
<SamantazFox> Blacksmoke16: Well, the example I gave (calling `` from instanciated `bar`) would work in C++ or PHP, but not in Crystal
<FromGitter> <Blacksmoke16> bring it up in that ticket maybe
<FromGitter> <> yeh will do some reading and maybe writing later 🧐
<FromGitter> <Blacksmoke16> pretty sure it wouldnt work in php
<FromGitter> <Blacksmoke16> php always requires a receiver, so its not exactly the same comparison
<FromGitter> <> it's too logical
<FromGitter> <> in most other languages `self` semantics are a trainwreck
<SamantazFox> in PHP, you can call a static method by doing `Class::method` if called from the outside, or `self::method` if canlled from an instance
<FromGitter> <Blacksmoke16> right
<FromGitter> <Blacksmoke16> hows that any diff than Crystal's `Class.method` or `self.class.method`
<FromGitter> <Blacksmoke16> or like `{{ @type }}.method`
<FromGitter> <Blacksmoke16> somewhat expected,
<FromGitter> <Blacksmoke16> using `self` within an initializer has its own set of "unique" behavior
<SamantazFox> .....
<SamantazFox> but, whyyyy ;_;
<FromGitter> <Blacksmoke16> because if you pass `self` to some other method, its possible that it could use values that havent yet been initialized
<FromGitter> <Blacksmoke16> leading to bugs/undefined behavior
<SamantazFox> Ah, I see
<SamantazFox> Should I open an issue regarding the error messages, btw?
<FromGitter> <Blacksmoke16> what about them?
<FromGitter> <Blacksmoke16> `Error: undefined method 'format_features' for Invidious::Search::Filters` you mean?
<SamantazFox> yeah
<SamantazFox> because "undefined method" is technically wrong
<FromGitter> <Blacksmoke16> its not tho
<FromGitter> <Blacksmoke16> there is no instance method called `format_features`
<SamantazFox> `undefined instance method` would be accurate
<FromGitter> <Blacksmoke16> could be argued thats clear from the type
<FromGitter> <Blacksmoke16> but :shrug: guess it wouldnt hurt
<SamantazFox> When I went to `Invidious::Search::Filters` and searched for `format_features`, said method was indeed here
<FromGitter> <Blacksmoke16> its a subtle thing for sure
<FromGitter> <Blacksmoke16> have to notice there is no `.class` and no `self.` or `extend self`
<SamantazFox> I didn't know you could `extend self` a class/struct O.o
<SamantazFox> I thought it was only for modules
<FromGitter> <Blacksmoke16> correct
<FromGitter> <Blacksmoke16> but that filters type could have been a module
<FromGitter> <Blacksmoke16> not based on the error message tho, but in general it could have been if you just saw `Invidious::Search::Filters`
<SamantazFox> yeah, but in 2022, I'd expect the compiler to be a bit more verbose :P
<FromGitter> <Blacksmoke16> :shrug: make an issue and see what happens
<FromGitter> <Blacksmoke16> or at least search first*
<FromGitter> <> agree
<SamantazFox> yeah, I'll do that
<FromGitter> <> if the compiler knows what type of method its looking for, it should say so in the error