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
alexherbo21 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 264 seconds]
alexherbo21 is now known as alexherbo2
<postmodern> ah ha crystal has a mutex class. maybe in the future we'd have compiler annotations for single-threaded C binding func's?
zorp_ has joined #crystal-lang
alexherbo22 has joined #crystal-lang
Human_G33k has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo22 is now known as alexherbo2
HumanG33k has quit [Ping timeout: 260 seconds]
alexherbo2 has quit [Ping timeout: 258 seconds]
f1refly has joined #crystal-lang
f1reflyylmao has quit [Ping timeout: 256 seconds]
<FromGitter> <mwlang> JSON serialization is the bane of my Crystal existence!
<FromGitter> <Blacksmoke16> oh?
<FromGitter> <mwlang> A somewhat longish example here: https://carc.in/#/r/9nhf But the gist of it is I have a "Collection" that can have zero or more indicators registered with it. If they're registered, they serialize to JSON just fine. but deserializing from JSON back into a collection has me stumped.
<FromGitter> <mwlang> the indicator classes are instantiated with a collection instance so the data points (@values) is centralized. So the to_json somehow needs to set the @collection property when deserializing
<FromGitter> <Blacksmoke16> i can take a look in a sec
<FromGitter> <Blacksmoke16> well the problem after a quick glance is it needs to have a default since its not set within the initializer
<FromGitter> <mwlang> so if I'm deserializing from point of view of the collection, how do I pass its instance into a from_json of an Indicator class?
<FromGitter> <mwlang> actually, I think I'm about to hit the second problem in this equation...how do I know which Indicator class to instantiate when deserializing?
<FromGitter> <Blacksmoke16> discriminator value?
<FromGitter> <mwlang> They live as a Hash, so I do record an `indicator_name` to the JSON output
<FromGitter> <mwlang> but not sure how to reverse that without ending up doing a big, ever growing case statement to instantiate the right Indicator sub-class
<FromGitter> <mwlang> Is there an alternative way to declare the discriminators within each sub-class as they're defined vs in one central place like `use_json_discriminator "type", {point: Point, circle: Circle}`
<FromGitter> <mwlang> I have about 50 indicators, so this list is gonna get gnarly to maintain if it's all in one place.
<FromGitter> <Blacksmoke16> not that i know of
<FromGitter> <mwlang> looks like I'll be writing a crystal spec that reads the name of all indicator files from their subfolder and ensuring they're all in the discriminator list. :-/
<FromGitter> <Blacksmoke16> might be able to generate it via a macro?
<FromGitter> <Blacksmoke16> iterate over subclasses or something
<FromGitter> <mwlang> oh, there's an idea.
<FromGitter> <mwlang> so what's the general approach to supplying the already instantiated `collection` to the indicator's from_json method so it can set it.
<FromGitter> <Blacksmoke16> where does the collection come from?
<FromGitter> <Blacksmoke16> like is it created based on the deserialized data?
<FromGitter> <mwlang> yeah, it's the genesis of the deserialization process... ⏎ `collection = Indicators::Collection.from_json(json_data)`
<FromGitter> <Blacksmoke16> can you overload `self.new` and access it that way?
<FromGitter> <Blacksmoke16> however if you supply an IO idt that would work as the IO would be consumed by the time you pass it to that?
<FromGitter> <mwlang> overloading self.new seems like it might work
<FromGitter> <Blacksmoke16> https://carc.in/#/r/9nhv
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <mwlang> so changing getter to `getter!` for the collection property is the magic sauce here?
<FromGitter> <Blacksmoke16> it at least makes the compiler happy as it defines it as nilable under the hood
<FromGitter> <mwlang> oh, I see. I think I'll come back to this tomorrow with a fresh mind. This makes compiler happy as you say, but it's not quite right, either. Thanks for your help, though! This at least gives me another angle to work from if I need to get things fully deserialized and then sweep back through the indicators loaded and set their collection afterwards.
<FromGitter> <Blacksmoke16> np gl
zorp_ has quit [Ping timeout: 240 seconds]
zorp_ has joined #crystal-lang
alexherbo2 has joined #crystal-lang
repo has joined #crystal-lang
csaba has left #crystal-lang ["WeeChat 2.3"]
zorp_ has quit [Ping timeout: 265 seconds]
<FromGitter> <roduquen> Hi all, I always have a problem with the websocket, it spams this error : ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f561353ddc2d041c0f3aca0]
<FromGitter> <roduquen> Sometime I can connect/disconnect quickly, and sometimes I go to that point
postmodern has quit [Quit: Leaving]
<FromGitter> <j8r> that's hard to say without looking at the code
<FromGitter> <j8r> You can try converting some immutable classes to struct
<FromGitter> <j8r> especially if they are created a lot
<FromGitter> <roduquen> I try
<FromGitter> <roduquen> WebSockets are stored into a class, and that class is stored into an array
<FromGitter> <j8r> hum, why?
<FromGitter> <roduquen> Because I need some more information with the websocket ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f5617fd48237809376cf204]
<FromGitter> <roduquen> This is the entire file to understand maybe it is better
<raz> roduquen: wild guess, can you still reproduce it if you change `struct` to `class`?
<FromGitter> <roduquen> (it is now a struct but previously it was a class with a finalize that did this : ⏎ ⏎ ```@socket.close if @closed == false``` [https://gitter.im/crystal-lang/crystal?at=5f5619eadfaaed4ef537bb4e]
<raz> ah ok
<FromGitter> <roduquen> I just changed class to struct ^^
<raz> another wild guess: your exception handlers are rather broad. perhaps try catching only specific exceptions that you're interested in and see if that leads somewhere.
<raz> but no idea why that would cause GC to go in a cycle (if that's what the msg means)
<FromGitter> <roduquen> I can't reproduce the GC Warning with a struct
<raz> ohhh
<FromGitter> <roduquen> So it seems that it is solved but I am not sure
<raz> sorry i should read better. you said you also removed the finalize. i think it's more likely that removal that fixed it
<FromGitter> <j8r> @roduquen It will be better to push an event instead of pulling to know if the WS is alive
<FromGitter> <roduquen> Oh yes maybe, but it didn't compile a finalize into the struct
<FromGitter> <j8r> a WS can be not alive, even open?
<raz> yup, finalizers are always weird (in every language). i dunno why this particular one shouldn't work in crystal, but would suggest to avoid them in general
<FromGitter> <roduquen> @j8r I don't understand
<FromGitter> <j8r> why there is a `is_alive` logic, wouldn't something called in `on_close` do the trick?
<FromGitter> <roduquen> I am not sure, it was a protection because I didn't know if it was handled in the websocket from crystal
<FromGitter> <j8r> If the client closes the connection, `on_close` will be called.
<FromGitter> <j8r> In your case, you handle the fact that it can be opened bu not responding to pings... not sure it can happen, maybe
<FromGitter> <j8r> also, you can use `__FILE__` for the mesages
<FromGitter> <roduquen> Oh
<FromGitter> <roduquen> Thank you for that information, it was weird line all over the code
<FromGitter> <j8r> On my side, I have a Hash(or Array) to list all opened WebSockets
<FromGitter> <j8r> and in `on_close`, I delete the entry
<FromGitter> <roduquen> Ok it is the same for me with the "@channel.unsubscribe"
<FromGitter> <roduquen> They are all stored into an array in "@channel"
<FromGitter> <j8r> the fact that 3 fibers exist for each WS connection cannot help
<FromGitter> <j8r> if you have few, that's ok
<FromGitter> <roduquen> I just spawn now the "is_connected", it is just a protection from my code, like if the guy who connects didn't send the good message before 10 first seconds, I disconnect him
alexherbo2 has quit [Ping timeout: 256 seconds]
alexherbo2 has joined #crystal-lang
<FromGitter> <j8r> yep sure, but the is_alive is a loop
<FromGitter> <j8r> that will break, ok
<FromGitter> <j8r> ok fine
<FromGitter> <roduquen> I deleted that function
<FromGitter> <roduquen> I think too that it was overprotected
repo has quit [Quit: WeeChat 2.9]
repo has joined #crystal-lang
deavmi has quit [Quit: Eish! Load shedding.]
<raz> i wonder if there's a general purpose websocket server shard already (or if that should even be in stdlib). everyone reinvents these same patterns over and over (and it's easy to get them subtly wrong)
deavmi has joined #crystal-lang
deavmi has quit [Client Quit]
zorp_ has joined #crystal-lang
deavmi has joined #crystal-lang
<FromGitter> <j8r> raz: I though of making one handling the sessions
<raz> yup, i also thought of shardifying the ws server i once made but then was too lazy (would have needed to generalize/abstract it a little more)
<FromGitter> <Daniel-Worrall> for the crystal doc generator, can I set a local path to be the View Source link instead of github?
deavmi has quit [Ping timeout: 260 seconds]
deavmi has joined #crystal-lang
deavmi has quit [Quit: No Ping reply in 180 seconds.]
<oprypin> Daniel-Worrall, yea, with `sed` 😂
deavmi has joined #crystal-lang
deavmi has quit [Quit: No Ping reply in 180 seconds.]
deavmi has joined #crystal-lang
deavmi has quit [Ping timeout: 265 seconds]
deavmi has joined #crystal-lang
<FromGitter> <andrewc910> Are fibers GC'd when they complete execution or do I have to manually kill them? If i have to manually kill them, how do i do that? Couldn't find any method in the API docs.
<yxhuvud> they should be GC'd. Not certain how the fiber stacks are handled. But I don't think you will have to handle them yourself.
<FromGitter> <andrewc910> That's what i figured since there was no kill-like method. Thanks!
<FromGitter> <mwlang> Almost got it with serializing/deserializing a collection of indicators: https://carc.in/#/r/9nkr The only thing left now is to somehow set the @collection property of each indicator to the owning collection. Is there an elegant way of overriding `#from_json` on this line `collection = Indicators::Collection.from_json(json_data)` to do that or is it necessarily a two step process?
<FromGitter> <Blacksmoke16> there is an `after_initialize` method that runs after deserialization
<FromGitter> <Blacksmoke16> dunno if that would help in this case tho
<FromGitter> <mwlang> sounds like it might! checking it out.
<FromGitter> <mwlang> hmmm...adding an `after_initialize` to the Collection class doesn't seem to get called?
<FromGitter> <Blacksmoke16> mm
<FromGitter> <mwlang> nevermind...gotta spell it correctly. key point there. :-D
<FromGitter> <Blacksmoke16> 👍 that would do it
<FromGitter> <mwlang> finally. I have a working solution that ain't too shabby.
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Blacksmoke16> nice one!
<FromGitter> <mwlang> dependency injection and JSON serialization is a pain to solve.
<FromGitter> <Blacksmoke16> DI related to a diff problem, or within this example?
<FromGitter> <HCLarsen> Hey folks, my newest Crystal blog post:
Human_G33k has quit [Ping timeout: 258 seconds]
<FromGitter> <mtsmmp_gitlab> hey bros
<FromGitter> <mtsmmp_gitlab> guys any way to bypass this error
<FromGitter> <mtsmmp_gitlab> ```Unable to remove directory: 'dir': Directory not empty```
<FromGitter> <Blacksmoke16> use the `Dir.rm_rf` method instead from `file_utils`
<FromGitter> <mtsmmp_gitlab> can i force it to delete all the child files?
<FromGitter> <Blacksmoke16> er its `FileUtils.rm_rf`
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/FileUtils.html#rm_rf(path:String):Nil-instance-method
<FromGitter> <mtsmmp_gitlab> grat
<FromGitter> <mtsmmp_gitlab> great
<FromGitter> <mtsmmp_gitlab> crystal rules
<FromGitter> <mtsmmp_gitlab> it works flawlessly
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <mtsmmp_gitlab> @Blacksmoke16 thanks again :D
<FromGitter> <mtsmmp_gitlab> you are the man
<FromGitter> <mtsmmp_gitlab> anything similar to nodejs child_proccess?
<FromGitter> <mtsmmp_gitlab> like i just want to execute ./gitpush.sh for example
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Process.html#run(command:String,args=nil,env:Env=nil,clear_env:Bool=false,shell:Bool=false,input:Stdio=Redirect::Close,output:Stdio=Redirect::Close,error:Stdio=Redirect::Close,chdir:String?=nil):Process::Status-class-method
<FromGitter> <mtsmmp_gitlab> thank you
<FromGitter> <mtsmmp_gitlab> no more questions today :D
Human_G33k has joined #crystal-lang
<FromGitter> <j8r> @HCLarsen neat, I thought cross compilation was more complicated!
<FromGitter> <galvertez> if i do something like `4 + sizeof(Int32)`, would it compile as `4 + 4` like a constant, or would the program actually have to calculate the size at runtime every time `4 + sizeof(Int32)` gets called?
zorp_ has quit [Remote host closed the connection]
zorp_ has joined #crystal-lang
<FromGitter> <galvertez> kind of an esoteric question, but for what i'm doing, i want a number constant, but i want that constant to be expressive and not just an actual number
<FromGitter> <Blacksmoke16> could assign it to a const first?
<FromGitter> <galvertez> i might as well
<FromGitter> <galvertez> was just wondering
<FromGitter> <galvertez> i'm messing around w/ some binary stuff so writing the code as `io.pos = io.pos + sizeof(Int32) + update_size` would be more expressive than `io.pos = io.pos + 4 + update_size`
<FromGitter> <galvertez> but as well just make a constant though why not
<FromGitter> <Blacksmoke16> i mean like `INT_SIZE = sizeof(Int32)`
<FromGitter> <galvertez> ya
zorp_ has quit [Read error: Connection reset by peer]
<FromGitter> <galvertez> and then just use that later
<FromGitter> <galvertez> i am still curious whether it compiles as a constant or calculates though
<FromGitter> <Blacksmoke16> sec
<FromGitter> <galvertez> like it probably doesn't matter - performancewise it's probably like a sub-nanosecond calculation, if it even is calculating, but now that i'm thinking about it i just wanna know ya know? lol
<FromGitter> <Blacksmoke16> could try emitting the ir code and see whats there
<FromGitter> <perfecto25> hello, question re iterating over YAML list, ⏎ ⏎ i have a Yaml file like this ⏎ ⏎ ```names: ⏎ - bob ⏎ - mary ⏎ - joe``` [https://gitter.im/crystal-lang/crystal?at=5f56a0ec9566774dfe5e14a9]
<FromGitter> <perfecto25> How can I iterate each loop over those names?
<FromGitter> <Blacksmoke16> `Array(String).from_yaml(string_or_io, root: "names").each { |n| puts n }`
<FromGitter> <perfecto25> thx let me try that
<FromGitter> <perfecto25> is there way to iterate of a hash? ⏎ ⏎ ie ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f56a1d25580fa092b4f88f4]
<FromGitter> <perfecto25> need to iterate each name and pull out age
<FromGitter> <Blacksmoke16> are these just for some one off thing? or like a config file or something?
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/YAML/Serializable.html id look into this if you need something more reuseable
<FromGitter> <perfecto25> config file, writing a UDPlistener that parses yaml config for mkt data,
<FromGitter> <perfecto25> looks like this ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f56a23636e6f709fd2e09b2]
<FromGitter> <perfecto25> will play around with "from_yaml" looks like this is what i need
<FromGitter> <Blacksmoke16> yes, would be able to define objects to represent your data
alexherbo22 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo22 is now known as alexherbo2
<FromGitter> <HCLarsen> @j8r I did too. Hopefully my article will show people how simple it can be.
kerframil has quit [Ping timeout: 256 seconds]
alexherbo2 has quit [Ping timeout: 258 seconds]