RX14 changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.26.1 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
greengriminal has quit [Quit: This computer has gone to sleep]
non-aristotelian has quit [Quit: non-aristotelian]
non-aristotelian has joined #crystal-lang
non-aristotelian has quit [Ping timeout: 244 seconds]
akaiiro has quit [Ping timeout: 272 seconds]
non-aristotelian has joined #crystal-lang
non-aristotelian has quit [Ping timeout: 240 seconds]
akaiiro has joined #crystal-lang
akaiiro has quit [Ping timeout: 272 seconds]
akaiiro has joined #crystal-lang
return0e_ has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
rohitpaulk has joined #crystal-lang
akaiiro has quit [Ping timeout: 252 seconds]
akaiiro has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 245 seconds]
rohitpaulk has joined #crystal-lang
_whitelogger has joined #crystal-lang
akaiiro has quit [Remote host closed the connection]
t0nyandre has joined #crystal-lang
t0nyandre has quit [Quit: WeeChat 2.3]
Raimondii has joined #crystal-lang
ashirase has quit [Ping timeout: 244 seconds]
Raimondi has quit [Ping timeout: 246 seconds]
Raimondii is now known as Raimondi
ashirase has joined #crystal-lang
druonysus has quit [Read error: Connection reset by peer]
ua_ has quit [Ping timeout: 252 seconds]
rohitpaulk has quit [Ping timeout: 240 seconds]
non-aristotelian has joined #crystal-lang
non-aristotelian has quit [Ping timeout: 252 seconds]
ua has joined #crystal-lang
rohitpaulk has joined #crystal-lang
t0nyandre has joined #crystal-lang
ua has quit [Ping timeout: 252 seconds]
ua has joined #crystal-lang
BigForceGun has joined #crystal-lang
BigForceGun has quit [Ping timeout: 240 seconds]
tankf33der has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 246 seconds]
rohitpaulk has joined #crystal-lang
teardown has joined #crystal-lang
tilpner has quit [Remote host closed the connection]
rohitpaulk has quit [Ping timeout: 272 seconds]
tilpner has joined #crystal-lang
rohitpaulk has joined #crystal-lang
moei has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 244 seconds]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 268 seconds]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 252 seconds]
akaiiro has joined #crystal-lang
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 268 seconds]
ashirase has quit [Ping timeout: 252 seconds]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 246 seconds]
non-aristotelian has joined #crystal-lang
rohitpaulk has joined #crystal-lang
t0nyandre has quit [Ping timeout: 272 seconds]
greengriminal has joined #crystal-lang
akaiiro has quit [Ping timeout: 268 seconds]
FromGitter has joined #crystal-lang
<FromGitter> <fridgerator> I just noticed the release
<FromGitter> <fridgerator> 🎉
<FromGitter> <fusillicode_twitter> Damn I'm battling with nested transactions...
<FromGitter> <fusillicode_twitter> ...again...
<FromGitter> <fusillicode_twitter> :(
<FromGitter> <fusillicode_twitter> I just want to perform multiple transactional insert and ignore unique constraints :'(
<FromGitter> <fusillicode_twitter> All this inside another transaction
<FromGitter> <bew> @vladfaust using `read_file` for this wouldn't work, because the file path won't pass through require's file resolution system
rohitpaulk has quit [Ping timeout: 252 seconds]
<FromGitter> <jemc> I'm new to Crystal, and a little confused by IO at the moment - how do I do a blocking `gets` from `STDIN` (or, if I can't do a blocking `gets`, I'd settle for any other blocking read operation)? I have a program where I `spawn` a fiber to read in a loop and send deserialized stuff out through a `Channel`, and I thought I was doing a blocking read in my loop, but it turns out I'm just busywaiting...
<FromGitter> <jemc> I've tried calling `IO::FileDescriptor#blocking=` with `true`, but it doesn't seem to have any effect? (also, I'd strongly prefer to just call a "blocking read" method rather than setting state on the file descriptor if possible...
<FromGitter> <jemc> If I can't do a blocking read, `IO.select` would be cool, but it seems like that's been removed? (https://github.com/crystal-lang/crystal/issues/3169) ⏎ ⏎ I know that the literal syscall `select` isn't appropriate in a libuv-evented context, but it would still be possible to implement `IO.select` with libuv (I once did this for Ruby, actually: https://github.com/jemc/rub
<FromGitter> ... y-bran/blob/2099526e796128936072302e0d6ef63f0e9a975f/lib/bran/ext/io.rb#L70-L106)
<FromGitter> <asterite> @kinxer exactly, nothing is really private
<FromGitter> <asterite> @jemc Hi! :-) . Why do you need a blocking read?
<FromGitter> <jemc> I wouldn't say I definitely need a blocking read if there's a more idiomatic way to do what I want to do
akaiiro has joined #crystal-lang
<FromGitter> <jemc> so I'm trying to create an abstraction that acts like `Channel#receive` does (blocking the current fiber until the next object is available) - internally it reads from an `IO` in a loop (usually `STDIN`, but sometimes other `IO` kinds for testing), deserializes some messages from it, and pushes those out for the `receive`-like method
<FromGitter> <jemc> as I mentioned above, I did this with a `spawn` that does `IO#gets` in a loop and parses the results
<oprypin> jemc, the main problem may be that its not a good idea to do input in non-main fiber
<FromGitter> <jemc> but without blocking reads, this just is a busywait that overuses the CPU when there is no data available
<FromGitter> <asterite> but if there's no data the CPU does nothing, right?
<FromGitter> <asterite> also, I just tried `STDIN.blocking = true` and it seems to work (but I wouldn't recommend it because standard file descriptors in the console are kind of shared and it's a mess)
<FromGitter> <asterite> I tried it with this: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5bdcb4cb5760a73eb42bd678]
<FromGitter> <asterite> so with `blocking = true` you don't get to see those `puts 1`, but with `blocking = false` you do
<FromGitter> <jemc> so I may be miscommunicating here - just to clarify, when I say "blocking", I mean "yield the current fiber until input is ready to read"
<FromGitter> <asterite> oh, in my mind that's non-blocking
<FromGitter> <jemc> > but I wouldn't recommend it because standard file descriptors in the console are kind of shared and it's a mess ⏎ ⏎ Yeah, as I mentioned above, I'd love to avoid mutating state on the file descriptor
<FromGitter> <jemc> so when I say "non-blocking" behaviour I mean "returns `nil` immediately when there is no data, without blocking the fiber"
<FromGitter> <jemc> but I can use whatever terms make the most sense here
<FromGitter> <asterite> Oooooh... I see
<FromGitter> <jemc> yeah, so my desired behaviour is to read from STDIN like it was a `Channel.receive`, yielding the fiber until data is available to read
<oprypin> but that's what happens by default
<FromGitter> <asterite> well, by default you go to another fiber. He wants to stay in the fiber and know that there's nothing immediately available
<FromGitter> <jemc> @asterite - no, that's not what I want, sorry
<FromGitter> <jemc> I'm still not being clear I guess
<FromGitter> <jemc> oprypin: for what method? `IO#gets` or something else?
<oprypin> gets
<FromGitter> <asterite> there's nothing like that but it shouldn't be hard to implement
<FromGitter> <jemc> let me try to come up with a minimal example and see how it compares to the behaviour I see in my actual code
<oprypin> yes
<FromGitter> <jemc> maybe something else strange is going on to make me busywait
<oprypin> it seems to me that something is wrong with socket flush_on_newline again
<oprypin> when someone writes a message on gitter, my application receives it immediately and writes to irc socket
<oprypin> but the message appears on irc only when ... uhh.. something else happens on irc
<oprypin> this is disturbing
<FromGitter> <jemc> okay, so working from a minimal example, forgetting about `spawn`ed fibers or anything outside the main fiber: ⏎ ⏎ ```loop do ⏎ p STDIN.gets ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5bdcb8405905a919554498b4]
<FromGitter> <jemc> what I get from that program is that it prints whatever it got in `STDIN`, then it prints `nil` forever in a busywait loop
<oprypin> oh? that's not what i get
<FromGitter> <jemc> what I want is a for that program to print data when it becomes available, but otherwise just wait for the next data to come in
<oprypin> and that's what your program does for me
<FromGitter> <jemc> oprpyin: interesting...
<FromGitter> <jemc> are you feeding it anything into `STDIN` when you run it? I am in my test
<oprypin> jemc, i just run the program
<FromGitter> <jemc> I'll try feeding it nothing...
<oprypin> jemc, so you mean you pipe something into it?
<oprypin> shouldve started with that
<FromGitter> <jemc> yeah, I was piping a JSONRPC message into it in my test
<FromGitter> <asterite> how do you do that in, say, Ruby?
<oprypin> echo a | crystal test.cr
<FromGitter> <jemc> when I pipe nothing into it, it waits patiently as desired
<oprypin> i see - you get nil forever here
<oprypin> but it just means that the file descriptor is closed, and it's expected behavior
<FromGitter> <asterite> I ask because Ruby behaves in the same way :-)
<FromGitter> <ukd1> I might be being dumb, but I can't figure out how to use JSON mapping with variable key names? i.e. {unknown_1: {...}, unknown_2: {...}}
<FromGitter> <ukd1> if anyone has an idea / sample <3
<oprypin> ok this may not be entirely true
<FromGitter> <jemc> @asterite - In Ruby, my go-to is `IO#readpartial`
<FromGitter> <jemc> (I use `IO#readpartial` or `IO.select` when I want blocking I/O in Ruby, but neither is present in Crystal)
<FromGitter> <jemc> (so I'm just trying to get something similar, even if it's not the methods I'm used to)
<oprypin> people, i am seriously disturbed by sockets flushing in crystal 0.26.1
<FromGitter> <asterite> I think you'll have to structure the program in a different way. There's no such thing in Go (neither readpartial nor select) and Crystal basically follows the Go model for IO
<oprypin> the socket flushes only when anything else happens in the application
<FromGitter> <jemc> @asterite - that's super weird to me that neither Go nor Crystal has a way to make I/O act like `Channel#receive` when that's like the cornerstone of the concurrency patterns?
<oprypin> the typical effect on this is that I see your messages from Gitter only when someone else writes the next message, either on Gitter or on IRC
<oprypin> asterite, the point here is that it's possible to make it so `gets` instantly returns nil in a loop and does not block
<FromGitter> <asterite> `Channel#receive` kind of works the same way: if there's nothing there it will block (yield to another fiber) and when there's data it will resume that fiber
<FromGitter> <jemc> @asterite - that's exactly how I want IO to act
<FromGitter> <jemc> I guess I need to add a check for if the FD is closed, to break the loop?
<FromGitter> <asterite> if `gets` returns `nil` it means the FD is closed
<oprypin> `echo a | crystal eval 'loop { p STDIN.gets }'` illustrates this
<oprypin> yeah dont loop on nil
<oprypin> BUT if I just run `crystal eval 'loop { p STDIN.gets }'` then i press Ctrl+D it can return nil once but then i can ceep typing and it will be non-nil
<FromGitter> <asterite> (but I'm probably misunderstanding something)
<FromGitter> <asterite> oprypin: yeah, that's strange. On the other hand I see the same behavior in Ruby, so it might have something to do with the console
greengriminal has quit [Quit: This computer has gone to sleep]
<oprypin> maybe
<FromGitter> <jemc> oprypin: but I can just check `IO#closed?` instead of basing my `break` on the return value, and I'll be golden, right?
<FromGitter> <jemc> :)
<FromGitter> <jemc> looks like `IO#closed?` returns `false` for me
<FromGitter> <jemc> when I run `echo a | crystal eval 'loop { p STDIN.gets; p STDIN.closed? }'`
<FromGitter> <asterite> Right... maybe a think with STDIN. On the other hand Ruby prints the same :-S
<FromGitter> <asterite> but why can't you use the return value from `gets`? If it's `nil` it means there's no more data
<FromGitter> <jemc> oprypin just mentioned an issue with that above
<FromGitter> <jemc> > *<oprypin>* BUT if I just run `crystal eval 'loop { p STDIN.gets }'` then i press Ctrl+D it can return nil once but then i can ceep typing and it will be non-nil
FromGitter has quit [Remote host closed the connection]
FromGitter has joined #crystal-lang
<FromGitter> <jemc> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5bdcbcdba9c55b25749a4e6d]
<FromGitter> <asterite> you can raise an error if you get `nil` :-)
<FromGitter> <jemc> is the issue oprypin mentioned above not a concern?
<oprypin> like, it still behaves exactly the same as ruby
<FromGitter> <asterite> I don't know because it works the same as in Ruby
<oprypin> ruby -e 'loop { p STDIN.gets }'
<FromGitter> <jemc> yeah, I see that
<FromGitter> <jemc> it's still pretty weird
<FromGitter> <jemc> but I suppose that the Ctrl+D usage probably won't affect my actual use case
<oprypin> jemc, FWIW this is read_partial equivalent https://crystal-lang.org/api/0.27.0/IO.html#read%28slice%3ABytes%29-instance-method
<FromGitter> <jemc> well, thanks for the troubleshooting help
<FromGitter> <jemc> ah, excellent, thanks
<oprypin> jemc, `buf = Bytes.new(0xffff); while STDIN.read(buf) > 0; end`
<FromGitter> <jemc> that'll serve me well when I'm not dealing with a `\n`-terminated protocol
<oprypin> and if you want `gets` to raise on EOF, that's what `read_line` does
<FromGitter> <jemc> thanks
FromGitter has quit [Remote host closed the connection]
FromGitter has joined #crystal-lang
<FromGitter> <jemc> I appreciate the patience and the help
return0e_ has quit [Remote host closed the connection]
return0e has joined #crystal-lang
<oprypin> `<<` is implemented with obj.to_s(self) but obj.to_s(io) is implemented with `io << stuff`
FromGitter has quit [Remote host closed the connection]
FromGitter has joined #crystal-lang
<FromGitter> <oprypin> added `.flush` in addition to `flush_on_newline`, hopefully this will work
<oprypin> and it did :/
<oprypin> `flush_on_newline` is broken on TCPSocket and while trying to understand why, i realized that i have no idea how `TCPSocket#<<` even works, it's supposed to be an endless recursion
<oprypin> is there a good way to make a repro with sockets locally?
<oprypin> ah i guess just make a server locally
<oprypin> nvm, it's probably specific to SSL socket
jemc has joined #crystal-lang
t0nyandre has joined #crystal-lang
t0nyandre has quit [Ping timeout: 268 seconds]
<oprypin> yes, made a repro!!
jemc has quit [Ping timeout: 244 seconds]
<oprypin> but it fails on an old version of crystal -_- `BIO routines:bio_read_intern:unsupported method (OpenSSL::SSL::Error)` - what am i supposed to do with this
jemc has joined #crystal-lang
<oprypin> posted #7021
ashirase has joined #crystal-lang
<FromGitter> <vladfaust> @bew, ⏎ ⏎ > @vladfaust using `read_file` for this won't work, because the file path won't pass through require's file resolution system ⏎ ⏎ I think `__DIR__/lib` will work in this case [https://gitter.im/crystal-lang/crystal?at=5bdcde54995818347b9441e4]
<FromGitter> <vladfaust> However, `require?` is useful IMO
<FromGitter> <bajro17> is crystal 0.27 out?
<FromGitter> <Blacksmoke16> yes, updated via apt hour or so ago