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: 240 seconds]
deavmi has joined #crystal-lang
HumanGeek has quit [Read error: Connection reset by peer]
HumanG33k has joined #crystal-lang
HumanG33k has quit [Ping timeout: 264 seconds]
HumanG33k has joined #crystal-lang
<FromGitter> <Blacksmoke16> best way to determine if an array has any duplicate values?
<FromGitter> <Blacksmoke16> er actually an `Indexable`
<FromGitter> <Blacksmoke16> `collection.tally.each_value.any &.>(1)`?
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 256 seconds]
postmodern has joined #crystal-lang
<postmodern> does crystal have something like StandardError? Something to denote that the programmer made a mistake, instead of a call failing for some system issue
<postmodern> also is there a macro for defining NotImplementedError methods?
<postmodern> (methods that are placeholders and just raise NotImplementedError)
<postmodern> wooohooo i finally read my first v4l2 frame with crystal
<postmodern> I'm noticing that Slice(UInt8) gets converted to Bytes when i `p` the slice. Are type aliases bi-directional? Is it possible to define a Slice(UInt8) or does it automatically get converted to Bytes? Or is `p` pretty-printing converting it to Bytes?
zorp has joined #crystal-lang
alexherbo2 has joined #crystal-lang
<postmodern> also how does crystal handle IO.select ? Doing a select() or poll() is how most v4l2 programs determine when data is available.
<postmodern> ah i guess i can use LibC.select. The C programs appear to just use select() as a kind of wait/timeout for data. Might have to wrap that up into a Channel as well, so I can read simultaneusly from multiple V4L2::Devices.
<postmodern> hmm how does one use FdSet? do I just write into the static array of FdMasks (really just Long)?
<yxhuvud> Bytes is defined as alias Bytes = Slice(UInt8)
<yxhuvud> crystal uses libevent, which is poll-based.
<yxhuvud> As for the Standarderror question, there was a issue/pr about what to do with those, but I can't find it again.
<yxhuvud> (and yes, aliases are bidirectional. I'd guess there is some special handling in the printing if it actually says 'Bytes'.)
<yxhuvud> Yeah, there is. See Slice#pretty_print
<yxhuvud> or #to_s
sorcus has joined #crystal-lang
<postmodern> yxhuvud, ah ha
<postmodern> yxhuvud, i still need some way of testing an fd (Int32) then do an ioctl() to dequeue the v4l2 buffer that points to which user-side buffer holds the data
<postmodern> yxhuvud, you can also just read() on fd, but i think that's slower/provides less information than the buffer method
<yxhuvud> I'm very much not certain how to do that in a way that plays well with the event loop. if there isn't an IO subclass that polls that fit your needs you may have a hard time. It might be possible to deduce how to do it by looking at socket.cr, but that is definitely in the deep side of the pool
<postmodern> yxhuvud, https://gist.github.com/maxlapshin/1253534#file-capture_raw_frames-c-L186-L212 is there a way I could initialize some kind of IO class around the fd and poll that way?
<yxhuvud> Looking around, it may be that IO::FileDescriptor.new(fd, blocking: false) could be what you need.
<yxhuvud> or ugh. That includes IO::Buffered which buffer, which you may nor may not want. :shrug:
<postmodern> oh that will help me when reading directly from the fd, but not sure how i'd only poll() the fd but not read from it directly
<postmodern> yeah it's basically a blocking read from the fd with a fixed size: https://gist.github.com/maxlapshin/1253534#file-capture_raw_frames-c-L93-L106
<yxhuvud> ah ok, you want to only look to see if you should do something. I don't think that is documented or exposed in a user friendly way, but in any case it boils down to using #wait_readable.
<yxhuvud> I think it an api that is not intended to be used by the public, but it *should* work. It is defined in evented.cr
<yxhuvud> I have .. spent a bit more time than I should looking at those pieces of code as I'm (slowly!) hacking together an event loop driven by io_uring
<FromGitter> <j8r> @Blacksmoke16 ...Use a set?
<FromGitter> <j8r> Could be more efficient, don't know
<FromGitter> <j8r> Like `Set.new array.size`, then use `add?`
postmodern has quit [Remote host closed the connection]
postmodern has joined #crystal-lang
<oprypin> Blacksmoke16, yea definitely a set. if the set's size < array size
<FromGitter> <j8r> The oprypin's option is shorter. Creating a Set from an array use `#concat`, which use `#each` + `#<<`. If you do it yourself an break early if `add?` is `false`, it will be more efficient. May not matter though, depends how many times and the sizes
<oprypin> >> a = [1, 2, 2, 3]; s = Set(Int32).new; a.any? { |x| s.add?(x) }
<DeBot> oprypin: # => true - https://carc.in/#/r/9ioh
<oprypin> j8r, oh i didnt understand your suggestion at first. it is in fact the optimal suggestion
<oprypin> >> a = [1, 2, 2, 3]; s = Set(Int32).new; a.any? { |x| s.all?(x) } #correction
<DeBot> oprypin: # => true - https://carc.in/#/r/9ioi
<FromGitter> <j8r> Ho, there is`Array#to_set` from `Enumerable`
<FromGitter> <j8r> anyway,won't be as efficient :)
<oprypin> omg what have i written
<oprypin> >> a = [1, 2, 2, 3]; s = Set(Int32).new; a.all? { |x| s.add?(x) } # actual correction
<DeBot> oprypin: # => false - https://carc.in/#/r/9ioj
<FromGitter> <j8r> Haven't thought about `all?`, nice
<FromGitter> <j8r> a bit better: https://carc.in/#/r/9iol
<postmodern> is there a slick crystal way of automatically converting a NamedTuple into a C Struct value upon assignment? (ex: `@struct.parm.capture.timeperframe = new_time_per_frame` where `new_time_per_frame` is a Fract tuple/named-tuple of (numerator/denominator))
<postmodern> trying to think of a way to implicitly splat the nominator/denominaotr from the named-tuple/tuple into the struct without having to unpack the tuple each time i try to assign one to a struct field
<yxhuvud> is it a 1:1 match or do the namedtuple have a bigger interface?
<yxhuvud> or wait, are you modifying an existing struct in place rahter than creating a new one?
<postmodern> existing struct in pace, it only has two members nominator and denominator. So will the named-tuple/tuple.
<postmodern> could also probably do a full struct value assignment
<oprypin> postmodern, at that point what insane justification do you have to still be using a namedtuple
<oprypin> postmodern, https://carc.in/#/r/9ioq
<oprypin> thats my attempt to answer the right question - "what is the better alternative to namedtuple here"
<postmodern> oprypin, note this is for doing a struct member assignment of a Linu::V4L2Fract (nominator : UInt32, denominator : UInt32). Obviously initializing the C struct Linux::V4L2Fract is a bit of work, so i was hoping to use a Tuple or NamedTuple and converting it back to the V4L2Fract or maybe splatting it into an assignment
<oprypin> postmodern, what is the relevance of namedtuple
<oprypin> like, what advantage do you think you are getting from using a namedtuple instead of a struct
<postmodern> oprypin, it's easier to initialize than initializing Linux::V4L2Fract (a C struct) directly
<oprypin> is it?
<postmodern> yes
<oprypin> see my example, in it it's just `fract(1, 2)`
<postmodern> i already saw it and gave you my feedback
<oprypin> i dont understand though
<oprypin> in the example i gave, struct Fract *is* Linux::V4L2Fract
<postmodern> because i'm working with C bindings, where the fract eventually has to be of type Linux::V4L2Fract
<postmodern> also if i remember correctly, C structs cannot have custom methods or initializers
<oprypin> postmodern: well i showed you a secret feature that they can
<postmodern> oprypin, and i already gave you feedback
<oprypin> there's really no such thing at the ABI level as a "C struct" or "not C struct", and the actual struct is not a part of the shared library's interface, it's just "pass those two things in a particular layout"
<oprypin> you just change the bindings definition to use this `Fract` struct and it will just work
<oprypin> ex v
<oprypin> and, other than this knowledge of an entirely separate approach,
<oprypin> yes, technically it is easier to splat a namedtuple. but for a struct it's also one tiny helper method away
<postmodern> oprypin, either i am not understanding you, or you are not understanding my use-case. Either way, here is some example code based on your suggestion of using Fract. It does not compile. https://play.crystal-lang.org/#/r/9iou
<oprypin> postmodern:
<oprypin> replace V4L2Fract with Fract everywhere
<oprypin> and delete struct V4L2Fract
<yxhuvud> oprypin: while I agree that namedtuples are to be avoided when possible, there was nothing in the question that suggested that the nametuple wasn't created by the actual intended usecase, ie some named argument list that was passed along.
<postmodern> oprypin, remember when i said that C structs cannot have custom initializers? :) https://play.crystal-lang.org/#/r/9iow
<oprypin> yxhuvud: oh i see. makes sense
<oprypin> my apologies :(
<oprypin> postmodern: you deleted struct Fract
<oprypin> i say [14:26:04] <ffffffoprypin> and delete struct V4L2Fract
<postmodern> it would be _great_ if C structs (which are _slihtly_ different from regular struct declarations) could have custom initializers
<oprypin> C structs were a mistake
<oprypin> i tried to push a change to disallow `struct` inside `lib`
<yxhuvud> they may be necessary unless we want to inherit all the packed-ness and other stuff that c-structs have. Or lose interoperability.
<postmodern> oprypin, https://play.crystal-lang.org/#/r/9iox here is it with a top level Fract, again a type error
<oprypin> but only the part to allow struct outside of lib was implemented
<oprypin> postmodern: ok now delete
<oprypin> delete struct Fract from inside the lib
<postmodern> oprypin, how about you work on that code
<oprypin> keep only the external one
<oprypin> sorry lol im in shower on my phone
<postmodern> lol who does IRC support in the shower. and is your phone waterproof?
<oprypin> it's great that you showed the example, it's just not possible to edit play.crysral on a phone
<oprypin> yes ip68 or whatever
<yxhuvud> oprypin: still in stockholm? It's hot today.
<postmodern> oh i get wwhat your trying to do
<postmodern> essentially define the struct layout _outside_ of the lib space
<postmodern> tempting, but i'd like to keep the full lib space 1:1 with the actual library/headers
<postmodern> if C structs could have custom #initialize methods, then i could just do `alias Fract = Linux::V4L2Fract`
<oprypin> yxhuvud: nope :s
<oprypin> postmodern: yes C structs are weird, what to say
<postmodern> also curious why C structs don't have a default initalize that accepts keyword args or something?
<oprypin> it does i think?
<oprypin> it's *only* keyword though
<postmodern> so what's with the @[Extern] keyboard? is that essentially the same thing as defining stuff inside a lib ... end block?
<oprypin> no it only ensures the field layout is exactly like in C
<oprypin> though in my experience it's like that even without the keyword
<oprypin> as i was saying, shared libraries have no concept of type safety, so anything that matches the same data layout will do
<oprypin> so i just say instead of converting between two things that represent the same concept *and* have the exact same data layout, just use one
<yxhuvud> How do you suggest unions would be handled?
<yxhuvud> C unions, that is.
<oprypin> oh I'm sure there could be a solution
<postmodern> just specify one keyword arg?
<oprypin> but nobody will look into that anyway
<yxhuvud> personally I feel the current solution is a bit weak in that unions and nested structs can't be defined inline. But perhaps I'm colored by trying to create bindings for a monster struct.
_whitelogger has joined #crystal-lang
<oprypin> >> lib L; struct S; x : Int32; y : Int32; end; end; L::S.new(**{x: 5, y: 6})
<DeBot> oprypin: - L::S.new() - https://carc.in/#/r/9ioz
<oprypin> weird
<oprypin> >> lib L; struct S; x : Int32; y : Int32; end; end; L::S.new(x: 5, y: 6)
<DeBot> oprypin: # => L::S(@x=5, @y=6) - https://carc.in/#/r/9ip0
<oprypin> postmodern: uh yea.. you see what's happening.. i hoped it would just work but apparently the syntax is even more special than i expected
<oprypin> i think a bugfix for this would be accepted easily. but it might entail a refractor to unify the implementations of these constructors with normal methods arg handling
<postmodern> workaround, is there a Fractional like type in Crystal I could convert to this Fract struct behind the scenes?
<oprypin> postmodern: no BigRational is way too heavy of a type
<postmodern> was wondering if crystal had something like ruby's Rational() (but that didn't reduce the fraction to lcd)
<FromGitter> <Blacksmoke16> ah nice, thanks @j8r
<FromGitter> <Blacksmoke16> i guess the challenge will be handling it when the collection could be any indexable, of which i dont know the type
Dreamer3 has joined #crystal-lang
<oprypin> Blacksmoke16, Set(typeof(indexable[0]))
<FromGitter> <Blacksmoke16> oh, yea that would prob do it
oddp has joined #crystal-lang
<oprypin> jesus the Docker CLI is so atrocious
<oprypin> to find any info i basically end up finding ridig tutorials on the internet, and then im like "ok so i had done this step a bit differently" - how do i adapt then? no idea, nothing just works
<oprypin> rigid*
<oprypin> REPOSITORY TAG IMAGE ID CREATED SIZE
<oprypin> <none> <none> b7d2f09bf9a6 12 hours ago 7GB
<oprypin> the *only* thing i figured out how to do with it was `docker run -i -t b7d2f09bf9a6`
<oprypin> ok got it. `sudo docker run -t -d b7d2f09bf9a6` opens the door to actually be able to refer to a running container in other commands
<FromGitter> <Blacksmoke16> cool thanks again, all specs pass using that implementation
ua has quit [Ping timeout: 240 seconds]
ua has joined #crystal-lang
DTZUZU_ has joined #crystal-lang
DTZUZU has quit [Ping timeout: 240 seconds]
<FromGitter> <Kusken> Hi everybody! Started to go through Crystal Syntax yesterday I was having a good time. ⏎ I'm now stuck at setting up an appropriate environment. ⏎ ⏎ I use vscode with the Crystal Language extension https://marketplace.visualstudio.com/items?itemName=faustinoaq.crystal-lang. ⏎ The issue I'm having is that at the top on every file I get this error, (red squiggly-lines) ...
<FromGitter> <Blacksmoke16> are you on mac?
<FromGitter> <Kusken> no I'm on linux
<FromGitter> <Kusken> Tried this both on a debian-vm and in the official docker container published at docker-hub (for crystal lang)
<FromGitter> <Blacksmoke16> looks like the fix was merged but isnt released yet so prob not on the marketplace?
<FromGitter> <Kusken> aah
<FromGitter> <Kusken> okey
<FromGitter> <Kusken> I see now :D Thanks for the direction
<FromGitter> <Blacksmoke16> `0.4.0` is on marketplace, and `0.4.1` was released towards end of may and patch was merged in june, so needs another release/push
<FromGitter> <Kusken> yee seems like it. But I guess I can't be the only one with the issue? The extension is pretty useless for me right now...
<FromGitter> <Blacksmoke16> :shrug: i dont actually use it so not sure if there is a workaround or not
<FromGitter> <Kusken> What do you use? Any alternative to vscode, except for vim?
<FromGitter> <Blacksmoke16> i just use sublime
<FromGitter> <Blacksmoke16> is a plugin that does highlighting and runs formatter on save, is enough for me
<FromGitter> <Kusken> It probably is :)
<FromGitter> <Kusken> I will try to install the extension manually from the github release :D
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Kusken> @Blacksmoke16 Thank you for the directions 👍
<FromGitter> <Blacksmoke16> np
<FromGitter> <Blacksmoke16> > *<postmodern>* does crystal have something like StandardError? Something to denote that the programmer made a mistake, instead of a call failing for some system issue ⏎ ⏎ https://crystal-lang.org/api/master/RuntimeError.html there is this
<FromGitter> <Blacksmoke16> > *<postmodern>* also is there a macro for defining NotImplementedError methods? ⏎ ⏎ no, id just add the method and raise yourself
<postmodern> Blacksmoke16, RuntimeError (and it's subclasses) are usually meant to desribe something that went wrong with the system (ex: diskspace exhausted) vs. something the programmer intentially did that wasn't allowed
<FromGitter> <Blacksmoke16> i mean wouldnt the compiler catch those things?
Dreamer3 has quit [Quit: Leaving...]
<FromGitter> <Blacksmoke16> only thing i can think of would be like dividing by zero or over(under)flows
Human_G33k has joined #crystal-lang
HumanG33k has quit [Ping timeout: 240 seconds]
<yxhuvud> well, stuff like segfaults etc might also qualify. There was an issue around it, but I don't remember the resolution.
<postmodern> Blacksmoke16, compiler cannot guard against specific values of enums or combinations of such values that violate some API constraint
<postmodern> this especially applies to C structs and unions, where depending on what a certain type enum field is, you may or may not access certain fields of the union/struct
postmodern has quit [Quit: Leaving]
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/9ipk im not sure how i feel about that
<FromGitter> <Blacksmoke16> either its genius or a total hack ha
ua has quit [Excess Flood]
<oprypin> ok now i have MSVC installed and running through wine and uh
<oprypin> i can compile my game for windows and try it out
<oprypin> because of course there's some Windows-specific crash with imgui
<oprypin> written in crystal, of course 😉
<oprypin> and this is, of course, in addition to github-actions CI making a standalone windows build
<oprypin> (cuz it's crashing and i have no idea why)
<FromGitter> <Blacksmoke16> 😢
_whitelogger has joined #crystal-lang
ua has joined #crystal-lang
zorp has quit [Ping timeout: 265 seconds]
yxhuvud has quit [Remote host closed the connection]
<oprypin> if im making bindings for a project called "foo-bar" and my repository name is "crystal-foo-bar", what should i have as shard.yml `name: ` and the `src/*.cr`?
<oprypin> `name: foo-bar` and `src/foo-bar.cr` doesnt seem quite right, but neither do underscores
yxhuvud has joined #crystal-lang
<FromGitter> <Blacksmoke16> style guide says to use `_`
<FromGitter> <Blacksmoke16> > File paths match the namespace of their contents. Files are named after the class or namespace they define, with underscore-case.
<FromGitter> <Blacksmoke16> fwiw
<oprypin> Blacksmoke16, ok thats one part. does it follow that shard name also must be underscores?
<FromGitter> <Blacksmoke16> looks like either or
<oprypin> i dont understand though
<FromGitter> <Blacksmoke16> id make it match the file
<oprypin> if im naming my shard foo-bar then i think it *does* follow that there needs to be the file src/foo-bar.cr
<FromGitter> <Blacksmoke16> correct
<FromGitter> <Blacksmoke16> for athena i use `-` to denote they're part of the `Athena` namespace, i.e. `athena-config`, but like `athena-dependency_injection`
<oprypin> O_o
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <Blacksmoke16> yea
<FromGitter> <Blacksmoke16> didnt want the names to be too generic and conflict with another shard or something
<FromGitter> <Blacksmoke16> since the repo names are generic
<FromGitter> <j8r> ho, didn't know GH actions had badges
<FromGitter> <Blacksmoke16> ye, cant point them to a specific job tho, is based on workflow
oprypin has quit [Quit: Bye]
oprypin has joined #crystal-lang
Human_G33k has quit [Ping timeout: 256 seconds]
alexherbo2 has quit [Ping timeout: 260 seconds]
Human_G33k has joined #crystal-lang
<oprypin> is there any way to include a module's class methods?
<FromGitter> <Blacksmoke16> Define them as instance methods, use extend self, then extend into your type
<oprypin> 😬
<oprypin> thanks
johnny101 has joined #crystal-lang
<FromGitter> <j8r> But they may not show properly in the API docs
<FromGitter> <j8r> Just extend is enough, no?
<FromGitter> <Blacksmoke16> not if they're defined using `self.` iirc
<oprypin> yea it wasnt working
Human_G33k has quit [Ping timeout: 265 seconds]