ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Fund Crystal's development: | GH: | Docs: | Gitter:
<FromGitter> <> is there a better way to handle the following pattern? ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <> it's … kinda annoying to have it complain it could be nil when you *just* assigned it
<FromGitter> <> `@ivar = ivar =`
<FromGitter> <> another idea I had was @foo = foo =
<FromGitter> <> oh, ok, so that actually is the way to go πŸ˜€
<FromGitter> <> The compiler's issue is that `@ivar` could be reassigned at any time, so it can't guarantee that it's non nil
<FromGitter> <> Even if you just assigned it, it could be reassigned in another thread/fiber
<FromGitter> <Blacksmoke16> ```@ivar.try |iv| ⏎ iv.some_method ⏎ end``` []
<FromGitter> <Blacksmoke16> `try do`*
<FromGitter> <> That could work as well
<FromGitter> <> `.try` is great
<FromGitter> <> Though I do have to say, the `try` and `not_nil!` methods make me wish `!` and `?` weren't valid ident pieces. It would be nice to be able to use a `!` postfix for `not_nil!` and a `?` postfix as an implicit `try`.
sagax has quit [Ping timeout: 245 seconds]
<FromGitter> <> btw, if I create a Slice(UInt8).new(2), but access slice[3] = 1 - will that increase the size of the slice or raise?
<FromGitter> <Blacksmoke16> idk, try it and find out? My vote is on raise
<FromGitter> <> well, trying out is one way to figure out the state *now*, but not the API contract πŸ˜›
<FromGitter> <> Pretty sure it's either a raise or undefined behavior
<FromGitter> <> Since a slice is a wrapper around a pointer
<FromGitter> <> Yep, it raises
<FromGitter> <> Also, `Bytes` is an alias for `Slice(UInt8)`
<FromGitter> <> ah, thx πŸ™‚
<FromGitter> <> Bytes sounds much nicer πŸ˜‰
<FromGitter> <> ```code paste, see link``` ⏎ ⏎ The compiler thinks `sock` is `UDPSocket | Nil` here. Any way around that? []
<FromGitter> <> oh, ignore
<FromGitter> <> Also, if you do need something resizable you can always use `IO::Memory`. Slices aren't resizable afaik.
<FromGitter> <> ```code paste, see link``` ⏎ ⏎ The compiler complains here that `sock` is `UDPSocket | Nil`. I suppose that is because I declare the variable without assigning it and it therefore implicitly adds a `?`? []
<FromGitter> <> ah nvm
<FromGitter> <> what is the preferred way to copy from a `String` into `Bytes`?
<FromGitter> <> Copy or convert?
<FromGitter> <> copy in as ASCII
<FromGitter> <> should throw if there's any non-ASCII chars
<FromGitter> <> or copy them verbatim, I don't care πŸ˜€
<FromGitter> <> (then the NS will just reject it)
<FromGitter> <> Because `String#to_unsafe` will grab the underlying utf8 encoded bytes.
<FromGitter> <> So `String#to_unsafe.clone` should copy the slice
<FromGitter> <> also, is there any better way to do this? ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <Blacksmoke16> Pretty sure that returns a pointer
<FromGitter> <Blacksmoke16> There's also to_slice
<FromGitter> <> Sorry, `String#to_slice`
<FromGitter> <> Not to_unsafe
<FromGitter> <> and to_slices is bytes? Not slice of UInt32 with Unicode code points or other shenanigans?
<FromGitter> <> Yeah
<FromGitter> <> There's a way to get a utf16 slice too, but `to_slice` returns bytes
<FromGitter> <> js ( u can do `ii = (0..).each`
<FromGitter> <> ok, great πŸ™‚
<FromGitter> <> `@raw_data[] = 1`
<FromGitter> <> oh, that's nice
<FromGitter> <> can I also skip several, e.g. skip 6?
<FromGitter> <> or is that then 6.times { }?
<FromGitter> <> iunoo
<FromGitter> <> ah, there's `.skip(6)`
<FromGitter> <> js ( im afraid it will not work
<FromGitter> <> may have to do `ii = ii.skip(6)`
<FromGitter> <> each of which is a heap allocation
<FromGitter> <> The other option is an old fashioned while loop
<FromGitter> <> Actually nvm
<FromGitter> <> won't work here
<FromGitter> <> oprypin ( oh right, returns a new iterator πŸ˜•
<FromGitter> <> crap
<FromGitter> <> so I guess counting manually is the way to go
<FromGitter> <> Yeah, or your `6.times { }`. That would work fine.
<FromGitter> <> It's not pretty, but it would work
<FromGitter> <> it will get slow when I copy in entire strings and have to do `component.bytesize.times { }`
<FromGitter> <> not an option, yea
<FromGitter> <> which brings me back to the problem of copying from one Slice into another πŸ˜€
<FromGitter> <> aka how to do `memcpy` in Crystal
<FromGitter> <> `Slice#copy_to`
<FromGitter> <> and `Slice#copy_from`
<FromGitter> <> I found those, but none takes an offset
<FromGitter> <> because I want to copy to slice_a + i
<FromGitter> <> You can use a slice of a slice. It points to the same memory.
<FromGitter> <> `slice_a.copy_to(slice_b[4...])
<FromGitter> <> ah
<FromGitter> <> that's a good idea
<FromGitter> <> You can also use pointers, but this way is cleaner
<FromGitter> <> so, ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ then, or is that evil for whatever reason? πŸ™‚ []
<FromGitter> <> (component is String)
<FromGitter> <> and I suppose this does length checks and won't just overflow, correct?
<FromGitter> <> Hard to tell without seeing the surrounding code if this is the best way to do things. If your writing a bunch of bytes it might make more sense to use an IO.
<FromGitter> <> I need to construct one UDP packet with a max size of 512 bytes
<FromGitter> <> for a protocol?
<FromGitter> <> yes, DNS
<FromGitter> <> You could always do ⏎ ⏎ ```io = ⏎ # ... ⏎ io.write(component.to_slice)``` []
<FromGitter> <> you can use IO::Memory, which will keep track of the index
<FromGitter> <> also, I just noticed - is there no sendto on IPSocket?
<FromGitter> <> and internally it is a slice
<FromGitter> <> interesting, I'll refactor to IO then once this works πŸ™‚
<FromGitter> <> (I'm basically only missing `sendto()` at this point
<FromGitter> <> `IPSocket` has a `send` method
<FromGitter> <> oh, 2nd parameter
<FromGitter> <> It exists on `Socket`
<FromGitter> <>,toaddr:Address):Int32-instance-method
<FromGitter> <> did not expect that since they're separate methods in BSD socket,s but it makes sense πŸ˜€
<FromGitter> <> ok, just commited it: http://localhost:8080/file?name=src/
<FromGitter> <> is there a convenient way to write a UInt16 in big endian to an IO?
<FromGitter> <> or is the current shifting and masking that I do the best way?
<FromGitter> <> `io.write_bytes(int.to_u16, IO::ByteFormat::BigEndian)`
<FromGitter> <> I've been doing this so much lately I know it by heart lol
<FromGitter> <> `io.write_bytes(int.to_u16, :BigEndian)` i think that works too?
<FromGitter> <> I don't believe so. `BigEndian` isn't an enum.
<FromGitter> <> oof sorry
<FromGitter> <> I wish though haha
<FromGitter> <> it's so interesting
<FromGitter> <> people might after a while decide to transparently convert from an enum to a self-extend module
<FromGitter> <> in their API
<FromGitter> <> *except* for the part where the shorthand would break
<FromGitter> <> `6.times { @io.write_byte(0) }` ← is there a better way to do this?
<FromGitter> <> `io.write( { 0_u8})`
<FromGitter> <> will that not allocate?
<FromGitter> <> Yeah I suppose it will
<FromGitter> <> I guess best to write uint32 and uint16?
<FromGitter> <> I don't really think there's a better way than what you're doing
<FromGitter> <> You could do that
<FromGitter> <> Though if you're worried about performance I'm sure just writing 6 times won't be any less performant
<FromGitter> <> 1) times { io.write(0_u16) } would actually be best - that woudl match the field sizes πŸ˜‰
<FromGitter> <> Be sure to `write_bytes` though. I don't think `io.write` will work here.
<FromGitter> <> `write` expects a slice
<FromGitter> <> ah, yeah :) sorry,meant that
<FromGitter> <> can I just `io << str` to write a string to it?
<FromGitter> <> Yep, that would work
<FromGitter> <> I believe
sagax has joined #crystal-lang
<FromGitter> <> This is much better indeed, thanks!
<FromGitter> <> once this is done, would this be something that could be considered for inclusion in stdlib? I think it would be useful to basically move everything that uses DNS to async πŸ™‚
<FromGitter> <> I'm sure it's something that would be considered
<FromGitter> <> what would be the requirements for that? I mean, there'll obviously be plenty of feedback and I'll address that. But other than that? I suppose Apache license?
<FromGitter> <> MIT I believe. Once you have a working library I'd ask in the forum and get some feedback from the maintainers, then open a PR.
<FromGitter> <> Forum?
<FromGitter> <>
<FromGitter> <> happy to put this under any license. The original (from ObjFW) is GPLv2/3/QPL, but I'm happy to relicense, obviously
<FromGitter> <> The licence that's generally created with `crystal init` is MIT, so that's what most people tend to go with
<FromGitter> <> And I believe that's what Crystal itself is licensed under
<FromGitter> <> I'm looking at the Socket documentation, but cannot find anyhting about async receives?
<FromGitter> <> Idk much about that myself
<FromGitter> <> Usually when I find the crystal docs lacking I go one of two places. If it's an implementation detail I'll usually check the Ruby docs/questions since Crystal and Ruby are still similar enough. If I can't find a good answer there I do the same with Go. Surprisingly enough Go and Crystal share a lot in common.
<FromGitter> <> Especially where concurrency is concerned.
<FromGitter> <> I … suppose the correct way is to use a fiber and blocking I/O?
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
<FromGitter> <> ok, so, if I have a fiber that is in receive, but I call close from another fiber, I get IO::Error on the fiber that is in the receive. Which is fine. If only there would be a way to tell this IO::Error apart from another. Anything I can do?
bazaar has quit [Ping timeout: 245 seconds]
<FromGitter> <> You could have a receive channel, a send channel, and a close channel
<FromGitter> <> Crystal also has `select` blocks, but they're some undocumented voodoo
<FromGitter> <>
bazaar has joined #crystal-lang
_whitelogger 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
HumanG33k has quit [Max SendQ exceeded]
HumanG33k 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]
_ht has joined #crystal-lang
fifr` has joined #crystal-lang
<FromGitter> <bararchy> I think i'm hitting this one as well
<FromGitter> <bararchy> and not sure if anyone had a chance to work around it
hendursa1 has joined #crystal-lang
hendursaga has quit [Ping timeout: 268 seconds]
<FromGitter> <naqvis> @bararchy that's happening because of tight loop invocation, thus giving GC no chance to breathe. Adding a small sleep after some invocations, will make it pass the test
<FromGitter> <naqvis> i've tested the same code on linux vm running from my mac, as was able to get through that 100K limit without OOM
<frojnd> So I have a module named: `Foo` file I have a bunch of functions inside that module. Now in another file named and I would like to call functions from that file. I tried like this: include Foo; pp function_name but I got: Error: undefined constant Foo for include Foo
<FromGitter> <naqvis> `Module` are Class in disguise. so you can invoke methods which are static or defined as class methods with `self`
<FromGitter> <naqvis> ```code paste, see link``` []
<FromGitter> <naqvis> either go with `extend self` or if you want only few methods to be marked as static then append `self` like in Bar example
hightower2 has quit [Ping timeout: 256 seconds]
<frojnd> Hm I still get Error: undefined constant Foo
<frojnd> Do I have to have naming of the file in order with module names too?
<frojnd> I mean your code works if it's in one file.. but if separated
<FromGitter> <asterite> frojnd: maybe provide some code?
<FromGitter> <asterite> you can add `{% puts "hello" %}` inside `` to know if it's being required or not
<frojnd> Ouch didn't require "./"
<frojnd> One question regarding naming conventions... file name is `` inside would be better to have `module FooBar` or `module Foo::Bar` or would later be better for `` file?
<straight-shoota> I'd place Foo::Bar in foo/
hendursa1 has quit [Remote host closed the connection]
hendursa1 has joined #crystal-lang
hightower3 has joined #crystal-lang
_ht has quit [Read error: Connection reset by peer]
_ht has joined #crystal-lang
<FromGitter> <roduquen> @j8r Hey, I got the issue, not about code, about port... 5060 not allowed on browser, so I wasn't able to connect to the websocket server just because of the 5060..
<FromGitter> <> 5060 is Session Initiation Protocol (SIP)
sz0 has quit [Quit: Connection closed for inactivity]
<FromGitter> <> by the way, better to choose classic "free" ports like 808x or 3000
<FromGitter> <> this case was strange though
hendursaga has joined #crystal-lang
hendursa1 has quit [Ping timeout: 268 seconds]
duane has joined #crystal-lang
duane has quit [Ping timeout: 264 seconds]
ua_ has quit [Ping timeout: 256 seconds]
ua_ has joined #crystal-lang
_ht has quit [Remote host closed the connection]
<Stephie> so, how stable is preview_mt these days?
<straight-shoota> Hey, nice to see you around =)
<straight-shoota> don't think there has been much work on it in the last year...
<straight-shoota> but people seem to be using it and looks like it can't be too bad
<hightower3> @watzon were you the one who at one point pasted a short program showing which chars (mostly from utf-8 set) are accepted in method names?
<FromGitter> <> It’s possible, but if so I don’t remember it
<hightower3> ok nm, found a way to document what I needed
<hightower3> tx
<FromGitter> <alexherbo2> can the json parser parse chunks in an array?, similarly to jq with the `--slurp` option?
<FromGitter> <alexherbo2> I want ⏎ ⏎ ```["a", "b"] ⏎ ["c","d"]``` ⏎ ⏎ to be parsed as `Array(Array(String))` []
<FromGitter> <Blacksmoke16> no
<FromGitter> <Blacksmoke16> thats not valid json
<FromGitter> <> split the string yourself, then use `Array.from_json`
<FromGitter> <alexherbo2> how?
<FromGitter> <alexherbo2> the chunk can span multiple liens
<FromGitter> <alexherbo2> lines*
<FromGitter> <> `string.each_line { |line| Array(String).from_json line }`
<FromGitter> <Blacksmoke16> could you do like ``?
<FromGitter> <alexherbo2> it only works if it's a one liner, I would like to abstract to parses the chunk in an array or have the chunks already in an array
<FromGitter> <Blacksmoke16> could install `oq` as a lib and use that πŸ˜†
<FromGitter> <alexherbo2> no I cannot ensure it will be a single line
<FromGitter> <> why do you want to do this way?
<FromGitter> <> I don't understand what's your requirement
<FromGitter> <alexherbo2> to send commands to kakoune as chunk or a big array
<FromGitter> <> I mean, why my proposal don't work?
<FromGitter> <alexherbo2> ```code paste, see link``` []
<FromGitter> <alexherbo2> here I have `Array(Array(String))` as input for `kcr send`
<FromGitter> <alexherbo2> ```kcr echo -- echo kanto | ⏎ kcr echo -- echo johto | ⏎ kcr send``` []
<FromGitter> <> Hum, ok
<FromGitter> <alexherbo2> here I have 2 chunks of `Array(String)`
<FromGitter> <> could you send the raw input you want to transform to with
<FromGitter> <> like, `"[0]"` => `Array(Int32)`
<FromGitter> <alexherbo2> I would like to have Crystal parses the chunks in a big array
<FromGitter> <> (or here)
<FromGitter> <> nvm you already sent the example sorry
postmodern has joined #crystal-lang
<FromGitter> <> so, if I understood correctly, `"["a", "b"]\n["c","d"]"` => `Array(Array(String))`
<FromGitter> <alexherbo2> yep
<FromGitter> <alexherbo2> and `[["a","b"],{"c","d"]]`
<FromGitter> <alexherbo2> to have a single interface to answer use cases above