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
postmodern has joined #crystal-lang
<FromGitter> <mixflame> whats the proper way to load stuff from inside a shard in an ubuntu snap?
<FromGitter> <mixflame> like files
<FromGitter> <mixflame> I made some changes to obscenity-cr. I made it load the blacklist from inside of Crystal instead of using files in the project dir. This allows me to use it from inside a snap. I bypassed the configuration ability to set which blacklist file you're using.
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
<FromGitter> <mixflame> how do I match multiple in Crystal regex?
<FromGitter> <mixflame> I'm working on another shard that filters links
<FromGitter> <mixflame> I made another one https://github.com/mixflame/Linksafe.cr
<FromGitter> <mixflame> I will try using it tomorrow but it works with the tests passing, blocks all but the whitelisted domains
<FromGitter> <mwlang> hmmm...stumbling on another "lost in translation" Ruby => Crystal interpretation ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f3df7d2a8c17801765e354e]
<FromGitter> <Blacksmoke16> `(a,b)`
<FromGitter> <mwlang> parens instead of pipe?
<FromGitter> <mixflame> isn't it `|(a,b)|
<FromGitter> <Blacksmoke16> was being lazy, yes that ^
<FromGitter> <mixflame> you pass the args as a tuple?
<FromGitter> <mixflame> yeah
<FromGitter> <mwlang> thanks, that was the ticket. [1,2,3,4,5].each_cons(2) {|(a,b)| pp! [a, b]}
<FromGitter> <mwlang> could not figure that out from reading the docs.
<postmodern> possibly dumb question, but if you cast an slice of uint8 pixel data into a slice of structs containing the uint8s, does the data get copied when you access the struct elements?
<FromGitter> <mwlang> here's another simple one, memoizing a return result: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f3dfa5c8b8d4f633e02657e]
<FromGitter> <mwlang> This seems a little roundabout, but it worked: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f3dfbae8b8d4f633e0268c5]
<postmodern> hmm doesn't appear that anyones written image processing library for crystal. libvips and imageflow look like solid alternatives to ImageMagic
<FromGitter> <mixflame> what's a Cline?
<FromGitter> <mwlang> open, high, low, close candle on stock charts -- Binance calls 'em Clines so that's what I ended up calling 'em, too.
<FromGitter> <mixflame> ah nice
<FromGitter> <mixflame> Nice. I made two filtering libraries today, one for bad words and one for URLs
<FromGitter> <mixflame> (for Crystal)
kevinsjoberg has quit [Read error: Connection reset by peer]
postmodern has quit [Quit: Leaving]
<FromGitter> <j8r> Where does the list come from?
<FromGitter> <j8r> there is `%w(one two three)` which translates to `["one", "two", "three"]`
melthelesbian has quit [Ping timeout: 272 seconds]
sorcus has joined #crystal-lang
melthelesbian has joined #crystal-lang
kevinsjoberg has joined #crystal-lang
melthelesbian has joined #crystal-lang
kevinsjoberg has joined #crystal-lang
melthelesbian has quit [Changing host]
kevinsjoberg has quit [Changing host]
zorp_ has joined #crystal-lang
<FromGitter> <naqvis> @j8r this is built-in syntax, go through lexer ⏎ https://github.com/crystal-lang/crystal/blob/master/src/compiler/crystal/syntax/lexer.cr#L404-L419
<FromGitter> <naqvis> don't know if it answers your question :P
<FromGitter> <j8r> @naqvis ha sorry, it was 2 separate sentences
<FromGitter> <j8r> I didn't mention @mixflame , I was responding to him, because he do `"one two three".split("\n")`
<FromGitter> <j8r> btw I didn't know the compiler intrinsics about this, thanks :)
<FromGitter> <grkek> Do any of you have a great library which is able to record videos by frames in crystal?
<FromGitter> <grkek> for mac os?
<FromGitter> <naqvis> @j8r aah :P
<FromGitter> <naqvis> @grkek I remember postmodern was working on Video4Linux (https://github.com/postmodern/v4l2.cr) not sure if that is going to help you in this regard
sorcus has quit [Quit: WeeChat 2.9]
sorcus has joined #crystal-lang
sorcus has quit [Quit: WeeChat 2.9]
sorcus has joined #crystal-lang
<FromGitter> <grkek> I wanted for mac os since v4l2 is working
<FromGitter> <grkek> I am making a mjpeg server :p
<FromGitter> <naqvis> 👍
_whitelogger has joined #crystal-lang
coderobe has quit [Quit: Ping timeout (120 seconds)]
coderobe has joined #crystal-lang
coderobe has quit [Quit: Ping timeout (120 seconds)]
coderobe has joined #crystal-lang
<FromGitter> <mtsmmp_gitlab> guys im a noob. i have a json file with a key "categories" (array). i can read the file no problem, but how do i push a new item to this key and save the file?
<FromGitter> <mtsmmp_gitlab> it says i cant push because the type is JSON::Any
<FromGitter> <mtsmmp_gitlab> i can read the categories using .as_a
<FromGitter> <mtsmmp_gitlab> i wanted to .push
<FromGitter> <Blacksmoke16> would be better off using https://crystal-lang.org/api/master/JSON/Serializable.html and not working with `JSON::Any`
postmodern has joined #crystal-lang
<FromGitter> <dscottboggs_gitlab> or even just like `Hash(String, Array(String)).from_json["categories"]`
<FromGitter> <Blacksmoke16> if its simple yea, that would suffice as well
woodruffw has quit [Ping timeout: 260 seconds]
<FromGitter> <mtsmmp_gitlab> im not getting it with serializable
<FromGitter> <Blacksmoke16> you could do something like what @dscottboggs_gitlab `Array(String).from_json File.read "my_file.json", "categories"` should work
<FromGitter> <dscottboggs_gitlab> what? what's that do?
<FromGitter> <Blacksmoke16> reads the file and the does the deserialization from the provided key
<FromGitter> <Blacksmoke16> so you end up with just the array of data versus a hash of the key and array
<FromGitter> <Blacksmoke16> assuming he just wants the data and doesnt care about the file structure itself
<FromGitter> <dscottboggs_gitlab> oh ok I see now, the parentheses were not right in the original message, I thought you were passing "categories" to File.read
<FromGitter> <Blacksmoke16> yea sorry, i edited it to add them
<FromGitter> <dscottboggs_gitlab> nbd
<FromGitter> <dscottboggs_gitlab> @mtsmmp_gitlab we're saying that you need to tell Crystal what type of data you're expecting to see from the file. If it looks like ⏎ ⏎ ```{"categories": ["one", "two", "three"]}``` [https://gitter.im/crystal-lang/crystal?at=5f3e904f07c30d132a9d598f]
<FromGitter> <dscottboggs_gitlab> then the way to deserialize it is like @Blacksmoke16 or I said
<FromGitter> <dscottboggs_gitlab> if it looks like ⏎ ⏎ ```{"categories": [ ⏎ "one", ⏎ {"category": "two", "details": 1234},``` [https://gitter.im/crystal-lang/crystal?at=5f3e9084750a27413030cf09]
<FromGitter> <dscottboggs_gitlab> 😛
<FromGitter> <mtsmmp_gitlab> thanks guys
<FromGitter> <mtsmmp_gitlab> im almost there
<FromGitter> <mtsmmp_gitlab> so i have this code
<FromGitter> <mtsmmp_gitlab> json = File.read("data.json") ⏎ categories = Array(String).from_json(json, "categories") ⏎ categories.push("new_category")
<FromGitter> <Blacksmoke16> looks fine yea
<FromGitter> <mtsmmp_gitlab> it works
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <mtsmmp_gitlab> but how to save the updated categories on data.json now?
<FromGitter> <mtsmmp_gitlab> sorry im pretty noob
<FromGitter> <Blacksmoke16> `File.write "data.json", {categories: categories}.to_json`
<FromGitter> <Blacksmoke16> BUT
<FromGitter> <Blacksmoke16> i would argue this is getting to be a better use case for the serializable stuff, as you could have a `def self.load` and `def save` methods
<FromGitter> <Blacksmoke16> i can make an example if you'd like...
<FromGitter> <mtsmmp_gitlab> sure
<FromGitter> <mtsmmp_gitlab> bring it on
<FromGitter> <mtsmmp_gitlab> i appreciate
<FromGitter> <mtsmmp_gitlab> > `File.write "data.json", {categories: categories}.to_json` ⏎ ⏎ it worked
<FromGitter> <mtsmmp_gitlab> > i can make an example if you'd like... ⏎ ⏎ u doing it?
<FromGitter> <Blacksmoke16> yes, give me a few
<FromGitter> <mtsmmp_gitlab> whenever you want
<FromGitter> <dscottboggs_gitlab> while he's doing that, I'd like to note that you should prefer using IO to using intermediate strings. For example, instead of ⏎ ⏎ ```File.open("data.json", mode: "w") { |file| {categories: data}.to_json file }``` [https://gitter.im/crystal-lang/crystal?at=5f3e95d307c30d132a9d74f6]
<repo> what's the debugging macro again?
<FromGitter> <Blacksmoke16> `{{debug}}`
<repo> no the pretty printing one
<repo> not pp
<repo> the one that shows assignments and such
<repo> i thought it was p
<repo> but it doesn't seem to be
<FromGitter> <Blacksmoke16> @mtsmmp_gitlab
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f3e97da78f4a8018017d036]
<FromGitter> <Blacksmoke16> something like that
<FromGitter> <Blacksmoke16> `p!`?
<FromGitter> <mtsmmp_gitlab> @dscottboggs_gitlab oh... i thought file.read was just a quick way to read the file. didnt know there was a difference
<FromGitter> <Blacksmoke16> the difference in this case is negligible, but using IO based approaches are usually better
<FromGitter> <mtsmmp_gitlab> the code looks harder to understand though
<FromGitter> <mtsmmp_gitlab> but ill update it
<FromGitter> <Blacksmoke16> in regards to my example?
<FromGitter> <mtsmmp_gitlab> > in regards to my example? ⏎ ⏎ i think the code looks cool, ill test
<FromGitter> <Blacksmoke16> re: the IO stuff
<FromGitter> <Blacksmoke16> the difference is that using `File.read` would load the content of the file into memory
<FromGitter> <Blacksmoke16> so you would have be using the memory it takes to represent the contents in addition to the memory used by the objects you're creating
woodruffw has joined #crystal-lang
<FromGitter> <Blacksmoke16> the IO approach makes it so you dont load the whole file into memory at once, so can be much more efficient when processing large files
<FromGitter> <mtsmmp_gitlab> great guys
<FromGitter> <mtsmmp_gitlab> the example worked
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <mtsmmp_gitlab> you know im going to use your interface as a base
<FromGitter> <mtsmmp_gitlab> to get the other data
<FromGitter> <Blacksmoke16> idk what the end goal is, so its totally possible its overkill
<FromGitter> <mtsmmp_gitlab> besided categories there will be other stuff
<FromGitter> <Blacksmoke16> another option instead of `add_category` could prob get away with doing like
<FromGitter> <Blacksmoke16> ```getter categories : Array(String) ⏎ ⏎ ... ⏎ ⏎ data.categories << "baz"``` [https://gitter.im/crystal-lang/crystal?at=5f3e9a2133878e7e60303768]
<FromGitter> <Blacksmoke16> maybe someone else has opinions on which is more optimal :P
<FromGitter> <Blacksmoke16> well this approach exposes the array, if thats not okay you would need to use the first example using `add_category`
<repo> Blacksmoke16: yeah!
<FromGitter> <mtsmmp_gitlab> i like this better
<repo> Blacksmoke16: quick question about athena-serializer: granite defines all fields as nilable. How can i force deserialization to fail on missing keys?
<FromGitter> <mtsmmp_gitlab> @Blacksmoke16 so this code only works if i declare the json keys that i want up front?
<repo> using @[ASRA::Accessor(setter: foo=)] ?
<FromGitter> <Blacksmoke16> yes
<FromGitter> <Blacksmoke16> repo: hmm
<FromGitter> <Blacksmoke16> way i handled this in the blog tutorial is using the assertion lib in addition to serializer
<repo> mh
<repo> Blacksmoke16: i suppose there's no general setter policy or something?
<FromGitter> <Blacksmoke16> ``` @[ASRA::Expose] ⏎ @[Assert::NotBlank] ⏎ column first_name : String``` [https://gitter.im/crystal-lang/crystal?at=5f3e9b5c750a27413030f9ab]
<FromGitter> <Blacksmoke16> like that
<repo> oh
<repo> where does @[Assert::NotBlank] come from?
<FromGitter> <Blacksmoke16> https://github.com/Blacksmoke16/assert (which is currently being refactored/moved into the athena org)
<FromGitter> <Blacksmoke16> is how i used it
<FromGitter> <mtsmmp_gitlab> @Blacksmoke16 so if i wanted something more generic. for example data.prices << "new_price", but prices isnt explicited on Data
<FromGitter> <mtsmmp_gitlab> with JSON::Serializable there is now way right
<FromGitter> <Blacksmoke16> whats the use case? You could do that be keeping a hash as the internal store, like `Hash(String, Array(String))`, however at that point you're not getting much type saftey
<FromGitter> <mtsmmp_gitlab> ok
<repo> Blacksmoke16: oh wow, assert seems awesome!
<repo> Blacksmoke16: i'm starting to become a fan of you :D
<FromGitter> <Blacksmoke16> 😎 good to hear :)
<FromGitter> <Blacksmoke16> assert has some limitations, its currently being refactored/moved to https://github.com/athena-framework/validator/tree/develop-v2
<FromGitter> <Blacksmoke16> but i got pulled into a minecraft server so that has been put on hold 😬
<repo> Blacksmoke16: haha
<FromGitter> <Blacksmoke16> it'll be the same API, but be a bit more robust
<repo> Blacksmoke16: but for now i should be using asset and not athena validator?
<repo> *assert
<FromGitter> <Blacksmoke16> correct
<repo> cool
<FromGitter> <Blacksmoke16> well you *could* use that `develop-v2` branch, if you want to be on the bleeding edge :p
<repo> naaah :D
<FromGitter> <Blacksmoke16> i figured :p
<repo> i had to code some go for a work project and boy does it put things in perspective. crystal is such a joy to write in comparison
<repo> Blacksmoke16: does athena-serializer have support for strict serialization?
<repo> *deserialization
<repo> as in raising on unknown keys
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <Blacksmoke16> not atm idt
<FromGitter> <mtsmmp_gitlab> @Blacksmoke16 hey, back to that example
<FromGitter> <mtsmmp_gitlab> i added another key that is an array of objetcs
<FromGitter> <mtsmmp_gitlab> how do i represent it? Array(Object doesnt work)
<FromGitter> <Blacksmoke16> need to define another class/struct to represent it
<FromGitter> <Blacksmoke16> see the example in https://crystal-lang.org/api/master/JSON/Serializable.html
<repo> Blacksmoke16: hm ok
<FromGitter> <mtsmmp_gitlab> yeah i saw that
<FromGitter> <mtsmmp_gitlab> just didnt think it was mandatory
<FromGitter> <Blacksmoke16> i.e. how a `House` has a `Location`
<repo> Blacksmoke16: hm `ASR.serializer.deserialize(Models::Room, body, :json)` seems to be returning a nilable type...
<repo> or even nil
<FromGitter> <mtsmmp_gitlab> my background is in nodejs and its so different
<FromGitter> <Blacksmoke16> does `Room` include the module?
<repo> Blacksmoke16: it includes ASR::Serializable
<repo> ah never mind
<FromGitter> <Blacksmoke16> im not a big fan of how some of that works, but i also havent thought of a better way to do it
<FromGitter> <Blacksmoke16> mainly say you include the module into a type, and that type has a property that isnt serializable. Currently it would just be ignored/return nil
<FromGitter> <Blacksmoke16> as opposed to compile time error when you cant really do anything about it
<repo> Blacksmoke16: hmm now i have a different issue
<repo> it seems like `@[ASRA::Name(strategy: :camelcase)]` isn't working
<FromGitter> <Blacksmoke16> moment
<repo> it deserializes the json correctly when a snake cased key is used
<repo> but not with the camelCased version
<FromGitter> <Blacksmoke16> thats only for serialization
<repo> oh
<repo> nothing for deserialization? :/
<FromGitter> <Blacksmoke16> would have to use that annotation on each property, or define the ivars via camelCase
<repo> meh
<repo> is there a specific reason for this?
<repo> maybe i'm missing something
<repo> but i'd think this would be pretty valuable in both directions
<FromGitter> <Blacksmoke16> yea probably, ill add a card for that
<FromGitter> <Blacksmoke16> should be fairly easy?
<FromGitter> <Blacksmoke16> workaround for now would be to apply the name annotation on each property using the `deserialize` key, is what the strategy would be doing essentially i think
<repo> yup
<repo> i see if i can add a PR
<FromGitter> <Blacksmoke16> okey dokey
<repo> tada
<repo> ups
<repo> Blacksmoke16:
<repo> sorry bougyman
<repo> tabfail
<bougyman> no worries !
<FromGitter> <Blacksmoke16> whats the reasoning for renaming `serialize` to `key`?
<repo> i didn't rename it, key is additional
<repo> it combines serialize and deserialize
<FromGitter> <Blacksmoke16> ah nice
<repo> same with `strategy`
<repo> it combines `serialization_strategy` and `deserialization_strategy`
<repo> i understand if you want to change this
<repo> because it's not _totally_ backwards compatible
<FromGitter> <Blacksmoke16> so `strategy` becomes an alias to setting both serialization/deserialization sides, but there is still a way to only define one direction correct?
<repo> yes
<FromGitter> <Blacksmoke16> no i think im cool with that
<repo> cool
<FromGitter> <Blacksmoke16> i can check that more later today
<repo> nice
<repo> i'll be afk for a while but feel free to highlight me if you have any questions
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <alexherbo2> @Blacksmoke16 it could be nice to make `oq` more installable with a Makefile
<FromGitter> <alexherbo2> and supporting stripping comments
<FromGitter> <alexherbo2> from json to yaml
<FromGitter> <Blacksmoke16> does it not do that already? What benefit would using a makefile be over `shards build --production --release`
<FromGitter> <Blacksmoke16> a bit shorter but :shrug:
sorcus has quit [Ping timeout: 260 seconds]
sorcus has joined #crystal-lang
<FromGitter> <Blacksmoke16> oh nvm, you mean like `make install`
<FromGitter> <Blacksmoke16> id accept a PR for that 😉
_whitelogger has joined #crystal-lang
<FromGitter> <dscottboggs_gitlab> if you require a shard which requires some part of the stdlib, that part of the stdlib is available implicitly without requiring it, right? For example, if I `require "foo"` and `foo` is a shard which `require "json"` would I also need to `require "json"` as well?
<FromGitter> <Blacksmoke16> idt tho
<oprypin> dscottboggs_gitlab, you wouldnt need to require that only on a technicality. include what you use.
<FromGitter> <dscottboggs_gitlab> this works, but you're probably right that it's better to not do things implicitly
<oprypin> "having required json" is not part of that shard's API contract, anyway
<FromGitter> <dscottboggs_gitlab> well, it is in this case, since it's a shard which interacts with a JSON API. Same with `http` since the shard queries an HTTP API. But yeah, that's not obvious to anyone who doesn't know what the shard does
<FromGitter> <dscottboggs_gitlab> like, the shard will never *not* include those things, even if it's implicit.
<FromGitter> <dscottboggs_gitlab> but implicit things are usually bad
<FromGitter> <dscottboggs_gitlab> also it didn't actually work when I went to do `shards build`, just in the playground
zorp_ has quit [Ping timeout: 260 seconds]