<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> 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
<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>
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> (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
<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> 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>
<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