jhass changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Crystal 0.35.1 | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <HertzDevil> hah this book skips over untagged unions
<FromGitter> <roduquen> Hey everyone, I have an issue at compilation and I don't get how to solve it, this is the error : ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ I am on it like for 3 hours I don't get at all what's my error, thanks by advance for any help [https://gitter.im/crystal-lang/crystal?at=6008c85bdfdbc1437fa07d09]
<FromGitter> <Blacksmoke16> try doing like
<FromGitter> <Blacksmoke16> `database_query.push(elem.merge({ "_id" => id } of String | Array(String)))`
<FromGitter> <roduquen> it doesn't compile lol but I did this ⏎ ⏎ ``` database_query.push(elem)``` ⏎ ⏎ and still the same error [https://gitter.im/crystal-lang/crystal?at=6008c97f753011449b075d4b]
<FromGitter> <Blacksmoke16> only that?
<FromGitter> <roduquen> yes
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/cr dont suppose you can make a reproducible example?
<FromGitter> <roduquen> Yes give me a minute
<FromGitter> <roduquen> I did this ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=6008cb91ac653a0802d00bc4]
<FromGitter> <roduquen> and it is working on the sandbox
<FromGitter> <Blacksmoke16> hm
<FromGitter> <Blacksmoke16> must be something else going on
DTZUZU has quit [Read error: Connection reset by peer]
<FromGitter> <roduquen> Humm maybe this line could help, the previous one from compiler : ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=6008cc363855dd07fd69f8bc]
<FromGitter> <Blacksmoke16> theres obs a type mismatch going on here
<FromGitter> <Blacksmoke16> oh wait
<FromGitter> <Blacksmoke16> nvm, is diff error
<FromGitter> <Blacksmoke16> dunno, hard to say without a isolated reproducible example
<repo> Blacksmoke16: does granite have transactions? e.g. `transaction { record.destroy!; other_record.destroy! }`
<FromGitter> <Blacksmoke16> i think so
<repo> hmm
<FromGitter> <Blacksmoke16> is strange how you have to access it tho
<repo> ah was it sth like `Model.adapter.database.transaction do ...`?
<FromGitter> <Blacksmoke16> looks like it yea
<repo> i thought it wouldn't work
<repo> based on that issue
<FromGitter> <Blacksmoke16> :shrug:
<repo> hm
HumanG33k has quit [Quit: Leaving]
<straight-shoota> @roduquen This looks really weird. The implementation of Array#map should be solid.
<straight-shoota> No idea where that type mismatch might come frome
DTZUZU has joined #crystal-lang
<FromGitter> <roduquen> Wow, I reproduce the entire pattern from start to the end, and still not error on sandbox when I have one locally
<FromGitter> <Blacksmoke16> it doesnt like generics, ref https://github.com/crystal-lang/crystal/issues/8812
<FromGitter> <roduquen> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=6008cf6bac653a0802d015c6]
<FromGitter> <roduquen> With the exact same values
<FromGitter> <Blacksmoke16> prob something to do with the lib you're using then
lanodan has quit [Ping timeout: 272 seconds]
<FromGitter> <Blacksmoke16> or are you doing something else in addition to this?
<FromGitter> <roduquen> Nop nothing, I did all the func just to have the same pattern of function call
<FromGitter> <roduquen> with the types etc
lanodan has joined #crystal-lang
<FromGitter> <roduquen> I checked into the lib that's why I have this .map, it is a simple .map doing nothing special
<FromGitter> <roduquen> I check the cryomongo lib and there is this : ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ so there is really nothing weird [https://gitter.im/crystal-lang/crystal?at=6008d1df6b20cf7730c97715]
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <roduquen> lol, this do exactly the same on my project : ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ really simplified, working on sandbox, but not on local it doesn't compile [https://gitter.im/crystal-lang/crystal?at=6008d332753011449b0774df]
<FromGitter> <roduquen> Should it be like "payload" is infered ?
<FromGitter> <roduquen> Anyway, thanks for help.. I will just do db calls one by one...
<FromGitter> <Dan-Do> > https://www.couchbase.com/comparing-couchbase-vs-couchdb ⏎ ⏎ @watzon you can try Arangodb, there is already shard `arangocr`. I am using it, it's quite good.
deavmi has quit [Ping timeout: 272 seconds]
deavmi has joined #crystal-lang
<FromGitter> <watzon> I forgot about arango
<FromGitter> <watzon> @Dan-Do arangocr doesn't look like it's been touched in a while. Is it really still in a good working condition?
<FromGitter> <Blacksmoke16> should `is_a?` be more strict?
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/aa8r
<FromGitter> <Blacksmoke16> `Foo.new.is_a? Foo? # => true`
<FromGitter> <Blacksmoke16> part of me thinks it should be false since its `Foo` not `Foo?`
<FromGitter> <HertzDevil> `f.class == Foo? # => false`
<FromGitter> <HertzDevil> is probably what you want
<FromGitter> <HertzDevil> or `typeof(f) == Foo? # => false`
<FromGitter> <Blacksmoke16> good point thanks
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 272 seconds]
<FromGitter> <Blacksmoke16> raz you around?
<FromGitter> <Blacksmoke16> or repo
chachasmooth has quit [Ping timeout: 264 seconds]
chachasmooth has joined #crystal-lang
avane has quit [Quit: ZNC - https://znc.in]
<FromGitter> <dukeraphaelng> ?Hey guys, do you know how to print the full stack trace during crystal spec --error-trace? When the stack trace is too long it only prints a part of it.
avane has joined #crystal-lang
<FromGitter> <Blacksmoke16> using error-trace should print all that it has
<FromGitter> <Blacksmoke16> is it not enough to find the issue?
<FromGitter> <dukeraphaelng> nvm thanks! its just vscode being weird, the normal shell prints everything
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Dan-Do> > @Dan-Do arangocr doesn't look like it's been touched in a while. Is it really still in a good working condition? ⏎ ⏎ Sorry, I would have said that I use ArangoRb, of course with many monkey patches to convert ruby -> crystal :)
duane has quit [Ping timeout: 256 seconds]
duane has joined #crystal-lang
sagax has joined #crystal-lang
_ht has joined #crystal-lang
Stephie has quit [Quit: Fuck this shit, I'm out!]
Stephie has joined #crystal-lang
<FromGitter> <rishavs> I so want to love arango (Specially foxx) but the dev experience on it has been so bad
<FromGitter> <watzon> Why is that @rishavs?
deavmi has quit [Ping timeout: 256 seconds]
deavmi has joined #crystal-lang
<frojnd> Hi there. I'm trying to select link within a href with myhtml shard: https://github.com/kostya/myhtml/blob/056be72c23b8b77908b90d7f2a368fb866a86c02/bench/test-myhtml.cr I found this so I tried it like this: next_nav = "#{parser.css(".next-nav a").map(&.attribute_by("href")).to_a}" but I get empty array
<frojnd> I have a class .next-nav and then a href="https://link"
<FromGitter> <Dan-Do> Did you try that css selector on browser?
<FromGitter> <Daniel-Worrall> Verify your assumption and map to_html
<frojnd> Great idea,.. didn't think of that
<frojnd> How do I verify in a browser? I know how to copy css selector but how do I try my selector? From console?
<FromGitter> <Dan-Do> yeap, create a html file and open in browser, then in developer console `document.querselectorAll('css')`
<frojnd> Can I do it on a live page? `TypeError: document.querselectorAll is not a function`
<frojnd> Ah
<frojnd> Don't know why but this worked: `parser.css(".next-nav > a:nth-child(1)").map(&.attribute_by("href")).to_a`
<frojnd> So I guess my selector was wrong
<FromGitter> <Dan-Do> my bad, it should be `document.querySelectorAll`
<frojnd> Ah
<frojnd> Thank you
<FromGitter> <Dan-Do> 👍
hightower2 has joined #crystal-lang
hightower2 has quit [Read error: Connection timed out]
hightower2 has joined #crystal-lang
<frojnd> I have JSON::Any ... now there I have dates,,.. how do I match by value? Any docs appreciated
<frojnd> my `data[0]` only gives me match by index
<frojnd> data being of class JSON::Any
ua has quit [Ping timeout: 246 seconds]
ua has joined #crystal-lang
<FromGitter> <Blacksmoke16> got a code example?
<FromGitter> <Blacksmoke16> raz repo https://github.com/athena-framework/dependency-injection/pull/20/files turned out pretty cool i must say :)
<FromGitter> <Blacksmoke16> is fully compile time type safe. I.e. wont compile if you typo a param name and/or try to inject a param of an invalid type
<frojnd> @Blacksmoke16 Code example? of json file?
<FromGitter> <Blacksmoke16> of the json and what you have so far yea
<frojnd> How do I reference someone @gitter from irc?
<FromGitter> <Blacksmoke16> just like that
<frojnd> Ok
<FromGitter> <Blacksmoke16> prefix their username with an `@`
<frojnd> I'm playing in icr
<frojnd> There I can require 'json'
<frojnd> And also load a file
<frojnd> Can i do it in carc?
<frojnd> Load file
<FromGitter> <Blacksmoke16> no, but could just make a HEREDOC with the contents
<frojnd> @Blacksmoke16 https://carc.in/#/r/aa9r I just pasted content of json for a few items
<frojnd> https://jsonformatter.org/json-editor you can paste example of json in that url for nicer look
<FromGitter> <Blacksmoke16> https://carc.in/#/r/aa9t
<FromGitter> <Blacksmoke16> ogh, this json is meh. `verse_id` can either be a string or an array of strings? :/
<FromGitter> <Blacksmoke16> why not just have an array of 1?
<frojnd> Yeah... it can have also array
<frojnd> Or just string
<frojnd> But array always includes just strings
<frojnd> Also if you notices it's more than just verse_id sometimes it's also verse_day, or smth else
<frojnd> Like just verses
hightower2 has quit [Ping timeout: 264 seconds]
<FromGitter> <phillvancejr> has anyone run into undefined symbols with C++ and Crystal? ⏎ ⏎ I've written a wrapper in C to a C++ class that uses c++'s fstream library to work with files. Interestingly I found that it works fine without fstream, however as soon as I try to use fstream I get undefined symbols for std::ofstream. ⏎ ⏎ I figured it was just a matter of passing the correct c++ linker flags, however even with
<FromGitter> ... that it doesn't work. Interestingly I can compile the C++ file using clang with the same flags, but Crystal isn't able to do it [https://gitter.im/crystal-lang/crystal?at=600997ac410c221440135e71]
<FromGitter> <asterite> I guess a gist or something that shows the files and what commands you run would be helpful. Crystal can't compile C++ code
<FromGitter> <phillvancejr> I've precompiled the C++ files to object files, and Crystal is linking with normal C++ classes and even the iostream header code no problem its just fstream that is giving me problems. Here is my makefile ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60099b63a2354e44ac9b48ef]
fifr[m] has quit [Quit: Bridge terminating on SIGTERM]
<FromGitter> <asterite> I see. I know nothing about how to link against the c++ std, sorry. I do know that order passed to the linker matters, but I don't understand that either :-)
<FromGitter> <phillvancejr> Thanks for trying :) it is very strange
<FromGitter> <phillvancejr> The weirdest part is that the cc command Crystal uses on my system is clang and I can compile the same C++ file using clang with the same flags I'm passing to Crystal
<FromGitter> <asterite> Oh. So to make things a bit more clearer, the `ldflags` that you specify there are passed when linking the Crystal program object files together with that `a` file.
<FromGitter> <asterite> When you mean "can compile the same C++ file", what's that file?
<FromGitter> <asterite> Maybe you need to also link against -lfstream
fifr[m] has joined #crystal-lang
<FromGitter> <phillvancejr> You're probably right, it may be some linker flag. -lfstream doesn't work directly but this might be the right direction. The linked overflow answer says to use a C++ compiler but I don't think there is a way to make Crystal use clang++ instead of clang right?
<FromGitter> <asterite> You can do `CC=clang++ crystal ...`
<FromGitter> <andrewc910> An http response is written to the `io` of `HTTP::Server::Response` like: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ Is there anyway to get just the body of a response after it's written? I can do this `io.to_s.split("\n").last` but it doesn't feel like the best solution. ... [https://gitter.im/crystal-lang/crystal?at=6009a823cf8b82773445bd4c]
<FromGitter> <phillvancejr> Dang it still didn't work with CC=clang lol
hightower2 has joined #crystal-lang
<hightower2> Blacksmoke16 just btw, where can one read what ART, ACF etc. stand for?
<FromGitter> <Blacksmoke16> in the api docs, they just aliases for the components so there is less to type
<FromGitter> <Blacksmoke16> i.e. `ACF = Athena::Config`, `ART = Athena::Routing`
<hightower2> found it, cool
<FromGitter> <Blacksmoke16> 👍
<oprypin> hightower2, click on each tab at the top of https://athenaframework.org/Routing/ and the first thing on each page is the alias
<FromGitter> <j8r> @andrewc910 What methods are you using?
<FromGitter> <j8r> I tried `HTTP::Server::Response#output`
<FromGitter> <jrei:matrix.org> @andrewc910: I see, you're making a kind of proxy
<oprypin> @phillvancejr: compiler is irrelevant as part of Crystal invocation. everything should already have been compiler. and the linker (which is what crystal actually uses) doesn't care
<oprypin> been compiled*
<FromGitter> <j8r> @andrewc910 at least you can use `rpartition('\n')`, not sure how to improve it
<FromGitter> <oprypin:matrix.org> hightower2, click on each tab at the top of https://athenaframework.org/Routing/ and the first thing on each page is the alias
<oprypin> nice matrix caught up in 15min
<FromGitter> <jrei:matrix.org> @andrewc910: what are you using exactly?
<FromGitter> <jrei:matrix.org> I tried `HTTP::Server::Response.output.gets_to_end`
<FromGitter> <oprypin:matrix.org> j8r (https://matrix.to/#/@jrei:matrix.org) looks like people on the other side are not seeing messages from Matrix at all 😂😂
<FromGitter> <oprypin:matrix.org> it's borked
<FromGitter> <oprypin:matrix.org> for over a day now
<FromGitter> <jrei:matrix.org> true, damn
hightower2 has quit [Ping timeout: 256 seconds]
<FromGitter> <jrei:matrix.org> ho, the matrix bridge sounds to work back... a bit
<FromGitter> <andrewc910> @j8r I have tried output. That just returns the io. ⏎ ⏎ If you want to see how lambda works, here is this link: https://github.com/andrewc910/serverless.cr/blob/crambda/src/serverless/lambda/runtime.cr ⏎ ⏎ Line 68 invokes a proc. The proc may look something like this: ... [https://gitter.im/crystal-lang/crystal?at=6009b4ce36db01248a921481]
<FromGitter> <andrewc910> I can get everything from the response except the body (unless i do something hacky). I have no problem ripping the body out of the io if i know it'll work. I don't think `io.to_s.split("\n").last` is the best solution. Would it be better to read the bytes? Is there a way to open up a class and add a helper method? I just can't figure out the best solution here :/
<FromGitter> <Blacksmoke16> wouldnt that logic break if you did like `response << "foo\nbar"`?
<FromGitter> <andrewc910> Very much so.
<FromGitter> <Blacksmoke16> `split("\r\n\r\n").last`
<FromGitter> <andrewc910> That's the gap between the http info at the top and the body at the bottom right? That's definitely one option. At the end of the day, i just want something that won't break 😢
<FromGitter> <andrewc910> It's definitely better than splitting on \n lol
<FromGitter> <Blacksmoke16> i thought this sounded familar
<FromGitter> <Blacksmoke16> this is what i did
<FromGitter> <Blacksmoke16> i use it in a spec context so not something that actually gets ran in prod
<FromGitter> <andrewc910> I will give it a whirl..
<FromGitter> <Blacksmoke16> basically it adds a dedicated io to also write the content to and exposes it
<FromGitter> <Blacksmoke16> versus trying to parse the whole HTTP response
<FromGitter> <andrewc910> Yeah i like that better than doing some string manipulation. I don't particularly like monkey patching but this does feel a bit better than string spliting.
<FromGitter> <phillvancejr> @asterite @oprypin:matrix.org lol, would you believe that the problem was that I just forgot to compile my CPP.o files with the correct c++ std....
<oprypin> @phillvancejr: yes there's nothing to prevent that then, c++ destructors are unique across all programming languages basically. you need to translate it into a different idiom, which is blocks. crystal blocks are closer to c++ destructors than Crystal destructors
<FromGitter> <phillvancejr> Ok interesting. How would I do it with a block? Using ensure?
<oprypin> @phillvancejr: bind the destructor as a call of its own, make a function that creates an object, yields it, then calls the destructor
<oprypin> that's not always appropriate if the object needs to have a longer lifetime
<oprypin> in that case there's no choice but to require an explicit destroy call from the end user
<oprypin> think of File.closr
<oprypin> e*
<FromGitter> <phillvancejr> I see, interesting ok thanks that makes sense~
<FromGitter> <asterite> Even `GC.collect` is not reliable because some things might be reachable from the stack. If you do `thing = nil` but that was a union type, it might be the case that the memory address of the object is still in the stack (this could be fixed later on, though)
cloaked1 has joined #crystal-lang
cloaked1 has quit [Quit: http://quassel-irc.org - Chat comfortably. Anywhere.]
<FromGitter> <HertzDevil> crystal only uses boehm gc's c api, not the c++ api, so crystal never calls c++ destructors "natively"
f1reflyylmao is now known as f1refld
f1refld is now known as f1refly
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
hightower2 has joined #crystal-lang
postmodern has joined #crystal-lang
<_ht> While testing, it is convenient to declare some constants like MESSAGE to use throughout the test class. However, when I want to use the same constant name in another test file, I run into the issue that both contants are in the same scope.
<_ht> Should I put each test in a separate module?
<_ht> What are your suggestions?
<_ht> Of course, I can define these constants in a separate test helper file or so, but I would like to keep the definition and use of these constants close together. Plus, in one test file, it might make sense to use a different value for a constant than in another
<FromGitter> <Blacksmoke16> have you considered not using a constant
<FromGitter> <Blacksmoke16> but a method that returns some default, but optionally can return what is passed to it
<_ht> Ah, yes, that could work as well.
<_ht> But I would not like to type the argument to this method over and over. Code duplication and all
<FromGitter> <Blacksmoke16> i said optionally, i.e.
<FromGitter> <Blacksmoke16> ```def get_value(value : String?) ⏎ value || "DEFAULT VALUE" ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=6009d120a2354e44ac9be9fb]
<_ht> Yes, I understand your gist.
<FromGitter> <Blacksmoke16> ```get_value # => DEFAULT VALUE ⏎ get_value "foo" # => foo``` [https://gitter.im/crystal-lang/crystal?at=6009d137004fab474157a72c]
<_ht> This works great if the default message is used almost always
<FromGitter> <Blacksmoke16> oh i know solution
<FromGitter> <Blacksmoke16> `private MESSAGE = ""` then its scoped to that specific spec file
<_ht> Awesome!
<_ht> That works!
<_ht> I was really surprised that files do not have a private / local scope by default somehow.
<_ht> But your solution is a neat one, and more explicit. I like it!
<FromGitter> <Blacksmoke16> 👍
<_ht> Thanks, Blacksmoke16
woodruffw has quit [*.net *.split]
woodruffw has joined #crystal-lang
<hightower2> Hey I noticed that sometimes I get an error with code snippet shown not being the actual location of the error.
<hightower2> Here's an example: https://carc.in/#/r/aaax
<hightower2> (the first is error without error-trace, which reports the snippet that's not the actual error. And the second below is with error-trace, where it is visible that the error location really is)
<hightower2> Is this something that could be improved or it is what it is?
<FromGitter> <asterite> I don't understand. The two errors are the same, except the first one contains more frames?
<FromGitter> <asterite> But yes, hiding frames was the wrong thing to do. I'd like to revert that but others don't want to, so 🤷
<hightower2> Yes, but I would think that the first error should have displayed that frame in the middle.
<FromGitter> <asterite> Oh, the compiler has no way to know which frame is the one you made the mistake in
<FromGitter> <asterite> that's why it should display all frames... otherwise it's pretty much a guess... a guess I find wrong more than half the times
postmodern_ has joined #crystal-lang
postmodern has quit [Ping timeout: 256 seconds]
<hightower2> yeah probably depends on the use case.. I do find it OK in general, except for specifically this type of cases where I go to convert a variable from one type to another, program-wide.
_ht has quit [Quit: https://quassel-irc.org - Chat comfortably. Anywhere.]
<hightower2>
<hightower2> Btw, why are we allowing comparisons with things that will never match? Like, https://carc.in/#/r/aabk
<hightower2> this doesn't throw any error, yet the == comparison is completely wrong
<FromGitter> <asterite> Because otherwise comparing things when unions are involved would be a bit annoying
<hightower2> I got bitten by this numerous times in many places... like if ( something = 'x' ) and then later I realize something is "x" (a string)
<hightower2> sorry I mean something == 'x'
<hightower2> it's a huge issue I would say
<straight-shoota> not really
<hightower2> but this is a compile-time-identifiable programmer error
<hightower2> such classes were not supposed to end up comparable
<straight-shoota> the alternative would be an all-time pain in the ass
<oprypin> hightower2: check this discussion https://github.com/crystal-lang/crystal/pull/8893
<oprypin> basically same
<straight-shoota> similar, but not the same
<FromGitter> <jrei:matrix.org> why `p 'a' === 97 #=> true` but `p 'a' === "a" #=> false`?
<straight-shoota> there's an actual discussion about this
<straight-shoota> jrei: using triple equal sign for case equality operator is just a really bad decision
<straight-shoota> because it looks like an equality operator, but it's not symmetric by design
<straight-shoota> ´==>´ would've probably been a better choice
<hightower2> ok, how about... if this re. type comparison is going to stay as-is... can a command line switch be added which will just print a warning during compile when uncomparable types are compared? So a programmer can at least review them...
<hightower2> I'm gonna check whether ameba catches this
<straight-shoota> no and no
<straight-shoota> there's nothing to catch
<straight-shoota> it's not a code smell if you test for equality of different types
<hightower2> Yes I mean I don't care about categorization... it doesn't necessarily have to be bad, after all that's why ameba can add exceptions
<straight-shoota> there's nothing actionable for ameba, really
<straight-shoota> there too many good reasons for having such equality tests to report it
<straight-shoota> It might not be a bad idea to have a more strict and type safe equality operation, though
<hightower2> Is this type of comparison allowed by the compiler as a special case, or it actually stems from any class being Comparable with any other class, even if no meaningful comparison is implemented?
<straight-shoota> It's just ´Object#==(other)´ returns false
<straight-shoota> or actually ´Value#==(other)´ and ´Reference#==(other)´
<straight-shoota> and subtypes typically override ´#==(other : self)´
<hightower2> ok it's not based on Comparable then, that's good since
<straight-shoota> no, not related to Comparable
<hightower2> ok so that great, I can at least override those 2 methods quickly and add a warning print for when I want to check.
<hightower2> ok, thanks for the discussion
<straight-shoota> definitely, you can do that
<straight-shoota> it'll probably show you many cases where you wouldn't want any type restriction ;)
<hightower2> sure, that's fine
<straight-shoota> at some point I was also contemplating about == needing type safety
<straight-shoota> but that's really not a practical problem
<FromGitter> <Blacksmoke16> `<=>` will error if they aren't comparable
<hightower2> yes, that's why I was surprised why this was going on
<straight-shoota> yeah, but that's a different concept
<FromGitter> <jrei:matrix.org> <=> is for inferior/superior/eqal
<hightower2> straight-shoota, yes but you have to know the concept, and also you need to know on a class by class basis whether a Comparable or Value/Ref#== will actually end up being used.
<straight-shoota> I don't follow
<straight-shoota> what do you mean by the latter part?
<hightower2> Maybe I'm missing something, I mean when I compare two values with ==, how do I know whether the implementation of == will come from them being Comparable, or they'll fallback to being compared with Val/Ref#== ?
<straight-shoota> It's the same as with any method, the closes implementation is chosen
<straight-shoota> *closest
<hightower2> yes, that's what I mean. One must know on a class by class basis whether the == will end up comparing them through Comparable or Val/Ref==
<straight-shoota> Why do you need to know that?
<hightower2> because you just told me that there is no automated tool to tell me that, not even ameba
<hightower2> So the only way is to know manually
<straight-shoota> But *why* do you need to know that?
<hightower2> because I just spent a lot of time figuring out why (something & something) != 0 was giving me true when it wasn't
<straight-shoota> btw. many types define custom equality methods and don't use the defaults from Reference or Struct or so
<straight-shoota> sry, I have no idea what you're talking about
<FromGitter> <Blacksmoke16> fwiw `&` for enums prob means something diff than other somethings
<hightower2> ok anyway, don't wanna monopolize the chat, it was a worthwile lesson in any case. I added a warning print to Value/Ref#== and caught some comparisons of Char to String which I didn't know where happening (and failing)
<FromGitter> <Blacksmoke16> this is why you should write specs 😉
<FromGitter> <Blacksmoke16> https://carc.in/#/r/aabr
<FromGitter> <Blacksmoke16> it was returning the `None` enum, which isnt the same as `0`
<FromGitter> <Blacksmoke16> but `None.value == 0 # => true`
<straight-shoota> > this is why you should write specs 😉
<straight-shoota> exactly
<hightower2> Blacksmoke16 yes that was my whole point... I didn't know that this was returning an enum type rather than an integer
<straight-shoota> hightower2, okay I just see ne reason why you would need to know *how* an equality operator is implemented
<hightower2> and the compiler didn't warn me
<straight-shoota> The implementation should always make sense, if it doesn't, it needs to be fixed
hightower2 has quit [Read error: Connection reset by peer]
hightower2 has joined #crystal-lang
<hightower2> I am reviewing the logs from a warning print in Value/Ref#==, and wondering whether this issue could have been solved by having == work only when coming from Comparable (and erroring otherwise), and having an operator similar but different than == which would be used when you don't want to prevent comparing uncomparable types (like all those cases listed in #2996 etc.)
<DeBot> https://github.com/crystal-lang/crystal/pull/2996 (Add restrictions to collection methods. Fixes #1764. Fixes #988)
<hightower2> That operator could have been named =? for example. Like:
<hightower2> "a" == 'a' ==> compile error (and the only sane thing to do, unless the user really makes these two types Comparable or defines a custom ==)
<hightower2> "a" =? 'a' ==> false (the same what == currently does)
<straight-shoota> yeah, type safe equality would be useful at times
<straight-shoota> in fact, I've been preparing an RFC on that topic
<oprypin> please do it as `====` operator
<straight-shoota> good idea :+1:
<straight-shoota> I've seen use cases mostly for specs, though
<straight-shoota> like when I want to ensure an array contains only Int32 values, I can't use ´Array#==´ for that
<straight-shoota> I also need to check the type of each value (or the Array's generic type argument)
<straight-shoota> oprypin, next cool thing is `==^==` operator btw. :D
<straight-shoota> not sure about the semantics, but it looks cool
<FromGitter> <Blacksmoke16> `$a -=- $b;` and `$a = $a +-0-+ 3;` 😆
<FromGitter> <asterite> It would be nice if equality was type safe. Someone can try it and see how hard it is to make the std specs pass with that change, and how the code changes.
aquijoule_ has quit [Remote host closed the connection]