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
<FromGitter> <j8r> anyway, after a benchmark, calling initialize instead of new is a bit slower
<FromGitter> <j8r> or same: https://carc.in/#/r/a3rx
<FromGitter> <Blacksmoke16> youd have to do `self.class.new`
<FromGitter> <j8r> anyway, that's more idiomatic to use `self.new`
<FromGitter> <j8r> looks like to be same
<hightower3> j8r yes, it is only expected to be the same. Both versions consist of 3 method calls + 1 allocation
<FromGitter> <j8r> still not sure, doing more tests
<FromGitter> <j8r> because we can have default ivars value
<FromGitter> <j8r> ha, ok, we have to beware of declaring ivars on the initializes
<FromGitter> <j8r> nothing prevent you to declare the same on multiple initializes, which are calling each-other
_whitelogger has joined #crystal-lang
<raz> ka-boom :(
<raz> is Hash Fiber-safe? :P i call `MemoryCache#cleanup` from a background fiber while other fiber(s) might be doing stuff on the underlying Hash
<raz> hmm, i wonder if that is related. that call to #rehash was added only recently, it never blew up on me before.
* raz wraps that cleanup in a mutex for now
deavmi_ has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 260 seconds]
avane has quit [Quit: ZNC - https://znc.in]
avane has joined #crystal-lang
chachasmooth has quit [Ping timeout: 256 seconds]
chachasmooth has joined #crystal-lang
<FromGitter> <Aaron-JM> Im currently binding a library and one of the functions uses a foward declared struct as a parameter type, does anyone know how to bind this correctly since empty structs are not allowed?
<FromGitter> <viraptor1:matrix.org> Does crystal have safe navigation / safe call operator? I can't find anything obvious in the docs :-(
<oprypin> "safe"
<oprypin> @viraptor1:matrix.org: https://crystal-lang.org/api/0.35.1/Object.html#try(&)-instance-method
<FromGitter> <viraptor1:matrix.org> Yeah, that's it. I was of safe like ruby's safe navigation &.
<FromGitter> <viraptor1:matrix.org> *was thinking of
<FromGitter> <maxbertinetti> Hi pals. I opened a POLL on the forum about IDE / Editor adoption for Crystal. Can you please vote? ⏎ https://forum.crystal-lang.org/t/poll-which-ide-are-you-using-with-crystal/2764 ⏎ Thanks
_ht has joined #crystal-lang
<oprypin> i cant, there's no possible option lol
<FromGitter> <j8r> oprypin: No Kate :P
<oprypin> :3
<raz> everybody come to VSCode, so it gets all the plugin attention :P
<Andriamanitra> seems like majority of people already have, and we still can't have working auto-indentation for crystal.. maybe time to try something else
<raz> well, indentation works for me with ⌘
<raz> ⌘⌥f
<raz> but not while typing indeed
<raz> vscode does all kinds of smart stuff for JS while typing, would be great to have that for crystal (e.g. it converts to multiline method args when the method list becomes to long, hashes magically re-align etc.)
<raz> arg list*
<Andriamanitra> myeah format on save is a life-saver but it's still bit annoying that it's all over the place while typing
<raz> true. i've just gotten into the habit of smacking that shortcut every couple seconds. at least it's fast (sub-second)
<raz> jumping to beginning/end of block (% in vim) would also be much appreciated :(
<o5r> a question: any way to access comments through the AST?
<o5r> (or barring that, at runtime?)
melthelesbian has quit [Ping timeout: 260 seconds]
melthelesbian has joined #crystal-lang
<o5r> oprypin: ah, thanks, glorious. i was looking for a "comment" method. (─.─||)
<FromGitter> <asterite> there's no such thing, the doc comments are only available when you run `crystal docs`
<FromGitter> <HertzDevil> vscode does lots of things for js and ts out of the box because that's where most contributors to the core editor come from
<FromGitter> <bew:matrix.org> just fyi, gitter joined Matrix and the gitter room can be accessed at https://matrix.to/#/!DCnOFYRfeFHMcbUHoI:gitter.im ⏎ The android app is waaay better
<oprypin> that link is doing something weird for me, i suggest https://app.element.io/#/room/#crystal-lang_crystal:gitter.im
<FromGitter> <bew:matrix.org> yes just changed it actually
Human_G33k has quit [Remote host closed the connection]
Human_G33k has joined #crystal-lang
<o5r> asterite: so comments can't be accessed at runtime or compile time?
<FromGitter> <Blacksmoke16> Right, maybe could access them from the generated docs json output
<straight-shoota> o5r, what do you want to do?
<o5r> i'm trying to figure out a way to generate an OpenAPI spec at compile-time; j8r referred to a framework/router that ticks a lot of the boxes at runtime, but I don't think it did anything with comments (which would have been cool in order to grab the description of a given endpoint, for example)
<o5r> (i mean i'm okay with it being runtime too, i just want "minimum dev hassle" in maintaining the openapi docs
<o5r> )
<raz> o5r++
<straight-shoota> yeah grabbing the JSON output from `crystal docs` should work for you
* raz adds o5r to his friends list
<raz> athena + auto-swagger would be uh-mazing
<FromGitter> <Blacksmoke16> its more possible now
<raz> right, annotations + method signature should go most of the way. if it can then also grab the comment from the comment, it would be perfect
<FromGitter> <Blacksmoke16> as latest release added a way to access all registered routes, which has their metadata like args, path etc
<FromGitter> <Blacksmoke16> naw, way i have things setup is the annotations are used to create runtime metadata types. Then you could use those without needing to interact with the annotations
<raz> well, doesn't matter as long as the info is available at compile- or at least at runtime :)
<FromGitter> <Blacksmoke16> yea plan was to have something that uses https://github.com/icyleaf/swagger
<FromGitter> <Blacksmoke16> can pull some of the higher level stuff from `shard.yml`
<FromGitter> <Blacksmoke16> then from there would just be a matter of like "iterate over each route, iterate over each argument, etc"
<raz> well, there's still a few days till xmas. just sayin' 😬
<FromGitter> <elbywan:matrix.org> > *<o5r>* i'm trying to figure out a way to generate an OpenAPI spec at compile-time; j8r referred to a framework/router that ticks a lot of the boxes at runtime, but I don't think it did anything with comments (which would have been cool in order to grab the description of a given endpoint, for example) ⏎ ⏎ https://github.com/elbywan/openapi-generator
<FromGitter> <Blacksmoke16> downside there is you still need to manually type all that for stuff thats most likely already known
<FromGitter> <elbywan:matrix.org> it's not 100% relevant since it's not generated at compile time but you can have a look at the code if you wanna check
<FromGitter> <elbywan:matrix.org> no, it can infer most of the stuff with luck or amber
<FromGitter> <Blacksmoke16> oh nice
<FromGitter> <Blacksmoke16> was just extra data in the first examples then?
<FromGitter> <elbywan:matrix.org> *lucky
<FromGitter> <elbywan:matrix.org> yes there are examples with / without inference
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Blacksmoke16> neat, looks like someone beat you do it o5r :p
<FromGitter> <Blacksmoke16> you to it*
<o5r> being beat to that sounds really darn good tbh :D
<FromGitter> <Blacksmoke16> there you go raz, add in athena support xD
<raz> wish i had time for that. busy on the web-side of things (recently defeated keyset pagination and... made a cookie banner 🍪)
<FromGitter> <Blacksmoke16> pagination, fancy
<FromGitter> <Blacksmoke16> did you see the cookbook entry on that?
<raz> nope i haven't put it in the API yet, but that part will be easy anyway. (the tricky thing about keyset pagination is maintaining those tokens and making the ORM play ball, esp. when you allow sort by multiple columns)
<FromGitter> <Blacksmoke16> ah gotcha
<frojnd> Hi there.. I'm parsing a page and sometimes page doesn't have content so my statment fails to: `Unhandled exception: Index out of bounds (IndexError)` Can I catch index out of bounds?
<frojnd> IndexError
<FromGitter> <naqvis> use `[]?` instead, which returns `nil` when index out of range
<FromGitter> <naqvis> `p [1,2,3][4]? # => nil`
<frojnd> verse_id = "#{parser.css("h3.name, div.address a").map(&.inner_text).to_a.last}"
<frojnd> This statement fails since there is no such element (different page)
<FromGitter> <naqvis> yes, `Enumerable` raises exception on empty collections
<FromGitter> <Blacksmoke16> `.last?` returns nil instead of raising
<frojnd> That would also work I think
<FromGitter> <naqvis> same logic with `[]?`, where methods with `?` doesn't raise
ua_ has quit [Ping timeout: 240 seconds]
ua_ has joined #crystal-lang
<FromGitter> <j8r> o5r: what's the advantage of compile time vs run time?
<FromGitter> <j8r> the result is nearly the same, at least on the framework
<FromGitter> <j8r> it is easier to deal with runtime code
<FromGitter> <j8r> there is a way to use a method in the block (like &->method(String), which could take its comment. I see, yes maybe...
<FromGitter> <j8r> I don't think it is a good idea
<FromGitter> <j8r> @elbywan:matrix.org how can it refer the possible return status?
<FromGitter> <j8r> *infer
<FromGitter> <elbywan:matrix.org> see: https://github.com/elbywan/openapi-generator#api
<FromGitter> <j8r> "intercept calls"...
<FromGitter> <elbywan:matrix.org> ?
<FromGitter> <j8r> > openapi-generator overload existing or adds similar methods and macros to intercept calls and infer schema properties.
<FromGitter> <elbywan:matrix.org> yeah but what's the matter with intercepting calls ?
<FromGitter> <j8r> I'm searching what does it means
<FromGitter> <elbywan:matrix.org> overloading methods and macros
<FromGitter> <elbywan:matrix.org> existing framework methods and macros
<FromGitter> <j8r> I mean, does it has any implications?
<FromGitter> <j8r> looks like midly dangerous
<FromGitter> <j8r> I guess it is supposed to be only used in a dev environment to have the yaml file?
<o5r> j8r: there's no concrete advantage of compile- vs run-time generation for my use case but I guess it could be possible to make sure at compile-time that certain guarantees hold? The reason I was looking at compile-time initially was because I was approaching it from an annotations + macros standpoint, where I could have collected all the relevant information during build.
<FromGitter> <elbywan:matrix.org> I'm not sure I understand the issue, the generator is basically intercepting method calls (like `json code: 200, whatever…`) at compile time and registering the response (for example) data. Then at runtime it maps this with a route and generates the openapi file.
<o5r> from my standpoint it would be absolutely marvelous if I could prevent a dev from releasing something that has a broken swagger spec because if I get this stuff where I want it to, the broken spec could get promoted to production and end up in the hands of integrators, possibly third parties. if I can prevent that at build, huge win.
<FromGitter> <j8r> @elbywan:matrix.org I meant, can it induces bugs by modifying the underlying framework? I'm still looking at the code
<FromGitter> <elbywan:matrix.org> yeah of course it is strongly tied to the framework code
<FromGitter> <elbywan:matrix.org> so if the framework makes breaking changes then yes it will cause trouble
<FromGitter> <elbywan:matrix.org> (the inference part at least - the rest is decoupled)
<FromGitter> <j8r> o5r how to know if the swagger doc is "broken"?
<o5r> i guess you can't really break it if it's generated at runtime
<FromGitter> <j8r> nothing stops you to generate it one time, and then check the json somehow
<o5r> my current (go centric) experience usually has it involve a dev not changing the spec, usually by hand
<FromGitter> <j8r> @elbywan:matrix.org if i understand correctly, intercepting means, I have to call the path to have it in the OpenAPI file, no?
<o5r> i might be pulling at the pendulum really really really hard in the opposite direction
<FromGitter> <j8r> I don't see how compile-time vs runtime solves the issue of broken OpenAPI
<FromGitter> <j8r> if the routers is not modifiable at runtime, the result is the same
<FromGitter> <j8r> *after the initialization of course
<o5r> i already admitted that I don't think there's a clear advantage. fair point, too, about tge router
<FromGitter> <elbywan:matrix.org> @j8r: "intercepting" means basically that you have to call one of the overloaded framework methods to have the request/response body schema and query params correctly inferred in the generated openapi file
<FromGitter> <j8r> Ok that'
<o5r> (at least i think i admitted that. of it was unclear, i apologize profusely)
<FromGitter> <j8r> what I thought, fine!
<o5r> s/of/if/
<FromGitter> <j8r> theoretically everything is modifiable at runtime, but the framework has nothing to encourage that and doing it easily
<FromGitter> <j8r> but it can be interesting to have a way to add/delete routes at runtime
<FromGitter> <j8r> for instance, Caddy, a reverse proxy, has an API to do so
<o5r> i'm just really excited at having better stuff for that than untyped comments that people forget to modify anyway (and that is the best case)
<FromGitter> <j8r> yeah
<FromGitter> <j8r> adding a CI could do the trick (at least for Gripen)
<FromGitter> <j8r> iterate over all routes, and see if the description/summary, or whatever is missing. ⏎ Same with @elbywan:matrix.org library
<FromGitter> <j8r> Type inference is nice, but more error prone because we have to do really all the possible calls. ⏎ That's a bit like checking the return types in dynamic langs like Python/Ruby
coderobe has quit [Quit: '); DROP TABLE users;--]
coderobe has joined #crystal-lang
<o5r> j8r: Maybe the one thing going for compile-time, then? you can inspect the return type of methods, no?
<FromGitter> <Blacksmoke16> if they have one
<o5r> You can know that they don't, too, right? That is also information
<o5r> That was a dumb reply, ignore me, I apologize.
<FromGitter> <Blacksmoke16> yes but you wont be able to know what the *possible* types are
<FromGitter> <j8r> o5r You can at runtime
<FromGitter> <Blacksmoke16> i.e. if you have `def foo : Int32` you know it returns an int32, if you have `def bar : String | Bool` you know it returns a string or a bool, but if you have `def baz` it could return all three and you cant know
<FromGitter> <Blacksmoke16> yea, at compile time at least
<FromGitter> <j8r> having the logic without macros at least
<FromGitter> <Blacksmoke16> but can you really know it at runtime w/o calling them method?
<o5r> ah, i see
<FromGitter> <Blacksmoke16> the method*
<o5r> framework-generated compile-time warning when there's no specified return type, saying that no output types were detected for handler XYZ, and call it a day? lol
<FromGitter> <Blacksmoke16> athena requires them, so its the approach i took. However in my case i need it for defining a Proc, but also helps for documentation and such
<FromGitter> <Blacksmoke16> plus it makes sense given a route prob shouldnt be returning diff things each time you call it
<FromGitter> <Blacksmoke16> of diff types at least
<raz> +1 for forcing the dev to be explicit in that case
<o5r> can you say "it's an array unless there's only one" in json? i'm laughing but internally i weep
<raz> just make it always an array
<FromGitter> <Blacksmoke16> fun fact, at work we have a suuuuuper legacy api that we still kinda maintain
<o5r> raz: yes, please
<raz> 1 also fits in an array
<FromGitter> <Blacksmoke16> and in one of the responses, if there is no data its `false`, if there is 1 result its a single object, if there are more than 1, its an array of the objects
<FromGitter> <Blacksmoke16> as the value of one of the keys*
<raz> smoke: yup, been there...
<raz> bad, bad, bad
<o5r> same.
<FromGitter> <Blacksmoke16> good times
<raz> i'm quite a fan of json:api nowadays. bit verbose in places, but gets most things right
<o5r> More fun? I've been doing Go mainly, for the past ~ 7 years
<raz> plus it has proper docs so i can actually point at docs rather than just saying "you are wrong"
<o5r> that kind of stuff is really hard to deal with in go, esp. in deep structures
<o5r> (i mean "really hard for me", don't discount the possibility that i'm an idiot)
<raz> don't get me started on go. i pledged to be nice during the holidays.
<o5r> Hahahaha hey, it's my bread and butter, more or less. it's much better than other stuff, but if you take a few steps back, everything is kinda terribad.
DTZUZU has joined #crystal-lang
Human_G33k has quit [Remote host closed the connection]
Human_G33k has joined #crystal-lang
_ht has quit [Remote host closed the connection]
<oprypin> whats the most correct way to express "`Time` is older than 90 days"?
<oprypin> >> Time.parse_rfc3339("2020-06-19T22:21:06Z") < Time.utc - 90.days
<DeBot> oprypin: # => true - https://carc.in/#/r/a3wo
<oprypin> i have observed no difference whatsoever if using `Time.local` instead of `Time.utc`
<FromGitter> <Blacksmoke16> whats the problem here?
<oprypin> no problem, just weird
<FromGitter> <Blacksmoke16> how so?
<FromGitter> <Blacksmoke16> oh, i see what you're getting at
<FromGitter> <Blacksmoke16> `Time.parse_rfc3339("2020-06-19T22:21:06Z") < 90.days.ago`
<oprypin> and that one is implemented thru `Time.local` 🤔
<oprypin> thanks
<FromGitter> <Blacksmoke16> `90.days.ago.to_utc` :p
<oprypin> no but there's no difference
sorcus has quit [Quit: WeeChat 2.9]
sorcus has joined #crystal-lang
sorcus has quit [Quit: WeeChat 2.9]
sorcus has joined #crystal-lang
Human_G33k has quit [Ping timeout: 260 seconds]
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
<hightower3> Does anyone know what's the "best" bindings for curses lib?
<hightower3> there are a couple choices available, none with recent activity or convincing number of commits
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
<straight-shoota> oprypin, Time.local and Time.utc return *exactly* the same instant on the time line, just observed in different time zones
<oprypin> so how does that change my question?
<straight-shoota> it relates to your statement that you didn't notice a difference between them
<straight-shoota> so it doesn't matter whether you compare with local or UTC time
<straight-shoota> or any time zone
<oprypin> i can get that too
<oprypin> but the semantics of it though
<straight-shoota> I'd probably just use `time < 90.days.ago` it's most concise
<straight-shoota> note that it's not exactly 90 days though when DST change lies in the time span.
<oprypin> so how to get exactly 90 days?
<FromGitter> <Blacksmoke16> `Time::MontSpan.new 30`?
<FromGitter> <Blacksmoke16> er nvm, dont mind me
<straight-shoota> time < Time.utc.shift(days: -90)
<straight-shoota> Time#shift(days) gives you the same time of day just shifted by the number of days
<oprypin> can't discern these https://carc.in/#/r/a3xc
<oprypin> both appear correct even though there was a time shift in between
<oprypin> by "in between" i mean less than 90 days ago
ryanprior has left #crystal-lang ["User left"]
<straight-shoota> you need to actually use a time zone which observes a DST change
<straight-shoota> on carc.in the local time zone is just fixed +00:00
<oprypin> oh huh
<oprypin> no, same locally
<straight-shoota> to see an actual difference in the comparison result, the result of the time shift needs to be actually close to the DST change
<oprypin> ahaa
<straight-shoota> otherwise there's no difference as there's no difference when I compare time > 1000.years.ago
<straight-shoota> but the results of Time#shift and days.ago are different
<straight-shoota> https://carc.in/#/r/a3xh