jhass changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Crystal 0.35.1 | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
deavmi has quit [Ping timeout: 256 seconds]
deavmi has joined #crystal-lang
postmodern has joined #crystal-lang
oddp has quit [Ping timeout: 256 seconds]
_whitelogger has joined #crystal-lang
<FromGitter> <mwlang> hmmm...any significant changes to `JSON::PullParser` and `JSON::Serializable`
<FromGitter> <Blacksmoke16> some stuff related to enums iirc
<FromGitter> <Blacksmoke16> why whats the error?
<FromGitter> <mwlang> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f2e00699231d665df62bbd6]
<FromGitter> <Blacksmoke16> sure the input just isnt an array when it should be an obj?
<FromGitter> <Blacksmoke16> `pull.kind == :begin_array`
<FromGitter> <Blacksmoke16> `pull.kind.begin_array?`
<FromGitter> <Blacksmoke16> try that
<FromGitter> <mwlang> ok
<FromGitter> <mwlang> that solved it.
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <mwlang> now to fix the other 6 or so. :-D
alexherbo2 has quit [Ping timeout: 240 seconds]
<postmodern> is there something like getter! but lets you specify the error class to raise-on-nil?
<postmodern> trying to define a getter that returns Foo or @[Raises(Unsupported)], but the compiler keeps saying the return signature is Nil | Foo
<FromGitter> <Blacksmoke16> define the getter yourself
<FromGitter> <Blacksmoke16> ```def foo ⏎ @foo || raise Unsupported.new ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5f2e0a4879da21426f1edff3]
<postmodern> trying to but getting that type signature error
<FromGitter> <Blacksmoke16> can you make an example?
<postmodern> ah that did the trick
<FromGitter> <Blacksmoke16> 👍
<postmodern> i was trying to do unless @foo ... raise ... end ... return @foo
<FromGitter> <Blacksmoke16> yea that wouldnt help
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 256 seconds]
duane has quit [Remote host closed the connection]
<FromGitter> <mwlang> If I set cossack to ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f2e0dcb88719865d948562f]
<FromGitter> <Blacksmoke16> Try adding like --ignore-crystal-version
<FromGitter> <mwlang> The weird thing is that the output did show that it changed. before the update, `shards update` showed: `Using cossack (0.1.4 at 0fba91e)` and while running the `shards update cossack` command, it output `Using cossack (0.1.5 at dc6dc41)`
<FromGitter> <Blacksmoke16> Or something like that
<FromGitter> <Blacksmoke16> Or maybe try deleting lib and shard.lock
<FromGitter> <mwlang> whacked. This time it outputs `Installing cossack (0.1.5 at dc6dc41)`
<FromGitter> <Blacksmoke16> Nice
<FromGitter> <Blacksmoke16> oh i read that as `worked`
Human_G33k has quit [Ping timeout: 264 seconds]
gangstacat has quit [Ping timeout: 272 seconds]
Human_G33k has joined #crystal-lang
<FromGitter> <mwlang> It did work!
<FromGitter> <mwlang> without the --ignore-crystal-version flag, it'll say "Using" instead of "Installing" on that 0.1.5 at dc6dc41 commit SHA
<FromGitter> <mwlang> so probably a bug in shards
DTZUZU has quit [Quit: WeeChat 2.8]
<FromGitter> <mwlang> I'm guessing HTTP::WebSocket has changed significantly as well... ⏎ ⏎ `````` [https://gitter.im/crystal-lang/crystal?at=5f2e17fb88719865d9486d7e]
gangstacat has joined #crystal-lang
<FromGitter> <mwlang> yup, CloseCode and String are returned instead of just a String
<FromGitter> <mwlang> Has the size of an integer for the JSON any class changed? For value 5292811062 I get ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f2e1aafe20413052e72d775]
<FromGitter> <mwlang> nevermind -- just realized I truly am busting 32-bit limit
_whitelogger has joined #crystal-lang
Human_G33k has quit [Ping timeout: 240 seconds]
<postmodern> so @[Deprecaated] only shows up in the documentation? There's no way to warn at compile or runtime time?
Human_G33k has joined #crystal-lang
<postmodern> hmm suppose i could use a macro to somehow check for @[Deprecated]. I'm trying to tag a C enum element with @[Deprecated] and filter it out of other macro code that loops over the enum
_whitelogger has joined #crystal-lang
Human_G33k has quit [Ping timeout: 264 seconds]
<postmodern> hair splitting question, is Pointer(T)#address the address _of_ the pointer or the address the pointer is pointing _to_
<postmodern> nm appears to be the pointer's "to" address
Human_G33k has joined #crystal-lang
<postmodern> would crystal's GC possibly fight with LibC.mmap'd memory? I have gotten the point where i am getting V4L2 to read frames into mmap Bytes slices, but when I print them out it prints "Bytes[" then Invalid memory access at 0xffffffffffffffff
<postmodern> making progress one error at a time :)
<FromGitter> <benphelps> is there a way to specify types on hash keys ?
<FromGitter> <benphelps> well, types on hash key/value pairs i guess
<FromGitter> <benphelps> `{ :input => "1+1", :expected => 2 }` ⏎ where I define :input has a string value and :expected has an Int32 value
_whitelogger has joined #crystal-lang
Human_G33k has quit [Ping timeout: 260 seconds]
Human_G33k has joined #crystal-lang
alexherbo2 has joined #crystal-lang
Human_G33k has quit [Ping timeout: 240 seconds]
<postmodern> benphelps, { :input => "...", :expected => 2} of Symbol => (String | Int32)
<postmodern> benphelps, but you probably want a NamedTuple
Human_G33k has joined #crystal-lang
<postmodern> benphelps, NamedTuple(input: String, expected: Int32).new(input: "1+1", expected: 2)
<postmodern> because Hashes can contain any number of pairs
oddp has joined #crystal-lang
Human_G33k has quit [Ping timeout: 264 seconds]
Human_G33k has joined #crystal-lang
<postmodern> is there a way to define a method overload where one of the arguments is a literal value, like from an enum?
<postmodern> hmm found my probllem with mmap. I'm testing for pointer.address == LibC::MAP_FAILED, but it's not catching the 0xffffffffffffffff address
<postmodern> note that MAP_FAILED = Pointer(Void).new(-1)
<postmodern> ah needed pointer == LibC::MAP_FAILED
<postmodern> one step forward, two steps back. the v4l2 api is "interestingly" design
<yxhuvud> What is v4l2?
<yxhuvud> postmodern, benphelps: personally I'd use a record in that situation, record SomeNiceName, input : String, expected : Int32.
<yxhuvud> That also allows for methods on it.
<FromGitter> <Blacksmoke16> ^
<postmodern> yxhuvud, Video 4 Linux (2) API. It provides direct kernel access to webcams, as well as a lesser used deep and big API for TV and Digital SDR cards
<postmodern> yxhuvud, https://gist.github.com/maxlapshin/1253534 the API allows for three separate ways of reading data, each with slight variations with how you handle the data you store on your side and what the kernel gives back to you via the ioctl()'ed structs
<yxhuvud> Ah, I see.
<postmodern> so far i have all of the C stuff mapped in, now just writing the classes that wrap around all of that and define the behavior
<FromGitter> <Blacksmoke16> Best bet would be a method restricted to the enum then use a case in
<postmodern> Blacksmoke16, can enums be restricted by the argument signature, or do you have to do that in code with case/when/raise?
<yxhuvud> You can't restrict by value, only by type, if that is what you are asking.
<postmodern> ah dang
<postmodern> was hoping to do something like #allocate(memory : Memory::USER_PTR, length : UInt32) and #allocate(memory : Memory::MMAP) or such
<postmodern> that would save me from having separate #mmap() and #malloc(length : UInt32) methods
<yxhuvud> that particular example have different signature though, so that would work even if the type system wouldn't enforce it being correct.
<yxhuvud> so correct parameters would have to be verified in the method body. :/
<postmodern> ah because the enum values are instances of the same enum. hmm
<yxhuvud> or well, you'd have to have memory as a Memory, but it would dispatch differently due to the length parameter being there or not
Human_G33k has quit [Remote host closed the connection]
Human_G33k has joined #crystal-lang
<FromGitter> <Blacksmoke16> Yea you can't, hence my case in suggestion
<FromGitter> <benphelps> @postmodern, yep named tuple is what I wanted, thank you
<FromGitter> <Blacksmoke16> a struct would most likely be better tho
<FromGitter> <benphelps> i don't know if it needs to be on the stack though since it's just tests
<FromGitter> <Blacksmoke16> named tuples are as well
<FromGitter> <benphelps> oh
<FromGitter> <Blacksmoke16> majority of the time you should use a struct versus a named tuple
oddp has quit [Quit: quit]
DTZUZU has joined #crystal-lang
<FromGitter> <j8r> Yeah a struct is usually better
<FromGitter> <j8r> You can also add API docs about each getter, or property. In your case, what is `expected`and `input`. ⏎ Plus, methods can be added
<FromGitter> <j8r> The main thing practical about NamedTuple is splat it to a method as `**kwarg`, and eventually iterating over each key
<FromGitter> <j8r> And also for tests
Human_G33k has quit [Remote host closed the connection]
Human_G33k has joined #crystal-lang
f1reflyylmao has quit [Ping timeout: 244 seconds]
f1refly has joined #crystal-lang
postmodern has quit [Quit: Leaving]
HumanGeek has joined #crystal-lang
Human_G33k has quit [Ping timeout: 240 seconds]
<FromGitter> <Blacksmoke16> splat the args into a struct 😉
oddp has joined #crystal-lang
Dreamer3 has joined #crystal-lang
<FromGitter> <Blacksmoke16> mm yes, these test cases are working out well
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f2ef36988719865d94a8d55]
<FromGitter> <Blacksmoke16> nice and simple :) ⏎ /
<FromGitter> <Blacksmoke16> results in ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f2ef39de20413052e74f2a5]
<FromGitter> <Blacksmoke16> (each as an `it` block)
<FromGitter> <Blacksmoke16> > *<postmodern>* so @[Deprecaated] only shows up in the documentation? There's no way to warn at compile or runtime time? ⏎ ⏎ See https://github.com/crystal-lang/crystal/issues/9246
<FromGitter> <Blacksmoke16> similar idea, but im pretty sure it also prints a warning if you're using a deprecated method
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f2efc69dca038052a57d5d3]
<FromGitter> <Blacksmoke16> ```83 | foo ⏎ ^-- ⏎ Warning: Deprecated top-level foo. ⏎ ⏎ A total of 1 warnings were found.``` [https://gitter.im/crystal-lang/crystal?at=5f2efc7251bb7d3380db4404]
zorp has quit [Ping timeout: 240 seconds]
<oprypin> i pass an expression to a macro. is there any way to get at compile time the typeof the expression ?
<FromGitter> <Blacksmoke16> like what it would be at runtime?
<oprypin> yes
<oprypin> actually no
<oprypin> typeof(1 + 2) is not runtime
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <Blacksmoke16> not as far as i know
<oprypin> anyway, i want a macro to act differently depending on the type passed to it
<FromGitter> <Blacksmoke16> i think you could know that its a `NumberLiteral`
<FromGitter> <Blacksmoke16> if that would help,
<FromGitter> <Blacksmoke16> i.e. like
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f2f0824fe39ca5d658ccae5]
<oprypin> well no this particular case is Call(receiver: NumberLiteral, name: "+", args: [NumberLiteral])
<FromGitter> <Blacksmoke16> cant just access the data in call?
<oprypin> well i dont want to reimplement type deduction entirely
<FromGitter> <Blacksmoke16> fair
<oprypin> actually makes sense that this is not possible
<oprypin> my main issue is that not all my possible values are literls
<FromGitter> <Blacksmoke16> gl
<FromGitter> <Blacksmoke16> seems like a non trivial problem
zorp has joined #crystal-lang
<oprypin> aw, cant get a pointer to a class variable?
<FromGitter> <dscottboggs_gitlab> hm?
<oprypin> class Foo; @@a = 5; end; pointerof(Foo.@@a)
<FromGitter> <dscottboggs_gitlab> hm. seems you can't
zorp has quit [Read error: Connection reset by peer]
<oprypin> wow this is surprising https://carc.in/#/r/9ilq
<oprypin> and no macro {%while %} 😬
<FromGitter> <Blacksmoke16> isnt a way to break either so cant even workaround it
<FromGitter> <Blacksmoke16> actually i have a solution :P
<FromGitter> <Blacksmoke16> sec
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/9ilv :S
<FromGitter> <Blacksmoke16> just dont push an item to break out
<oprypin> oh
<oprypin> that could actually work
<FromGitter> <Blacksmoke16> less than ideal but yea, should do the trick
<FromGitter> <dscottboggs_gitlab> I can imagine that would be brutal for compiler performance
<FromGitter> <Blacksmoke16> :shrug: from i know large unions have a larger impact
<FromGitter> <Blacksmoke16> my exp at least*
<FromGitter> <dscottboggs_gitlab> yeah that would be *really* bad lol
<FromGitter> <j8r> oprypin you can use free variables in a regular method
<FromGitter> <j8r> and, why a macro particularly?
<FromGitter> <j8r> @Blacksmoke16 weird, just use `(0..100)`
<FromGitter> <Blacksmoke16> point was to show it could be infinite, with a breakout path
<FromGitter> <j8r> ha yes
<FromGitter> <j8r> In fact usually `for` loops and `#each` are based on `while`
<FromGitter> <j8r> does not surprise me to have infinite iteration then
<oprypin> check https://bpa.st/WARQ line 48 and 56
<oprypin> it works
<oprypin> i ended up not using a stack and instead just hoping that there will never be repetitions in the array of items
<FromGitter> <sirikon> Hello there, I noticed a problem and I'm not sure if it's a bug or I'm not understanding something: ⏎ ⏎ In the Crystal reference -> Concurrency -> Spawning a fiber and waiting for it to complete, there is this example: ⏎ ⏎ ```Before receive ⏎ Before send ⏎ After send ⏎ After receive``` [https://gitter.im/crystal-lang/crystal?at=5f2f16cc79da21426f216645]
<FromGitter> <sirikon> But if I change the example to this: ⏎ ⏎ ```Before send ⏎ Before receive ⏎ After receive ⏎ After send``` [https://gitter.im/crystal-lang/crystal?at=5f2f170765e829425e6eb20b]
<FromGitter> <sirikon> I saw this issue about *Buffered* channels: https://github.com/crystal-lang/crystal/issues/9661 saying that the docs need to be updated, but this is not a buffered channel...
<FromGitter> <j8r> there are buffered channels?
<FromGitter> <sirikon> By buffered I mean capacity greater than zero
<FromGitter> <j8r> in the examples above, there is no order to expect
<FromGitter> <sirikon> In the example of the reference, `puts "After send"` should not be called before `puts "After receive"`
<FromGitter> <sirikon> and it gets called
<FromGitter> <j8r> why?
<FromGitter> <sirikon> That's what I'm asking 😂
<FromGitter> <j8r> no, it can be, or not
<FromGitter> <j8r> There a 2 fibers: the main one, the one you spawned. ⏎ They do things, like putsing to STDOUT. One may do after or before the other, depends
<FromGitter> <j8r> and they do this in parallel (or one can say in concurrence)
<FromGitter> <sirikon> When calling `channel.send(nil)` on a channel with capacity `0`, I expect it to wait until the fiber that called `channel.receive` finishes or sleeps
<FromGitter> <sirikon> Isn't that correct?
<FromGitter> <j8r> receive blocks yes
<FromGitter> <j8r> In the first example, after this method, the 2 `puts` will execute in parallel
<FromGitter> <sirikon> Crystal doesn't have parallelism
<FromGitter> <j8r> but only one can go before the other, because of IO
<FromGitter> <sirikon> (at least not by default)
<FromGitter> <j8r> in concurrence if you prefer
<FromGitter> <sirikon> parallelism != concurrency, the terms are important
<FromGitter> <j8r> the result would be the same anyway
<FromGitter> <j8r> spawning fibers or threads in this case would be the same, because only 1 write can be done at a time to STDOUT
<FromGitter> <sirikon> of course, but thanks to the channels `send` and `receive` I expect an order
<FromGitter> <j8r> Otherwise you'll have overlapping texts
<FromGitter> <sirikon> Because one block should wait the other
<FromGitter> <j8r> `receive` waits a value, sent by `send`
<FromGitter> <j8r> that's it
<FromGitter> <j8r> don't expect any order before, and any order after
<FromGitter> <j8r> just that the `before` would be before, and the `after` after
<FromGitter> <sirikon> That's not what the documentation and the example shows :/
<FromGitter> <sirikon> > Then channel.send(nil) is invoked, and so execution continues at channel.receive, which was waiting for a value. Then the main fiber continues executing and finishes, so the program exits without giving the other fiber a chance to print "After send".
<FromGitter> <sirikon> It shouldn't even print "After send"
<FromGitter> <j8r> Yes, that's why @asterite said in his comment - docs outdated, don't rely on order
sorcus has quit [Ping timeout: 246 seconds]
<FromGitter> <sirikon> Ok, so it applies to every Channel, buffered or not.
<FromGitter> <sirikon> Is there any post or written reasoning about not ensuring this order on execution?
<FromGitter> <sirikon> Because I think it's crucial, and cumbersome if the order isn't respected. I'm actually having many issues with this
<FromGitter> <Blacksmoke16> prob because with MT?
<FromGitter> <sirikon> I think it's possible to maintain execution order with channels and multithreading
<FromGitter> <sirikon> it's their purpose, in part
<FromGitter> <Blacksmoke16> :shrug: not super familiar with it
<FromGitter> <j8r> why you just send something at the end of the `spawn`?
<FromGitter> <j8r> Then, `receive` will block until it finishes
<FromGitter> <sirikon> My use case is a little bit more complicated than that
<FromGitter> <sirikon> currently to prevent issues, I have a boolean that turns to `true` when a communication channel is closed, so I can synchronize two fibers without exceptions, `channel.send` that lock forever, etc
<FromGitter> <j8r> you have many fibers in the story?
<FromGitter> ... in-memory array, and each byte received from the process is sent to each block in the array, so the web server gets the bytes and sends them thru the HTTP connection. [https://gitter.im/crystal-lang/crystal?at=5f2f1f07dca038052a58284e]
<FromGitter> <sirikon> I have a `Process` that captures the stdout and is sent to a "Data service" ⏎ ⏎ The "data service" does two things: Stores the stdout in disk *and* allows other parts of the program to subscribe to the stdout, so they receive a copy in real time. ⏎ ⏎ Then I have a web server that, on an specific route, will subscribe to that process's stdout. The mechanism is just leaving a block stored in an
<FromGitter> <sirikon> The problem comes from handling client disconnections. The user could reload the page and the connection gets closed and re-opened. In that case I'll know when trying to write to the http response, it fails. ⏎ ⏎ In that moment I send a `nil` thru a channel, so the fiber that keeps the http connection alive can cancel the subscription to the data service and close the request.
<FromGitter> <sirikon> my problem is: Because the `send(nil)` doesn't force the `receive` to be executed first, I get a bunch of extra bytes that will fail because the request is already clossed by the client.
<FromGitter> <sirikon> So I need to have a `bool` that says if the request is alive or not, and prevent more exceptions
<FromGitter> <sirikon> this wouldn't happen, and would be way easier, if the execution order of channels were respected
<FromGitter> <j8r> I don't thing you need a channel
<FromGitter> <j8r> what is the subscribe, adding the Client IO into an array?
<FromGitter> <sirikon> adds a block, defined in the http request context
<FromGitter> <sirikon> so the block gets called with new bytes to be sent
<FromGitter> <sirikon> wether I need a channel for that or not is another story, my main issue right now is that channels doesn't behave as I would expect xD
<FromGitter> <j8r> I think it would be better to use websockets here...
<FromGitter> <j8r> I have a Set of current connections, which is removed on `on_close`
<FromGitter> <asterite> @sirikon the reason is that it's more efficient not to switch to another fiber right away
<FromGitter> <j8r> so you append the bytes in the `HTTP::Client::Response`?
<FromGitter> <asterite> or that's what I remember (I didn't implement any of that and I didn't make the change in how it works)
<FromGitter> <sirikon> I prefer to stream info in an http request because the extra overhead to do so is absolute zero. The frontend receives a lot of information and don't want the extra bytes of websockets backs and forths. ⏎ ⏎ Also I'm not sending info from client to server
<FromGitter> <j8r> Why not having a set of `HTTP::Client::Response`? ⏎ On each new byte of the Process stdout, iterate over it.
<FromGitter> <j8r> If there is an exception, delete the value from the set.
<FromGitter> <j8r> Or a `Hash` if the set don't work
<FromGitter> <sirikon> @j8r It's a possibility, but still, my issue is with Channels. Can change the implementation to have less problems in general anyway
<FromGitter> <j8r> You won't have problems. You know, each request is already in its own fiber anyway
<FromGitter> <sirikon> @asterite Who did the change? I would love to hear the reasons for that
alexherbo2 has quit [Ping timeout: 264 seconds]
<FromGitter> <sirikon> Will ask in the forum about the topic
<FromGitter> <asterite> its been asked
<FromGitter> <asterite> before
oddp has quit [Quit: quit]
Dreamer3 has quit [Quit: Leaving...]