RX14 changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.27.0 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
rohitpaulk has quit [Ping timeout: 268 seconds]
rohitpaulk has joined #crystal-lang
sagax has quit [Quit: Konversation terminated!]
rohitpaulk has quit [Ping timeout: 244 seconds]
<FromGitter> <Blacksmoke16> i do something similar for a project of mine
<FromGitter> <Blacksmoke16> have travis run it once a day comparing a stored etag vs etag of resource
<FromGitter> <Blacksmoke16> works quite wlel
<FromGitter> <m-o-e> nice! thx, gonna check that out
<FromGitter> <Blacksmoke16> np
<FromGitter> <Blacksmoke16> looks like raw version of that file has an etag so totally could use that
<FromGitter> <Blacksmoke16> are some cases where the etag changes but the diff is the same, if github goes down for a bit etc, but can just see if anything changed before commiting
<FromGitter> <Blacksmoke16> CI ftw ;)
<FromGitter> <Blacksmoke16> the key is to have it run at a time where the file is most likely to be already up to date, i.e. late at night or early morn depending on their main tz...
<FromGitter> <m-o-e> yea the file is tiny anyway. i'll likely just fetch the whole thing once a month and not even care if it changed
<FromGitter> <Blacksmoke16> 👌
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 245 seconds]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 252 seconds]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 240 seconds]
non-aristotelian has quit [Quit: non-aristotelian]
akaiiro has quit [Ping timeout: 246 seconds]
<FromGitter> <dscottboggs_gitlab> is there a technical reason why the keywords `and`, `not`, and `or` were removed from the langauge, or was it just a design decision?
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 268 seconds]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 244 seconds]
<FromGitter> <Blacksmoke16> prob the latter
<FromGitter> <dscottboggs_gitlab> that's super disappointing
<FromGitter> <Blacksmoke16> not really a big deal imo
<FromGitter> <Blacksmoke16> the symbols are the same for every lang pretty much so meh
<FromGitter> <dscottboggs_gitlab> idk it irks me when I have to write `delete_webhook || raise "err"` instead of `delete_webhook or raise "err"` ⏎ ⏎ for a language based on syntax that strips as much special symbols as possible, requiring them for those really readable cases seems weird.
<FromGitter> <dscottboggs_gitlab> I guess it's familiar if you've ever done shell scripting
<FromGitter> <dscottboggs_gitlab> wait a second... so in ruby, `&&` and `and` don't do the same thing?? wtf...
<FromGitter> <Blacksmoke16> their level of precedence is diff
<FromGitter> <dscottboggs_gitlab> that makes a lot of sense now, but I'm not sure I'm a fan of the weird precedence thing in the operators. I expected them to evaluate left-to-right, not `&&` first, then `||`, that's just strange...
<FromGitter> <Blacksmoke16> https://stackoverflow.com/a/12983650
<FromGitter> <dscottboggs_gitlab> wow that's so confusing.
<FromGitter> <Blacksmoke16> indeed :p
<FromGitter> <Blacksmoke16> in python they are the same just diff syntax
<FromGitter> <dscottboggs_gitlab> as ruby?
<FromGitter> <dscottboggs_gitlab> yeah but in python you can't do `a = false or true` because it doesn't have assignment expressions, and when it gets them it'll require parentheses
<FromGitter> <dscottboggs_gitlab> yeah in python `a = False or True` sets `a == True` like you'd expect
<FromGitter> <Blacksmoke16> no, i meant that the syntax for `&&` in python is `and`
<FromGitter> <Blacksmoke16> doing the `&&` is a syntax error
<FromGitter> <dscottboggs_gitlab> oh I see. yes, why can't crystal have `and` that's just a mirror of the `&&` operator?
<FromGitter> <dscottboggs_gitlab> because it would confuse rubyists, of course
<FromGitter> <Blacksmoke16> because aliases arent well liked
<FromGitter> <Blacksmoke16> hence why its `#size`
<FromGitter> <dscottboggs_gitlab> that's pretty fair.
<FromGitter> <Blacksmoke16> and you dont have `#length`, `#size`, `#count`
rohitpaulk has joined #crystal-lang
<FromGitter> <Blacksmoke16> `It's hidden behaviour and thus makes the code less obvious as it requires inherent knowledge.` as @jhass
<FromGitter> <dscottboggs_gitlab> but it's not if it's not weird behavior like in ruby, it's just an alias. Like I would literally have it just swap them out at compile time. He was talking about the weird ruby behavior, which, I 100% agree on
<FromGitter> <Blacksmoke16> main point still sticks, less aliases means more clear code, and forces a general syntax style you could say
<FromGitter> <Blacksmoke16> otherwise you could argue there should be other aliases for other things and before you know it everything isnt as clear as it could
<FromGitter> <dscottboggs_gitlab> a valid point, and I respect the decision despite my disagreement :p
rohitpaulk has quit [Ping timeout: 245 seconds]
<FromGitter> <Blacksmoke16> one thing that comes to mind for me is `reduce` vs `inject`
<FromGitter> <Blacksmoke16> in ruby they the same thing just diff names, which i always thought they had diff functionality
<FromGitter> <dscottboggs_gitlab> yeah that doesn't make sense either
<FromGitter> <m-o-e> things should have a single name
<FromGitter> <m-o-e> aliases only cause confusion for absolutely no gain
<FromGitter> <m-o-e> in a similar vein i'm still a bit sad every time i run into a thing that crystal renamed from ruby, for no reason... eg. include? vs includes?
<FromGitter> <Blacksmoke16> `includes` is a bit more readable
<FromGitter> <m-o-e> sorry but bs.
<FromGitter> <Blacksmoke16> [1,2].includes? 1
<FromGitter> <dscottboggs_gitlab> on one hand, you're right, @m-o-e, on the other, it's ruby's fault for choosing `#include?` which doen't fit
<FromGitter> <Blacksmoke16> vs `[1,2].include? 1`
<FromGitter> <m-o-e> it's crystal that copied ruby, not the other way round. which was imho an extremely smart move. which makes such random renames even more baffling
<FromGitter> <Blacksmoke16> first can read like a sentence, `arr includes val`
<FromGitter> <dscottboggs_gitlab> what am I doing wrong? https://carc.in/#/r/5j6w
<FromGitter> <Blacksmoke16> imo `include?` sounds like it will try to add val
<FromGitter> <dscottboggs_gitlab> yeah but crystal explicitly decided not to be backwards compatible so they could make design decisions like that.
<FromGitter> <Blacksmoke16> to the arr
<FromGitter> <m-o-e> the point is: why throw sticks in the legs of ruby expats for *absolutely no reason*
<FromGitter> <Blacksmoke16> https://carc.in/#/r/5j6x
<FromGitter> <m-o-e> everyone who goes back and forth between ruby and crystal will tumble over this all the time
<FromGitter> <dscottboggs_gitlab> but the API I'm using gives me a JSON::Any. Do I have to convert that back to a string then do from_json with that???
<FromGitter> <Blacksmoke16> just pass `from_json` the json string?
<FromGitter> <dscottboggs_gitlab> no I'm using a library that gives me JSON::Any not a string
<FromGitter> <Blacksmoke16> sec
<FromGitter> <Blacksmoke16> https://carc.in/#/r/5j78
<FromGitter> <Blacksmoke16> other option would be to define a class method that accepts `JSON::Any` and consumes that to build out your obj
<FromGitter> <Blacksmoke16> ideally you want to get away from the `JSON::Any` asap
rohitpaulk has joined #crystal-lang
<FromGitter> <Blacksmoke16> kinda annoying it returns you `JSON::Any`
rohitpaulk has quit [Ping timeout: 252 seconds]
<FromGitter> <dscottboggs_gitlab> yeah I might just have to make the request manually, going from a string to `JSON::Any`, back to a string and then to a type is going to be really inefficient.
<FromGitter> <dscottboggs_gitlab> although it only happens once and that's a lot of work so maybe I'll just make a note to come back to it
<FromGitter> <Blacksmoke16> whats the api?
<FromGitter> <dscottboggs_gitlab> the shard for making telegram bots
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <dscottboggs_gitlab> well, the top one on crystalshards.xyz, there are like 5. There were a few other minor patches I was thinking of adding too, maybe I'll send a PR.
<FromGitter> <dscottboggs_gitlab> I was just trying to get a proof of concept set up though
<FromGitter> <Blacksmoke16> would think they would build out some obj from the response and return that :/
<FromGitter> <dscottboggs_gitlab> they woul've but they didn't have an object for the `WebhookInfo` object so I just made a struct and used the `request` method of the bot class (which one overloads to make the bot) which apparently returns JSON::Any...makes me worry how it's parsing the JSON for the actual objects, I haven't delved into it yet
<FromGitter> <JamesLe15782584_twitter> Can I avoid using the 2 vertical bars after "do" keyword?
<FromGitter> <Blacksmoke16> in what context?
<FromGitter> <JamesLe15782584_twitter> (2 - 1).each do i
<FromGitter> <dscottboggs_gitlab> no
<FromGitter> <Blacksmoke16> no, its part of the syntax
<FromGitter> <Blacksmoke16> however if its a short you could use the short syntax
<FromGitter> <Blacksmoke16> like `[1,2].each do { |v| puts v }`
<FromGitter> <JamesLe15782584_twitter> Like python, golang doesnt need, perhaps we could skip it?
<FromGitter> <Blacksmoke16> nope, is part of the lang :shrug:
<FromGitter> <dscottboggs_gitlab> what don't python and go need?
<FromGitter> <JamesLe15782584_twitter> Yeah, Crystal is interesting but it could be get sweeter without that
<FromGitter> <JamesLe15782584_twitter> Python and go use something like_, err
<FromGitter> <JamesLe15782584_twitter> with no parentheses
<FromGitter> <dscottboggs_gitlab> I guess in python you can do `lambda: action()` but you still need parens in `def`s and you hardly ever use lambdas. The only equivalent in go is a `func(){ action() }()` expression but you still need parens there
<FromGitter> <JamesLe15782584_twitter> I see, have not yet go deeper in python
<FromGitter> <JamesLe15782584_twitter> anyone reside in Asia regions?
<FromGitter> <Blacksmoke16> not me
<FromGitter> <dscottboggs_gitlab> I got the bot working! :D
<FromGitter> <Blacksmoke16> nice one
<FromGitter> <BrowncoatShadow> Ahoy, I have spent all day going through the docs and source trying to figure out why my JSON.mapping is not working. Is this a good place to get some support?
<FromGitter> <Blacksmoke16> got an example of it?
<FromGitter> <BrowncoatShadow> Sure.
<FromGitter> <Blacksmoke16> like a playground link
<FromGitter> <BrowncoatShadow> https://play.crystal-lang.org/#/r/5j7e
<FromGitter> <dscottboggs_gitlab> the type of name should be `String?` not `String` if it's nillable
<FromGitter> <BrowncoatShadow> It is not nillable.
<FromGitter> <dscottboggs_gitlab> oh I misread
<FromGitter> <Blacksmoke16> its because your mapping `name:` is looking for a key in the json string that doesnt exist
<FromGitter> <BrowncoatShadow> The problem seems to be that :root option is not working within the mapping.
<FromGitter> <BrowncoatShadow> But the docs clearly state that it should
<FromGitter> <BrowncoatShadow> I can even see in the source where it does a JSON::PullParser#on_key! https://github.com/crystal-lang/crystal/blob/c9d1eef8fde5c7a03a029d64c8483ed7b4f2fe86/src/json/mapping.cr#L124
<FromGitter> <Blacksmoke16> i dont think `.from_json(json, root: "data")` is the same thing that gets defined using the mapping
<FromGitter> <Blacksmoke16> iirc root didnt do what i thought it did
<FromGitter> <Blacksmoke16> sec
<FromGitter> <BrowncoatShadow> Hmm. Docs say "root: assume the value is inside a JSON object with a given key (see Object.from_json(string_or_io, root))".
<FromGitter> <Blacksmoke16> hm
<FromGitter> <BrowncoatShadow> It works when doing a direct `Object.from_json(string_or_io, root)`. If you remove the name mapping it works like a charm.
<FromGitter> <BrowncoatShadow> Or if I create another class for attributes as the target type. But I am trying to create a flat object.
<FromGitter> <anamba> @JamesLe15782584_twitter i am in korea
<FromGitter> <Blacksmoke16> maybe you found a bug :p
<FromGitter> <BrowncoatShadow> Well shucks.
<FromGitter> <Blacksmoke16> well the issue is with how root works i think
<FromGitter> <BrowncoatShadow> Right. It works for #from_json, but not within the mapping.
<FromGitter> <BrowncoatShadow> Unless I am completely missing something.
<FromGitter> <Blacksmoke16> it first looks for the key called `results` then `heroes`
<FromGitter> <Blacksmoke16> which in your case it is looking for the key called `name` which it cant find, maybe because it doesnt know to do another `from_json` on the array of objects?
<FromGitter> <BrowncoatShadow> Hmm. I wonder what happens if it is not in an array.
<FromGitter> <BrowncoatShadow> Nope. Same result.
<FromGitter> <Blacksmoke16> id make an issue for it, to me it look like a bug in that its trying to create the obj directly from the result, which in this case is another json obj
<FromGitter> <Blacksmoke16> wait, why doesnt this work now...
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/5j7z
<FromGitter> <Blacksmoke16> yea this isnt how root works
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/5j82
<FromGitter> <Blacksmoke16> its relative to the obj with the key of the property
<FromGitter> <BrowncoatShadow> Well, that is not confusing at all...
<FromGitter> <Blacksmoke16> like for example there could be other properties in the `attributes` obj, `root` is saying, `go fetch this specific one`
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/5j85
<FromGitter> <Blacksmoke16> yup
<FromGitter> <BrowncoatShadow> Yeah, that seems to do it! https://play.crystal-lang.org/#/r/5j84
<FromGitter> <Blacksmoke16> 👌
<FromGitter> <Blacksmoke16> nice
<FromGitter> <BrowncoatShadow> Thanks @Blacksmoke16. I literally spent half my day trying to debug that.
<FromGitter> <Blacksmoke16> np
<FromGitter> <Blacksmoke16> maybe check out https://github.com/Blacksmoke16/CrSerializer too ;)
<FromGitter> <Blacksmoke16> depending on what you're working on it might be handy
<FromGitter> <BrowncoatShadow> Nice! I will bookmark that for sure. For this particular project I am trying to avoid any 3rd-party deps. But will keep it in my back pocket.
<FromGitter> <Blacksmoke16> downside of `key` is that will also be the key if you do `.to_json`
<FromGitter> <Blacksmoke16> which in this case makes sense if you want to reproduce the input data...but not so much if you just wanted it to print like `{"id": "foo", "name": "Jim"}`
<FromGitter> <BrowncoatShadow> Good to know. Not perfect, but good enough for now.
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/5j87 thats pretty neat
<FromGitter> <Blacksmoke16> guess root also makes it define the sub obj on `to_json`
<FromGitter> <Blacksmoke16> 👌
<FromGitter> <BrowncoatShadow> Thanks again. Cheers!
<FromGitter> <Blacksmoke16> np
<FromGitter> <BrowncoatShadow> @Blacksmoke16 The plot thickens. https://play.crystal-lang.org/#/r/5j8a
<FromGitter> <Blacksmoke16> well shit
<FromGitter> <BrowncoatShadow> Apparently you can only grab from a key once.
<FromGitter> <Blacksmoke16> its prob because ofc the `to_json` so that you dont end up with 1 obj having the same 2 keys
<FromGitter> <Blacksmoke16> in this case tho you should prob do like
<FromGitter> <BrowncoatShadow> I mean, these macros and methods were not made to deal with a combination of a very verbose API and flattening the objects.
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/5j8f
<FromGitter> <BrowncoatShadow> Yeah...
<FromGitter> <dscottboggs_gitlab> what about https://play.crystal-lang.org/#/r/5j8i
<FromGitter> <Blacksmoke16> oh my
<FromGitter> <BrowncoatShadow> I supposed I can have it store the attributes privately and write my own getters.
<FromGitter> <dscottboggs_gitlab> but like, define the Attributes class like @Blacksmoke16 did
<FromGitter> <BrowncoatShadow> Exactly like that.
<FromGitter> <dscottboggs_gitlab> :D glad I could help
<FromGitter> <BrowncoatShadow> Easily managed with an macro to define those getters.
<FromGitter> <dscottboggs_gitlab> ooh, yeah, that's a real nice way of doing it
<FromGitter> <Blacksmoke16> private property of class `Attribute` with custom getters/setters would be a good solution
<FromGitter> <Blacksmoke16> maintains the type saftey
<FromGitter> <BrowncoatShadow> Is it better to `include JSON::Serializable` as you guys have or use `JSON.mapping`? pros/cons?
<FromGitter> <Blacksmoke16> serializeable is the preferred method, the mapping might get removed in the future
<FromGitter> <BrowncoatShadow> Oh really? good to know.
<FromGitter> <dscottboggs_gitlab> Mapping came first
<FromGitter> <dscottboggs_gitlab> I was a slow convert to serializable but when I ran into a few cases like yours I saw how much more flexible it could be
<FromGitter> <Blacksmoke16> my lib makes it even *more* flexible ;)
<FromGitter> <BrowncoatShadow> It does end up being cleaner looking.
<FromGitter> <dscottboggs_gitlab> yes, and you can add documentation to the properties that way
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <Blacksmoke16> also helps with `def initialize` too i think
rohitpaulk has joined #crystal-lang
woodruffw has quit [Ping timeout: 246 seconds]
ua has quit [Ping timeout: 268 seconds]
dostoyevsky has quit [Quit: leaving]
dostoyevsky has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 240 seconds]
<FromGitter> <codenoid> hi
<FromGitter> <codenoid> i have a string `-5.209102` , how i can convert that as int
woodruffw has joined #crystal-lang
<FromGitter> <codenoid> .to_f
<FromGitter> <dscottboggs_gitlab> so `fun`s can't end in `=`, are there other limitations? for example, do they not overload? How does crystal know which `fun` to match up with the appropriate C header?
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 268 seconds]
rohitpaulk has joined #crystal-lang
ua has joined #crystal-lang
ua has quit [Ping timeout: 245 seconds]
<FromGitter> <dscottboggs_gitlab> ah, no, `fun` overloads don't work...
rohitpaulk has quit [Ping timeout: 250 seconds]
<jokke> hm there's no #peek for channels right?
ashirase has quit [Ping timeout: 252 seconds]
ashirase has joined #crystal-lang
alxnlssn has joined #crystal-lang
<FromGitter> <yxhuvud> jokke: No, but I think you can select over multiple.
alxnlssn has quit [Quit: Connection closed for inactivity]
flxy has joined #crystal-lang
<FromGitter> <Blacksmoke16> @codenoid https://play.crystal-lang.org/#/r/5ja1
<FromGitter> <Blacksmoke16> ofc this doesnt take into consideration rounding, which you would want to do? This would just truncate the digits after the `.`
<FromGitter> <JamesLe15782584_twitter> @anamba Hello, I'm reside in Singapore!
t0nyandre has joined #crystal-lang
akaiiro has joined #crystal-lang
ua has joined #crystal-lang
<FromGitter> <fusillicode_twitter> `must be Array(Rest::ExceptionResult | Rest::Result), not Array(Rest::Result)`
<FromGitter> <fusillicode_twitter> mmm
<FromGitter> <Blacksmoke16> declare your array like `[] of Rest::Result | Rest::ExceptionResult`
<FromGitter> <fusillicode_twitter> well it is defined like that
<FromGitter> <fusillicode_twitter> well...with an alias...
<FromGitter> <Blacksmoke16> i mean when you have your result, sec
<FromGitter> <fusillicode_twitter> `alias ResultOrException = (Result | ExceptionResult)`
<FromGitter> <fusillicode_twitter> and initialized with `Array(Rest::ResultOrException).new`
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/5jax
<FromGitter> <Blacksmoke16> yea, what you have should work, you have the full example?
<FromGitter> <fusillicode_twitter> got it got it @Blacksmoke16 :D
<FromGitter> <Blacksmoke16> im betting that the array being passed to it of one type, thus doesnt meet the union type requirements
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <fusillicode_twitter> I mean with your clarifying example I got it working :D
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <fusillicode_twitter> I just needed an extra `of Rest::ResultOrException`
<FromGitter> <Blacksmoke16> yup
<FromGitter> <fusillicode_twitter> Thanks a lot! Saved my day once again! 🙇 🙇 🙇
<FromGitter> <swinSpo> hi, how do i test this?
<FromGitter> <swinSpo> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5beeef9d80e46b4266bfb76d]
<FromGitter> <Blacksmoke16> feed it keys and make sure you get the correct string from it?
<FromGitter> <swinSpo> My idea was to create a builder_spec.cr file
<FromGitter> <swinSpo> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5beeefb94720c11e0e77d81d]
<FromGitter> <fusillicode_twitter> Makes sense to me @swinSpo :)
<FromGitter> <Blacksmoke16> yea pretty much
<FromGitter> <Blacksmoke16> you also might be able to build a big hash with like key as input, value as output then just iterate over that hash
<FromGitter> <swinSpo> crystal spec gives me no output though
<FromGitter> <Blacksmoke16> make sure you do `b = Builder.new` imagine thats just a typo tho
<FromGitter> <Blacksmoke16> also prob better to use `eq` in this case
<FromGitter> <Blacksmoke16> as it stands now your `build` method could prob be static
<FromGitter> <fusillicode_twitter> @swinSpo does your file name ends with the `_spec.cr`
<FromGitter> <Blacksmoke16> does that matter?
<FromGitter> <swinSpo> @fusillicode_twitter yes
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5beef0a4ddad8777ef73f045]
<FromGitter> <Blacksmoke16> running that like `crystal test.cr` works fine ⏎ ⏎ ```. ⏎ ⏎ Finished in 88 microseconds ⏎ 1 examples, 0 failures, 0 errors, 0 pending``` [https://gitter.im/crystal-lang/crystal?at=5beef0b780652945c370e480]
<FromGitter> <fusillicode_twitter> well it shows 1 successful example :)
<FromGitter> <swinSpo> crystal spec does nothing, running crystal builder_spec.cr seems to work
<FromGitter> <swinSpo> maybe it is because of my folder structure?
<FromGitter> <swinSpo> I have all files in the same folder
<FromGitter> <swinSpo> Oh yes I think that is it
<FromGitter> <swinSpo> "# Run all specs in files matching spec/**/*_spec.cr"
<FromGitter> <renich> Good day, Crystalians!
<FromGitter> <renich> I need to read a file of columns separated by space. I wanted to use mapping. Any ideas?
<FromGitter> <swinSpo> but crystal spec . seems to do what I want it to do, nice
<FromGitter> <renich> I need to check, accross files, if there are any duplicate entries of column 1; if we start from 0 that is.
akaiiro has quit [Ping timeout: 264 seconds]
<FromGitter> <kinxer> Is the "main" Fiber of a Crystal program special? I'm writing to write to `STDOUT` in a spawned Fiber but it's not doing so while the main fiber is blocking.
<FromGitter> <swinSpo> how do generics work for just functions?
<FromGitter> <swinSpo> something like ⏎ ⏎ ```def notNil(val : T) ⏎ val.should be_truthy ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5beef8ac6183a977eec8c76d]
<FromGitter> <kinxer> https://carc.in/#/r/5jbc
<FromGitter> <kinxer> You use `forall T` at the end of the signature.
<FromGitter> <swinSpo> i havent seen that syntax before
<FromGitter> <kinxer> From Stdlib: https://crystal-lang.org/api/0.27.0/Enumerable.html#chunks%28%26block%3AT-%3EU%29forallU-instance-method
<FromGitter> <swinSpo> i dont understand that syntax
<FromGitter> <swinSpo> T -> U
<FromGitter> <kinxer> Also, there's a section on "Free Variables" here (https://crystal-lang.org/docs/syntax_and_semantics/type_restrictions.html).
<FromGitter> <kinxer> `T` is the generic type of the Enumerable (i.e. `String` for the array `["something", "also", "and", "this"]`), and the block passed in to the method returns an object of generic type `U`, which can be anything.
<FromGitter> <kinxer> As the section from the docs that I sent says, you can also use that to capture the type of the method argument, such as in ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ (from the docs) [https://gitter.im/crystal-lang/crystal?at=5beefaf3ddad8777ef7437f8]
<FromGitter> <renich> any idea of why this doesn't work? ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5beefbd0de42d46bba750b2b]
akaiiro has joined #crystal-lang
<FromGitter> <renich> I tried `File.open()` as well...
<FromGitter> <kinxer> What output do you get that's wrong?
<FromGitter> <renich> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5beefccc1ad4155d3ad508cc]
<FromGitter> <renich> I've been looking how to use `IO` to read a file, but haven't found any.
<FromGitter> <renich> Just `IO::Memory` examples.
<FromGitter> <kinxer> A File is an IO.
<FromGitter> <renich> So this is really weird then...
<FromGitter> <kinxer> Try ⏎ ⏎ ```file = File.read("file.log") ⏎ CSV.parse(file, separator: ' ')``` [https://gitter.im/crystal-lang/crystal?at=5beefd3eddad8777ef744a89]
<FromGitter> <kinxer> The error you're getting appears to be because `CSV.parse` takes a `Char` as a separator.
<FromGitter> <kinxer> Also, you said you're only looking at the second line, right?
<FromGitter> <renich> Hah! That works!
<FromGitter> <renich> OK, I thought single quotes weren't used in crystal. Now, I know they're used for chars... Thanks a lot.
<FromGitter> <renich> I'll look if there's a way to get it to ignore all white space.
<FromGitter> <kinxer> No problem. Are your CSV files very large? 'Cause the docs (https://crystal-lang.org/api/0.27.0/CSV.html) say that `CSV.parse` is pretty inefficient.
johndescs has quit [Ping timeout: 276 seconds]
johndescs has joined #crystal-lang
<FromGitter> <renich> @kinxer not really, but I have many files to compare. Thanks for the heads up.
<FromGitter> <kinxer> No worries. I'm glad it's working now.
<jokke> i just pushed the first commits of a native NATS client lib for crystal: https://github.com/jreinert/nats.cr Contributions and testers very welcome! There is a lot of low hanging fruit. Especially the input of people experienced in message queue client implementations in crystal would be much appreciated
<FromGitter> <kinxer> @jokke Could you update the readme to fill in your GitHub username, just so it's a simple copy-paste to follow the installation instructions?
<jokke> sure
<jokke> done
<FromGitter> <kinxer> Awesome. Thanks. :)
return0e has quit [Remote host closed the connection]
return0e has joined #crystal-lang
<FromGitter> <Blacksmoke16> @swinSpo did you get what i meant when i was talking about a hash for your tests?
<FromGitter> <renich> I want to remove all elements of that array that are empty (""). Any suggestions? https://play.crystal-lang.org/#/r/5jbr
<FromGitter> <r00ster91> `array.delete("")`
<FromGitter> <m-o-e> is there a way to detect if my code is running in the context of `crystal spec`?
<FromGitter> <renich> hehehe, OK. Is there a recursive version of htat @r00ster91 ?
<FromGitter> <m-o-e> (ah n/m, i'll just set me an env var in spec helper)
<FromGitter> <renich> OK, this works. Thanks a lot. ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5bef0e416183a977eec96770]
<FromGitter> <r00ster91> @renich ⏎ You don't need the `rindex`: ⏎ ⏎ ```csv.dup.each do |row| ⏎ row.delete("") ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5bef0ea5de42d46bba7593ab]
<FromGitter> <renich> @r00ster91 thanks, I appreciate the advice. Will remove it.
t0nyandre has quit [Quit: WeeChat 2.3]
non-aristotelian has joined #crystal-lang
ua has quit [Ping timeout: 252 seconds]
<FromGitter> <j8r> @Blacksmoke16 you'll get better perf by using `String.build` then append to an io instead of creating intermediary strings with `+=`
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <j8r> Your `Builder.build` example with `s = ""`
<FromGitter> <Blacksmoke16> @swinSpo ^ that was his
<FromGitter> <Blacksmoke16> was having trouble running his specs
<FromGitter> <Blacksmoke16> but yea, good call, he should take a look at that
<FromGitter> <j8r> Nvm then
ua has joined #crystal-lang
<FromGitter> <swinSpo> @Blacksmoke16 a hash for my tests? Huh
<FromGitter> <Blacksmoke16> instead of doing like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5bef15f11665691e0fb4b781]
<FromGitter> <Blacksmoke16> where you have a new it/describe block for each test case you could do something like
<FromGitter> <swinSpo> ah yes a test table
<FromGitter> <Blacksmoke16> yea
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5bef16a96183a977eec99b0e]
<FromGitter> <m-o-e> hmm, anyone know how to do spec testing of sidekiq? the docs say nothing about testing :(
<FromGitter> <Blacksmoke16> does it use redis?
<FromGitter> <Blacksmoke16> would have to enqueue a message and have it process it and assert that the required things happened?
<FromGitter> <Blacksmoke16> maybe check out if there are any docs for the ruby side of it? might give you some ideas
<FromGitter> <m-o-e> yes. well, on other platforms sidekiq jobs simply execute synchronously in test-mode
<FromGitter> <m-o-e> but the crystal version doesn't seem to have a switch for that
<FromGitter> <m-o-e> guess i'll indeed have to actually spawn a worker and run them through redis, hm
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <ljuti> @Blacksmoke16 Great job with the new release. Can replace my custom assertions and the basic assertion annotations are much cleaner 👍
<FromGitter> <Blacksmoke16> 💯 thanks :)
<FromGitter> <Blacksmoke16> also be sure to check out error message section, default error messages/tokens are now a thing 😉
<FromGitter> <Blacksmoke16> better default error messages*
<FromGitter> <Blacksmoke16> out of ideas on what else to do/add so any ideas feel free to hmu or make an issue
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 252 seconds]
<FromGitter> <m-o-e> interesting @bararchy
<FromGitter> <m-o-e> imagine how much better the world would be if everything starting with java* just disappeared
<FromGitter> <j8r> thanks for the link @bararchy
<FromGitter> <j8r> you mean everything in PHP @m-o-e ?
<FromGitter> <m-o-e> hehe
<FromGitter> <m-o-e> wow ruby dropped from #5 to #10 in the past 4 years
<FromGitter> <m-o-e> while python keeps growing. i really don't understand how people tolerate python
<FromGitter> <m-o-e> (former pythonista myself, but would never go back to that trainwreck of an ecosystem)
<FromGitter> <j8r> python itself looks good, but it is a pain for portability and safety
<FromGitter> <j8r> I've tried to statically compile the cpython, lots of modules are missing, including pip
<FromGitter> <m-o-e> the package management alone drives me up the wall everytime i'm forced to use it... the whole 2 vs 3 split brain *still* isn't resolved
<FromGitter> <j8r> thanks to `pipenv` , the state is a bit better
<FromGitter> <m-o-e> well yes, but how many years did it take them to copy that from ruby...
<FromGitter> <j8r> yeah. Even if in Crystal we have frequent breaking changes, this isn't really a pain. The compiler tell us what's wrong
<FromGitter> <m-o-e> yes, it puzzles me how many languages *still* haven't realized how critically important good pkg management is
<FromGitter> <m-o-e> crystal gladly gets this very right
<FromGitter> <j8r> I wish Crystal will still have frequent, easy to fix breaking changes, like now vs. One single big major release and then having a big pain to port
<FromGitter> <m-o-e> yes, python continues to demonstrate what a horrible mistake the v2 -> v3 disaster was
<FromGitter> <j8r> I think at the end the main point was cultural
<FromGitter> <j8r> In Go, Rust and Crystal, people often wants to stick with the latest, even nightly version. This helps to be confident about the compiler
<FromGitter> <j8r> In Python, we don't want to change because we haven't any warranty if it will works
<FromGitter> <j8r> I know compiling != working, but still.
<FromGitter> <renich> How do I declare an array of arrays?