ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Fund Crystal's development: | GH: | Docs: | Gitter:
<FromGitter> <> js ( you dont need to search, just read it all pls.
<FromGitter> <> I usually look up the stuff that I need as I go πŸ™‚
hendursa1 has quit [Quit: hendursa1]
hendursaga has joined #crystal-lang
<FromGitter> <> is missing the most important detail: Whether this is a cryptographic random number generator
<FromGitter> <Blacksmoke16> old docs btw
<FromGitter> <> oh, interesting
<FromGitter> <> first google result is old
<FromGitter> <> the newer one has something
<FromGitter> <> 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> <> it recommends, but it doesn't really say what that is?
<FromGitter> <Blacksmoke16> you prob want `Random::Secure`
<FromGitter> <> ah, thx. Never heard of that one before
<FromGitter> <> > 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> <> 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> <> 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> <> so without the :, ok :)
<FromGitter> <Blacksmoke16> and with the type
<FromGitter> <> well optionally
<FromGitter> <> 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> <> I see
<FromGitter> <> thx
<FromGitter> <> I might be missing something obvious, but does not mention how I can access an ivar that is not on self
<FromGitter> <Blacksmoke16> `property` defines a getter
<FromGitter> <> e.g. if I have `def dup`, how can I access @foo on the copy? `copy.@foo = 1234` doesn't work
<FromGitter> <> so I have to have a getter, no way to directly access the ivar?
<FromGitter> <> 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> <> ```code paste, see link``` []
<FromGitter> <> the last_reload is not something that should have a setter
<FromGitter> <Blacksmoke16> why not just `, ...)`?
<FromGitter> <> but if you dup, it should make it to the copy
<FromGitter> <> oh, you mean have a new, private initializer?
<FromGitter> <Blacksmoke16> sure
<FromGitter> <> 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> <> system config
<FromGitter> <> and yes, I need the dup - I need to keep the config as of the moment I sent the query
<FromGitter> <> if the config changes in between, it still needs to be performed with the old settings
<FromGitter> <Blacksmoke16> i mean this, `dup` is already defined. Just returns the same obj but with a diff obj id
<FromGitter> <> if I don't define it I get an error :/
<FromGitter> <> maybe I should figure out why that is instead
<FromGitter> <> oh, it was a missing type πŸ˜€
<FromGitter> <> I had @settings = settings.dup
<FromGitter> <> and it could not infer the type from that
<FromGitter> <> if I added @settings : Settings, it works
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <Blacksmoke16> its better to be explicit imo
<FromGitter> <> 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> <> Basically, the block would be `Response | Error`
<FromGitter> <> on error, I could yield early
<FromGitter> <> (for some, that is)
<FromGitter> <> but for others, I'd need to capture it and call it later
<FromGitter> <> yes that's what I read exactly
<FromGitter> <> 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> <> how can you use exceptions in async code?
<FromGitter> <> wouldn't that unwind to the wrong place?
<FromGitter> <> ```code paste, see link``` []
<FromGitter> <> is what I currently have
<FromGitter> <Blacksmoke16> `loop do` πŸ˜‰
<FromGitter> <Blacksmoke16> but hmm
<FromGitter> <> that I had at first, but then it complained about id being read before being set
<FromGitter> <> 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``` []
<FromGitter> <Blacksmoke16> :S
<FromGitter> <Blacksmoke16> prob something to do with blocks or something
<FromGitter> <> that was my guess, too
<FromGitter> <> that the compiler cannot prove the block gets called
<FromGitter> <> anyway, the error in this case an also come from the nameserver
<FromGitter> <> 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> <> I suppose there will be fibers as soon as I use sockets
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <> otherwise the non-blocking DNS resolver will, well, not be non-blocking πŸ˜‰
<FromGitter> <> ok, pushed my current state
<FromGitter> <> in case someone feels like early reviewing
<FromGitter> <> 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>,*properties)-macro might be helpful to you
<FromGitter> <Blacksmoke16> this would help with your other issue, i.e. `` 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> <> @alexherbo2: what's the difference with
richbridger has quit [Remote host closed the connection]
<FromGitter> <> @Blacksmoke16: ah, thx πŸ™‚ will change those
<FromGitter> <> but the symbols should be lowercase, not uppsercase?
<FromGitter> <Blacksmoke16> doesnt actually matter
<FromGitter> <> 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> <> 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> <> 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> <> I mean, having to add more types is a downside ;)
<FromGitter> <Blacksmoke16> if you say so
<FromGitter> <> 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> <> e.g. ⏎ ⏎ ```property foo : String ⏎ ⏎ def initialize(@foo) ⏎ end``` ⏎ ⏎ ? []
<FromGitter> <Blacksmoke16> but losing better docs, error messages, etc
<FromGitter> <Blacksmoke16> i usually do both
<FromGitter> <Blacksmoke16> the former
<FromGitter> <> ok
<FromGitter> <> so basically never use type inference?
<FromGitter> <> 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> <> @Blacksmoke16: Like this?
<FromGitter> <Blacksmoke16> thats my preferred style yea, but im sure others have their own opinions on it
skrzyp has joined #crystal-lang
<FromGitter> <> type inference is still done. type restrictions only *restrict* the allowed outcomes.
<FromGitter> <> im nitpicking here though
<FromGitter> <> > 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> <> 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? from_json
<FromGitter> <> verses is an array, `verses[0].date` works
<FromGitter> <> but you function foo return nothing
<frojnd> No I missed array, thank you
<FromGitter> <> oh no it returns something, why?
<FromGitter> <> ok that's why:**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> <> 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 ="ws://localhost:5060/");``` ⏎ ⏎ I got : Firefox can’t establish a connection to the server at ws://localhost:5060/ ... []
<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 `""`
<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> <> for me localhost bind do ::1, not
<FromGitter> <> ```$ ping localhost ⏎ PING localhost(localhost (::1)) 56 data bytes``` []
<FromGitter> <> 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> <> I recommend you to do like this: ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <> 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> <> great :)
<FromGitter> <> 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> <> Multi process would be better
<FromGitter> <> Multi thread don't scale linearily
<FromGitter> <> 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> <> I just read about SO_REUSEPORT and what it does.
<FromGitter> <> Sound better to let HAProxy do the dispatch instead of the machine's OS
<FromGitter> <> The main thing I've in mind is healthcheck
<FromGitter> <roduquen> Thanks, I got this when I do the puts on logs 'Board WebSocket Server Listening on', 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://"
<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> <> You're on docjer?
<hightower2> roduquen localhost on ipv6
<FromGitter> <roduquen> Locally not but on AWS yep
<FromGitter> <> Try the basic example from the API docs
fifr` has quit [Ping timeout: 260 seconds]
<FromGitter> <> Or a similar basic one. Of it works, you can start from there
<FromGitter> <roduquen> ```"", 5060)``` []
<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, with the address and can't connect, when with the websocket client from crystal I can
<FromGitter> <> 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> <> 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> <> (I recommend to put this in STDERR)
<FromGitter> <roduquen> Oh well
<FromGitter> <roduquen> :facepalm:
<FromGitter> <> 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 []
<FromGitter> <> and with a simple HTTP server?
<FromGitter> <roduquen> Works fine
<FromGitter> <> 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> <> you can have the ws and HTTP on the same port
<FromGitter> <> websocket is http, at least at the beginning
<FromGitter> <roduquen> Oh ok I didn't know I separated everything on terraform
<FromGitter> <> 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 '': Address already in use (Socket::BindError) ⏎ from /usr/share/crystal/src/socket/ in 'initialize:reuse_port' ⏎ from /usr/share/crystal/src/socket/ in 'new:reuse_port' ⏎ from /usr/share/crystal/src/http/
<FromGitter> ... in 'bind_tcp' ⏎ from lib/kemal/src/ in 'run' ... []
<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> <> 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> <> 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> <> 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> <> why?
<straight-shoota> 1.4 ms for sounds reasonable a simple query
fifr` has quit [Ping timeout: 276 seconds]
<FromGitter> <> How does one best handle avoiding to accidentally return something from a function?
<FromGitter> <> Example?
<FromGitter> <> Say, my function calls another function which returns something
<FromGitter> <> but I don't want to return anything
<FromGitter> <> Just do `function_call; nil`
<FromGitter> <> I mean technically you're always returning something, but in this case you return `nil`
<FromGitter> <> is there a way to declare that as the type and get an error if I accidentally return someting?
<FromGitter> <> def foo : Nil?
<FromGitter> <> Just `def foo : Nil` would do. The question mark is redundant.
<FromGitter> <> well, the question mark was not supposed to be part of it πŸ˜€
<FromGitter> <> it was because it was a question - I should have used ` around it
<FromGitter> <> Lmao
<FromGitter> <> 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> <> 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``` []
<FromGitter> <Daniel-Worrall> I literally typed that exact thing in my playground
<FromGitter> <Daniel-Worrall> *interesting*
<FromGitter> <> Oh weird. I didn't know that actually.
<FromGitter> <> well, I don't care about the compiler warning or not - I just want to make sure I don't accidentally return something πŸ˜€
<FromGitter> <> So just adding a `Nil` return type will make sure it always returns `nil`?
<FromGitter> <> so `: Nil` seems what I want
<FromGitter> <Blacksmoke16> yes
<FromGitter> <> but, I managed to make .dup break
<FromGitter> <> does it not work for classes that contain enums?
<FromGitter> <> 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> <> ```code paste, see link``` []
<FromGitter> <> AsyncDNS::DNSClass is an enum
<FromGitter> <Blacksmoke16> `Enum` prob needs to redefine `dup`
<FromGitter> <> Does seem like something that could count as a bug
<FromGitter> <> hitting compiler bugs is my speciality πŸ˜‰
<FromGitter> <Blacksmoke16> wait
<FromGitter> <> (as in, actual compiler bugs, not "must be a compiler bug")
<FromGitter> <Blacksmoke16>
<FromGitter> <Blacksmoke16> i think something else is going on
<FromGitter> <> Have some code to show?
<FromGitter> <> js ( ^
<FromGitter> <Blacksmoke16> its prob defines as a class
<FromGitter> <> 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> <> I have `getter class : DNSClass`
<FromGitter> <Blacksmoke16> try doing `klass`
<FromGitter> <> You should definitely avoid using the work clas
<FromGitter> <> yep, renaming to `klass` works
<FromGitter> <> so I'll just call it dns_class then
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <> that explains why it called self.class :D
<FromGitter> <Blacksmoke16> kinda related
<FromGitter> <Blacksmoke16> diff method, but same problem
<FromGitter> <> 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> <> *phew*
<FromGitter> <> is `type` another dangerous name?
<FromGitter> <Blacksmoke16> idt
<FromGitter> <> `type` is fine from my experience
<FromGitter> <> I use it all the time
<FromGitter> <> 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> <> can I also set default values when I use the `record` macro?
<FromGitter> <> Yep
<FromGitter> <> `record Foo, bar : String = "baz"`
<FromGitter> <> perfect, thx! πŸ˜€
HumanG33k has quit [Remote host closed the connection]
<FromGitter> <> ```code paste, see link``` []
<FromGitter> <> Hmm, I suppose it does not work with unions?
<FromGitter> <> oh wait, no, that's the block
<FromGitter> <> is it that things without a default need to be last or something?
HumanG33k has joined #crystal-lang
<FromGitter> <> or is using a record discouraged anyway when it gets too complex?
<FromGitter> <> Things with a default value have to be at the end
<FromGitter> <> 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> <> 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> <> Since there is some weird behavior if you try to modify values in structs after init
<FromGitter> <> 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> <> Yeah. Structs are passed by value, so that's another consideration to take.
<FromGitter> <> Big structs could impact performance