ChanServ changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | 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> <oprypin:matrix.org> js (https://matrix.to/#/@js:nil.im): you dont need to search, just read it all pls.
<FromGitter> <js:nil.im> I usually look up the stuff that I need as I go πŸ™‚
hendursa1 has quit [Quit: hendursa1]
hendursaga has joined #crystal-lang
<FromGitter> <js:nil.im> https://crystal-lang.org/api/0.24.2/Random.html is missing the most important detail: Whether this is a cryptographic random number generator
<FromGitter> <Blacksmoke16> old docs btw
<FromGitter> <js:nil.im> oh, interesting
<FromGitter> <js:nil.im> first google result is old
<FromGitter> <js:nil.im> the newer one has something
<FromGitter> <js:nil.im> would it be a good idae to add a banner to old documentation pointing out that you are looking at old documentation and a link to the current one?
<FromGitter> <js:nil.im> it recommends https://crystal-lang.org/api/0.36.1/Random/ISAAC.html, but it doesn't really say what that is?
<FromGitter> <Blacksmoke16> you prob want `Random::Secure`
<FromGitter> <js:nil.im> ah, thx. Never heard of that one before
<FromGitter> <oprypin:matrix.org> > I usually look up the stuff that I need as I go πŸ™‚ ⏎ ⏎ i'm not messing around, like seriously, it's really short and you'll just know everything
<FromGitter> <js:nil.im> hmm, maybe a good idea. I thought it was too much to read it one go, but given the recommendation, I suppose it can't be that long πŸ™‚
<FromGitter> <js:nil.im> hmm, I noticed that there's `property :foo` and `property foo` in the docs. Which one is preferred? And apparently there's also `property @foo`
<FromGitter> <Blacksmoke16> `property foo : String`
<FromGitter> <Blacksmoke16> or whatever type it is
<FromGitter> <js:nil.im> so without the :, ok :)
<FromGitter> <Blacksmoke16> and with the type
<FromGitter> <js:nil.im> well optionally
<FromGitter> <js:nil.im> if I have `def initialize(@foo : String)`, I'm not gonna need it, right
<FromGitter> <Blacksmoke16> no, but imo its still good to have
<FromGitter> <Blacksmoke16> e.g. so the generate methods have the type restrictions, and for docs
<FromGitter> <Blacksmoke16> iirc the error message would also be diff
<FromGitter> <js:nil.im> I see
<FromGitter> <js:nil.im> thx
<FromGitter> <js:nil.im> I might be missing something obvious, but https://crystal-lang.org/reference/syntax_and_semantics/methods_and_instance_variables.html does not mention how I can access an ivar that is not on self
<FromGitter> <Blacksmoke16> `property` defines a getter
<FromGitter> <js:nil.im> e.g. if I have `def dup`, how can I access @foo on the copy? `copy.@foo = 1234` doesn't work
<FromGitter> <js:nil.im> so I have to have a getter, no way to directly access the ivar?
<FromGitter> <js:nil.im> because this is internal state that I copy but do not want to expose
<FromGitter> <Blacksmoke16> wellllll, that latter syntax *does* work, but it's not suggested to use that unless you *really* have a good reason
<FromGitter> <Blacksmoke16> got a playground link of what you're trying to do?
<FromGitter> <js:nil.im> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60402c4195e23446e40eafb3]
<FromGitter> <js:nil.im> the last_reload is not something that should have a setter
<FromGitter> <Blacksmoke16> why not just `Setting.new(@static_hosts, ...)`?
<FromGitter> <js:nil.im> but if you dup, it should make it to the copy
<FromGitter> <js:nil.im> oh, you mean have a new, private initializer?
<FromGitter> <Blacksmoke16> sure
<FromGitter> <js:nil.im> because currently none of those are in the initializer, as they are all parsed from configs
<FromGitter> <Blacksmoke16> are you sure you need to define `dup` tho? Pretty it should just work
<FromGitter> <Blacksmoke16> yaml config?
<FromGitter> <js:nil.im> system config
<FromGitter> <js:nil.im> and yes, I need the dup - I need to keep the config as of the moment I sent the query
<FromGitter> <js:nil.im> if the config changes in between, it still needs to be performed with the old settings
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/ahol i mean this, `dup` is already defined. Just returns the same obj but with a diff obj id
<FromGitter> <js:nil.im> if I don't define it I get an error :/
<FromGitter> <js:nil.im> maybe I should figure out why that is instead
<FromGitter> <js:nil.im> oh, it was a missing type πŸ˜€
<FromGitter> <js:nil.im> I had @settings = settings.dup
<FromGitter> <js:nil.im> and it could not infer the type from that
<FromGitter> <js:nil.im> if I added @settings : Settings, it works
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <Blacksmoke16> its better to be explicit imo
<FromGitter> <js:nil.im> something else I'm not getting from the documentation: If I declare a block as part of the arguments, can I capture it *and* yield it?
<FromGitter> <js:nil.im> Basically, the block would be `Response | Error`
<FromGitter> <js:nil.im> on error, I could yield early
<FromGitter> <js:nil.im> (for some, that is)
<FromGitter> <js:nil.im> but for others, I'd need to capture it and call it later
<FromGitter> <js:nil.im> yes that's what I read exactly
<FromGitter> <js:nil.im> it doesn't talk about mixing
<FromGitter> <Blacksmoke16> prob just use two diff overloads?
<FromGitter> <Blacksmoke16> can pass the capture block to the yielding method
<FromGitter> <Blacksmoke16> but, any reason to not just use exceptions here?
<FromGitter> <js:nil.im> how can you use exceptions in async code?
<FromGitter> <js:nil.im> wouldn't that unwind to the wrong place?
<FromGitter> <js:nil.im> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=6040308122a5ce4a913065d4]
<FromGitter> <js:nil.im> is what I currently have
<FromGitter> <Blacksmoke16> `loop do` πŸ˜‰
<FromGitter> <Blacksmoke16> but hmm
<FromGitter> <js:nil.im> that I had at first, but then it complained about id being read before being set
<FromGitter> <js:nil.im> it seems the compiler can prove the while true happens, but cannot prove it for loop do
<FromGitter> <Blacksmoke16> interesting, because `loop do` is literally just like ⏎ ⏎ ```def loop ⏎ while true ⏎ yield ⏎ end ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=604030e495e23446e40eba42]
<FromGitter> <Blacksmoke16> :S
<FromGitter> <Blacksmoke16> prob something to do with blocks or something
<FromGitter> <js:nil.im> that was my guess, too
<FromGitter> <js:nil.im> that the compiler cannot prove the block gets called
<FromGitter> <js:nil.im> anyway, the error in this case an also come from the nameserver
<FromGitter> <js:nil.im> what I do in my ObjC code is have an exception, but I don't throw it, I pass it around as an error argument
<FromGitter> <Blacksmoke16> but regarding your thing, disregard what i said, as they're the yielded arguments, not the response
<FromGitter> <Blacksmoke16> also unless you're using fibers, passing a capture block around isn't technically async. It would be more like delaying the invocation of the code
<FromGitter> <js:nil.im> I suppose there will be fibers as soon as I use sockets
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <js:nil.im> otherwise the non-blocking DNS resolver will, well, not be non-blocking πŸ˜‰
<FromGitter> <js:nil.im> ok, pushed my current state
<FromGitter> <js:nil.im> https://fossil.nil.im/asyncdns-cr/dir?ci=tip&name=src in case someone feels like early reviewing
<FromGitter> <js:nil.im> the goal is definitely to get this into a state where it can be part of stdlib, to have non-blocking DNS lookups in Crystal πŸ™‚
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/toplevel.html#record(name,*properties)-macro might be helpful to you
<FromGitter> <Blacksmoke16> this would help with your other issue, i.e. `context.id` versus `context.@id`
<FromGitter> <Blacksmoke16> as majority of the time you really shouldnt be accessing internal state like that
<FromGitter> <Blacksmoke16> `super(name, DNSClass::IN, RRType::A, ttl)` symbols are autocasted to enum members. So could do something like `super name, :in, :a, ttl` Just something to keep in mind/save some keystrokes
<FromGitter> <jrei:matrix.org> @alexherbo2: what's the difference with https://crystal-lang.org/api/master/Process.html#quote(args:Enumerable(String)):String-class-method
richbridger has quit [Remote host closed the connection]
<FromGitter> <js:nil.im> @Blacksmoke16: ah, thx πŸ™‚ will change those
<FromGitter> <js:nil.im> but the symbols should be lowercase, not uppsercase?
<FromGitter> <Blacksmoke16> doesnt actually matter
<FromGitter> <js:nil.im> what's preferred? consistency with the enum name or the lowercase symbols convention?
<FromGitter> <Blacksmoke16> i usually use lower snake case
<FromGitter> <Blacksmoke16> e.g. `:foo` or `:some_key` for `Foo` and `SomeKey`
richbridger has joined #crystal-lang
<FromGitter> <js:nil.im> but enums are always upper, aren't they?
<FromGitter> <Blacksmoke16> they have to start with a capital letter. I never know how i want to have them :/
<FromGitter> <Blacksmoke16> they're technically constants, but not really constants :shrug:
<FromGitter> <js:nil.im> ah, I just noticed that if I use the symbol trick, I need to put the type in the initializer. So just putting it to the property doesn't work
<FromGitter> <Blacksmoke16> they're equivalent, mainly was just making you aware. Is up to you on which you want to use
<FromGitter> <js:nil.im> I mean, having to add more types is a downside ;)
<FromGitter> <Blacksmoke16> if you say so
<FromGitter> <js:nil.im> is it preferred to repeat types everywhere?
<FromGitter> <Blacksmoke16> to me yes, esp if it's something you're planning on making public. As the only thing you're saving is a few keystrokes
<FromGitter> <js:nil.im> e.g. ⏎ ⏎ ```property foo : String ⏎ ⏎ def initialize(@foo) ⏎ end``` ⏎ ⏎ ? [https://gitter.im/crystal-lang/crystal?at=60403e3be562cf54ac98f57b]
<FromGitter> <Blacksmoke16> but losing better docs, error messages, etc
<FromGitter> <Blacksmoke16> i usually do both
<FromGitter> <Blacksmoke16> the former
<FromGitter> <js:nil.im> ok
<FromGitter> <js:nil.im> so basically never use type inference?
<FromGitter> <js:nil.im> shouldn't the documentation use the compiler and use the inferred types to fix that?
<FromGitter> <Blacksmoke16> :shrug: probably?
DTZUZU has joined #crystal-lang
postmodern has joined #crystal-lang
<FromGitter> <js:nil.im> @Blacksmoke16: Like this? https://fossil.nil.im/asyncdns-cr/info/c210ddc089b9b014
<FromGitter> <Blacksmoke16> thats my preferred style yea, but im sure others have their own opinions on it
skrzyp has joined #crystal-lang
<FromGitter> <oprypin:matrix.org> type inference is still done. type restrictions only *restrict* the allowed outcomes.
<FromGitter> <oprypin:matrix.org> im nitpicking here though
<FromGitter> <oprypin:matrix.org> > shouldn't the documentation use the compiler and use the inferred types to fix that? ⏎ ⏎ generally it's super hard to correctly automatically collapse whatever was inferred to a declaration that is readable
<FromGitter> <oprypin:matrix.org> it could just turn out wrongly inferred. say a function is only ever used with one type but actually it can accept any type
<FromGitter> <HertzDevil> > that I had at first, but then it complained about id being read before being set ⏎ ⏎ that's because `loop` creates a new scope and `while` doesn't
<FromGitter> <HertzDevil> you could do `while false` and any variables declared within will still be accessible afterwards, only that they'll be nil
_ht has joined #crystal-lang
robertmeta_ has joined #crystal-lang
issyl0_ has joined #crystal-lang
avane_ has joined #crystal-lang
oprypin_ has joined #crystal-lang
lanodan_ has joined #crystal-lang
oprypin has quit [*.net *.split]
avane has quit [*.net *.split]
robertmeta has quit [*.net *.split]
FromGitter has quit [*.net *.split]
issyl0 has quit [*.net *.split]
lanodan has quit [*.net *.split]
robertmeta_ is now known as robertmeta
issyl0_ is now known as issyl0
avane_ is now known as avane
FromGitter has joined #crystal-lang
hendursa1 has joined #crystal-lang
hendursaga has quit [Ping timeout: 268 seconds]
<FromGitter> <asterite> Also, to capture a block and yield it, you don't use yield: you use call on the block
<frojnd> Hm... why this won't work? https://carc.in/#/r/ahr2 from_json
<FromGitter> <erdnaxeli:cervoi.se> verses is an array, `verses[0].date` works
<FromGitter> <erdnaxeli:cervoi.se> but you function foo return nothing
<frojnd> No I missed array, thank you
<FromGitter> <erdnaxeli:cervoi.se> oh no it returns something, why?
<FromGitter> <erdnaxeli:cervoi.se> ok that's why: https://crystal-lang.org/api/0.36.1/toplevel.html#pp(**objects)-class-method
<frojnd> pp vs puts was also interesting while learning crystal
richbridger has quit [Ping timeout: 256 seconds]
postmodern has quit [Quit: Leaving]
bougyman has quit [Excess Flood]
bougyman has joined #crystal-lang
<FromGitter> <Blacksmoke16> There's also p and p! Iirc
<FromGitter> <erdnaxeli:cervoi.se> and pp!
deavmi has quit [Ping timeout: 258 seconds]
deavmi has joined #crystal-lang
_ht has quit [Remote host closed the connection]
_ht has joined #crystal-lang
teardown has quit [Ping timeout: 268 seconds]
teardown has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
lanodan_ is now known as lanodan
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
fifr` has quit [Ping timeout: 245 seconds]
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
fifr` has joined #crystal-lang
HumanG33k has quit [Ping timeout: 276 seconds]
<FromGitter> <roduquen> Hi everyone, I got an issue with websocket server that I don't get between Crystal and js, I do a simple ws server : ⏎ ⏎ ```ws = WebSocket.new("ws://localhost:5060/");``` ⏎ ⏎ I got : Firefox can’t establish a connection to the server at ws://localhost:5060/ ... [https://gitter.im/crystal-lang/crystal?at=60411c79d71b6554cd2004e8]
<FromGitter> <roduquen> I never had this error in 0.35.1 and have already 3 websockets server running on aws with 0.35.1, I don't know if it is about 0.36.1
HumanG33k has joined #crystal-lang
richbridger has joined #crystal-lang
<FromGitter> <roduquen> Does anyone ever meet this issue ?
<FromGitter> <Blacksmoke16> i assume you're using the same host and port in both cases?
<FromGitter> <Blacksmoke16> could try making the host like `"0.0.0.0"`
<FromGitter> <roduquen> yep I use this host
<straight-shoota> what's `WebSocket.handler()`?
<straight-shoota> Maybe try some other browsers or websocket client, maybe you can get some debug info (or try to see what's going on in firefox)
<straight-shoota> Alternatively, you could add debug info into Crystal's websocket implementation, but client debugging seems like a better idea
<FromGitter> <jrei:matrix.org> for me localhost bind do ::1, not 127.0.0.1
<FromGitter> <jrei:matrix.org> ```$ ping localhost ⏎ PING localhost(localhost (::1)) 56 data bytes``` [https://gitter.im/crystal-lang/crystal?at=60412b93e8267a46f2f0e1f8]
<FromGitter> <jrei:matrix.org> Try listening to `::1`
<straight-shoota> oh yeah right, it's probably a problem that firefox can't even establish a TCP connection. I assumed it might be the WS handshake.
hightower2 has joined #crystal-lang
<FromGitter> <jrei:matrix.org> I recommend you to do like this: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60412c635d0bfb4e58889725]
<FromGitter> <jrei:matrix.org> this way it is clear what address is used
<hightower2> Hey friends, just a nice success - for a customer I had to rewrite some python stuff to be more performant (some code which combines http, rabbit, and redis). The desired target was to achieve 1M requests per hour. Even without -Dpreview_mt, the end result was 2.5M requests/hour.
<straight-shoota> nice
<straight-shoota> however, it might just be a testimony that Python's inefficiency was accepted as normal :D
<FromGitter> <jrei:matrix.org> great :)
<FromGitter> <jrei:matrix.org> what was the previous actual rate per hour?
<straight-shoota> Btw. multithreading might not really make a web app faster. Likely even worse than running multiple single-thread processes.
<hightower2> jrei: was interested in it myself too, but hard to tell... in the end didn't get figures from them, and didn't bother to check myself
<hightower2> will report just for info in case I hear about it tomorrow
<hightower2> straight-shoota, right, that was my other plan... haproxy is already in front of everything, so easy job to just multiply workers
<straight-shoota> you can also just use SO_REUSEPORT
<hightower2> yes, yes, but it's distributed across multiple machines etc., so
<hightower2> plus haproxy is used for a ton of stuff other than just pure load balancing (ddos protection, retries, ssl, rate limiting, etc.)
<straight-shoota> yeah, but on each machine you can use that. they'll likely have multiple CPU cores, right? =)
<straight-shoota> so you go haproxy -> port on worker instances -> multple processes with SO_REUSEPORT
<hightower2> ah yes, that's a nice trick too, even though there's no control which process will take it. So retries, which they always send to a different process, may land on the same one multiple times
<straight-shoota> if haproxy distributes over different instances...
<hightower2> that's a good idea, I'll think about it some more, thanks
<FromGitter> <jrei:matrix.org> Multi process would be better
<FromGitter> <jrei:matrix.org> Multi thread don't scale linearily
<FromGitter> <jrei:matrix.org> Plus, it won't be as stable – it is still a preview
<straight-shoota> yeah, the last few comments were about whether multiplexing on a single machine happens over SO_REUSEPORT or if just every process is a separate backend for haproxy (with its own port)
<FromGitter> <jrei:matrix.org> I just read about SO_REUSEPORT and what it does.
<FromGitter> <jrei:matrix.org> Sound better to let HAProxy do the dispatch instead of the machine's OS
<FromGitter> <jrei:matrix.org> The main thing I've in mind is healthcheck
<FromGitter> <roduquen> @jrei:matrix.org Thanks, I got this when I do the puts on logs 'Board WebSocket Server Listening on 0.0.0.0:5060', I always use puts I never took time to read logs I have them in my docker logs on aws... I guess it should probably be better to use Log API.. I don't remember the way to go through crystal master instead of regular
<FromGitter> <roduquen> And I didn't get the listen on ::1, the same on aws happened, the address is "wss://dev.wss.remotings.com:5060"
<FromGitter> <roduquen> It works with Crystal WebSocket Client API but JS WebSocket API still not succeed to connect
<FromGitter> <roduquen> (I meant I don't know what means listen on ::1)
<FromGitter> <jrei:matrix.org> You're on docjer?
<hightower2> roduquen localhost on ipv6
<FromGitter> <roduquen> Locally not but on AWS yep
<FromGitter> <jrei:matrix.org> Try the basic example from the API docs
fifr` has quit [Ping timeout: 260 seconds]
<FromGitter> <jrei:matrix.org> Or a similar basic one. Of it works, you can start from there
<FromGitter> <roduquen> ```WebSocket.run("0.0.0.0", 5060)``` [https://gitter.im/crystal-lang/crystal?at=604135da120cd84f78f407ec]
<FromGitter> <roduquen> it is on a module but no classes
<FromGitter> <roduquen> I wrote new servers in a more functionnal way
<FromGitter> <roduquen> But I guess it couldn't be an issue
<FromGitter> <roduquen> I ll try through Chrome to check
<FromGitter> <roduquen> Same issue, I can't get to the connection I tried https://www.websocket.org/echo.html, with the address and can't connect, when with the websocket client from crystal I can
<FromGitter> <jrei:matrix.org> Also why are you putting the method name in case of an exception
<FromGitter> <roduquen> I don't really know my logs are really bad globally
<FromGitter> <jrei:matrix.org> It will be already present in the trace with `exception.inspect_with_backtrace`
<FromGitter> <roduquen> I spend more time spamming travis with new puts
<FromGitter> <jrei:matrix.org> (I recommend to put this in STDERR)
<FromGitter> <roduquen> Oh well
<FromGitter> <roduquen> :facepalm:
<FromGitter> <jrei:matrix.org> You're on what OS?
<FromGitter> <roduquen> Ubuntu
<FromGitter> <roduquen> 1) 04
<FromGitter> <roduquen> same on AWS
<FromGitter> <roduquen> the dockers are running on CENTOS but on aws ubuntu 20.04
<FromGitter> <roduquen> (I meant I created the EC2 on ubuntu but dockers are running through centos, I use bintray docker for crystal)
<FromGitter> <roduquen> ```code paste, see link``` ⏎ ⏎ like a simple one ⏎ I guess it is the most reproductible environment I can give my computer is not the most setted up I use to try online directly because of ssl [https://gitter.im/crystal-lang/crystal?at=604138c9d71b6554cd205e7d]
<FromGitter> <jrei:matrix.org> and with a simple HTTP server?
<FromGitter> <roduquen> Works fine
<FromGitter> <jrei:matrix.org> O.o
<FromGitter> <roduquen> There is also an HTTP server listening on 5020 on the same service
<FromGitter> <roduquen> With exactly the same pattern
<FromGitter> <roduquen> Just not on websocket
<FromGitter> <jrei:matrix.org> you can have the ws and HTTP on the same port
<FromGitter> <jrei:matrix.org> websocket is http, at least at the beginning
<FromGitter> <roduquen> Oh ok I didn't know I separated everything on terraform
<FromGitter> <jrei:matrix.org> I've a case/when, which either serve the API or ws
<FromGitter> <roduquen> Oh ok like this, cause I try the idiot way doing both servers on same ports I got ```Unhandled exception in spawn: Could not bind to '0.0.0.0:5020': Address already in use (Socket::BindError) ⏎ from /usr/share/crystal/src/socket/addrinfo.cr:75:15 in 'initialize:reuse_port' ⏎ from /usr/share/crystal/src/socket/tcp_server.cr:32:3 in 'new:reuse_port' ⏎ from /usr/share/crystal/src/http/server.cr:211:5
<FromGitter> ... in 'bind_tcp' ⏎ from lib/kemal/src/kemal.cr:52:7 in 'run' ... [https://gitter.im/crystal-lang/crystal?at=60413a6444f5a454a454f1d4]
<FromGitter> <roduquen> But could connect now even if the normal server isn't running now
<FromGitter> <roduquen> I meant the HTTP normal
<FromGitter> <roduquen> Is 5060 a bad port I ll try an other lol
<FromGitter> <roduquen> No unfortunately, but what I can see is only one server running and it accepts websocket connection
<FromGitter> <roduquen> from Firefox
<FromGitter> <roduquen> And in any cases Crystal WebSocket client works
HumanG33k has quit [Ping timeout: 260 seconds]
<FromGitter> <roduquen> really weird, when I launch only one server on 5020, the websocket ones, I cant connect through firefox, when I try to launch both on 5020, the restful one crashes but I can connect to the websocket one
<FromGitter> <roduquen> I tried to inverse the spawn but did nothing
<FromGitter> <roduquen> And it works really lol
<FromGitter> <roduquen> When the first one crashes
<FromGitter> <roduquen> I guess the first one even if spawned influenced the websocket once, in a good and bad way at the same time
<FromGitter> <roduquen> When crashes it works, when not here it doesn't work
<FromGitter> <roduquen> Well I think I go through the problem step by step, When not here I let the require
<FromGitter> <roduquen> But without that require of restful one, I could connect through websocket
<FromGitter> <roduquen> And what is different from my others services with 2 servers HTTP/ws, is kemal
HumanG33k has joined #crystal-lang
<FromGitter> <roduquen> I ll erase all kemal stuffs on the HTTP one, and try again and I will tell you when done, but I will eat fastly I'll ping you to know if the problem was here
<FromGitter> <roduquen> (I tried to use kemal just to not do the get/post etc by myself by the way ^^')
fifr` has joined #crystal-lang
fifr` has quit [Ping timeout: 260 seconds]
<FromGitter> <Luj8n> Hey! How can you get the instance of the struct/class inside that class? Idk how to ask, but in javascript there is `this` keyword
<FromGitter> <Blacksmoke16> `self`?
<FromGitter> <Luj8n> hmm
<FromGitter> <Luj8n> yeah
<FromGitter> <Luj8n> i thought that self.something was like a static method
<FromGitter> <Blacksmoke16> `def self.something` is a class method
<FromGitter> <Luj8n> yeah
<FromGitter> <Blacksmoke16> but `self` can either mean the instance, or the class depending on the context of where it's used
<FromGitter> <Luj8n> oh
<FromGitter> <Luj8n> thanks so much!
<FromGitter> <Blacksmoke16> e.g. if you use `self` within a class method its a reference to the class
<straight-shoota> in class context, class is the instance
<straight-shoota> (kindof)
<frojnd> I Would like to measure my operation of writing data into db. What functions, classess hould I use?
fifr` has joined #crystal-lang
_ht has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> prob fine?
<frojnd> Yeah.. just using .realtime
<frojnd> One would expect this would be 365, but no it gives false: `days = Time.leap_year? 2021 ? 366 : 365` I had to use parenthesis: `days = (Time.leap_year? 2021) ? 366 : 365`
<FromGitter> <jrei:matrix.org> prefer to use `Time.leap_year?(2021)`
<FromGitter> <Blacksmoke16> and?
<FromGitter> <Blacksmoke16> ^, yea this is kinda expected and is a case where you need the `()`
<frojnd> I see
<FromGitter> <jrei:matrix.org> will be still ambiguous even if it worked
<frojnd> I never kno when to use method arg vs method(arg) now I know :D
<FromGitter> <jrei:matrix.org> at times I'd like to have `expr if true else false`. `expr if true` already works
<frojnd> Am I reading this righ? "dbexec: 00:00:05.300371454" this is 5 seconds
<FromGitter> <Blacksmoke16> yes
<frojnd> And this is "dbquery: 00:00:00.001585947" well quick..
<FromGitter> <jrei:matrix.org> why?
<straight-shoota> 1.4 ms for sounds reasonable a simple query
fifr` has quit [Ping timeout: 276 seconds]
<FromGitter> <js:nil.im> How does one best handle avoiding to accidentally return something from a function?
<FromGitter> <watzon:matrix.org> Example?
<FromGitter> <js:nil.im> Say, my function calls another function which returns something
<FromGitter> <js:nil.im> but I don't want to return anything
<FromGitter> <watzon:matrix.org> Just do `function_call; nil`
<FromGitter> <watzon:matrix.org> I mean technically you're always returning something, but in this case you return `nil`
<FromGitter> <js:nil.im> is there a way to declare that as the type and get an error if I accidentally return someting?
<FromGitter> <js:nil.im> def foo : Nil?
<FromGitter> <watzon:matrix.org> Just `def foo : Nil` would do. The question mark is redundant.
<FromGitter> <js:nil.im> well, the question mark was not supposed to be part of it πŸ˜€
<FromGitter> <js:nil.im> it was because it was a question - I should have used ` around it
<FromGitter> <watzon:matrix.org> Lmao
<FromGitter> <watzon:matrix.org> Then yes
hendursa1 has quit [Quit: hendursa1]
hendursaga has joined #crystal-lang
<FromGitter> <Blacksmoke16> well to be clear if you do `def foo : Nil`, you wont get an error if it returns something other than `nil`, as the compiler makes it always return `nil`
<FromGitter> <watzon:matrix.org> Right. `def foo : Nil` would be for if you just want to make sure the function you're wrapping is returning `nil`.
<FromGitter> <Daniel-Worrall> Wouldn't it be a compiler error that the last line *could* return non-nil?
<FromGitter> <Blacksmoke16> no
<FromGitter> <Blacksmoke16> its special
<FromGitter> <Blacksmoke16> ```def foo : Nil ⏎ 1 ⏎ end ⏎ ⏎ foo # => nil``` [https://gitter.im/crystal-lang/crystal?at=60416dc1e8267a46f2f1a85d]
<FromGitter> <Daniel-Worrall> I literally typed that exact thing in my playground
<FromGitter> <Daniel-Worrall> *interesting*
<FromGitter> <watzon:matrix.org> Oh weird. I didn't know that actually.
<FromGitter> <js:nil.im> well, I don't care about the compiler warning or not - I just want to make sure I don't accidentally return something πŸ˜€
<FromGitter> <watzon:matrix.org> So just adding a `Nil` return type will make sure it always returns `nil`?
<FromGitter> <js:nil.im> so `: Nil` seems what I want
<FromGitter> <Blacksmoke16> @watzon:matrix.org yes
<FromGitter> <js:nil.im> but, I managed to make .dup break
<FromGitter> <js:nil.im> does it not work for classes that contain enums?
<FromGitter> <watzon:matrix.org> Very interesting
<FromGitter> <Blacksmoke16> and again to be clear this is *only* with explicit `Nil` return type
<FromGitter> <Blacksmoke16> `SomeObj?` is *not* the same thing
<FromGitter> <js:nil.im> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60416e60120cd84f78f4abdd]
<FromGitter> <js:nil.im> AsyncDNS::DNSClass is an enum
<FromGitter> <Blacksmoke16> `Enum` prob needs to redefine `dup`
<FromGitter> <watzon:matrix.org> Does seem like something that could count as a bug
<FromGitter> <js:nil.im> hitting compiler bugs is my speciality πŸ˜‰
<FromGitter> <Blacksmoke16> wait
<FromGitter> <js:nil.im> (as in, actual compiler bugs, not "must be a compiler bug")
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/ahvl
<FromGitter> <Blacksmoke16> i think something else is going on
<FromGitter> <watzon:matrix.org> Have some code to show?
<FromGitter> <watzon:matrix.org> js (https://matrix.to/#/@js:nil.im): ^
<FromGitter> <Blacksmoke16> its prob defines as a class
<FromGitter> <js:nil.im> can it be that I use the name "class"?
<FromGitter> <Blacksmoke16> as that implementation is only for reference types
<FromGitter> <Blacksmoke16> yes, thats not an emum :P
<FromGitter> <js:nil.im> I have `getter class : DNSClass`
<FromGitter> <Blacksmoke16> try doing `klass`
<FromGitter> <watzon:matrix.org> You should definitely avoid using the work clas
<FromGitter> <js:nil.im> yep, renaming to `klass` works
<FromGitter> <js:nil.im> so I'll just call it dns_class then
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <js:nil.im> that explains why it called self.class :D
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang/crystal/issues/7292 kinda related
<FromGitter> <Blacksmoke16> diff method, but same problem
<FromGitter> <js:nil.im> oh ffs, name is another propery name I use
<FromGitter> <Blacksmoke16> well that has been fixed i think, and was a class method
<FromGitter> <Blacksmoke16> so prob not a problem now
<FromGitter> <js:nil.im> *phew*
<FromGitter> <js:nil.im> is `type` another dangerous name?
<FromGitter> <Blacksmoke16> idt
<FromGitter> <watzon:matrix.org> `type` is fine from my experience
<FromGitter> <watzon:matrix.org> I use it all the time
<FromGitter> <watzon:matrix.org> The ones I'd stay away from are the legit keywords. class, struct, module, enum, def, abstract, private, and macro are the only ones I can think of off the top of my head.
<FromGitter> <js:nil.im> can I also set default values when I use the `record` macro?
<FromGitter> <watzon:matrix.org> Yep
<FromGitter> <watzon:matrix.org> `record Foo, bar : String = "baz"`
<FromGitter> <js:nil.im> perfect, thx! πŸ˜€
HumanG33k has quit [Remote host closed the connection]
<FromGitter> <js:nil.im> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=604172c8823b6654d283fcb5]
<FromGitter> <js:nil.im> Hmm, I suppose it does not work with unions?
<FromGitter> <js:nil.im> oh wait, no, that's the block
<FromGitter> <js:nil.im> is it that things without a default need to be last or something?
HumanG33k has joined #crystal-lang
<FromGitter> <js:nil.im> or is using a record discouraged anyway when it gets too complex?
<FromGitter> <watzon:matrix.org> Things with a default value have to be at the end
<FromGitter> <js:nil.im> I think I'll make it a class after all, it's getting messy
<FromGitter> <Blacksmoke16> depends on what the intention of the type is, you can still break things out using a normal `struct` versus `class`
HumanG33k has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> `record` and by extension `struct` should be used when the type is small and immutable
<FromGitter> <Blacksmoke16> as its passed by value and allocated on the stack
<FromGitter> <watzon:matrix.org> Yeah. My general rule of thumb is to use a struct any time I want a type to be immutable, and a class otherwise.
HumanG33k has joined #crystal-lang
<FromGitter> <watzon:matrix.org> Since there is some weird behavior if you try to modify values in structs after init
<FromGitter> <js:nil.im> isn't a struct also on the stack? so a big one that should be immutable would still not be a good fit for a struct?
<FromGitter> <Blacksmoke16> class in on the heap
<FromGitter> <Blacksmoke16> struct on the stack
<FromGitter> <watzon:matrix.org> Yeah. Structs are passed by value, so that's another consideration to take.
<FromGitter> <watzon:matrix.org> Big structs could impact performance