daemonwrangler has quit [Ping timeout: 240 seconds]
asterite has quit [Ping timeout: 240 seconds]
asterite_ is now known as asterite
wmoxam has quit [Ping timeout: 240 seconds]
wmoxam has joined #crystal-lang
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 272 seconds]
kerframil has quit [Quit: WeeChat 3.0.1]
<FromGitter>
<acook> I ran into a fun bug earlier where I had an if statement inside a case statement and the compiler refused to believe the nil was handled until I moved everything into the case. Had me chasing my tail for a minute there though.
<FromGitter>
<Blacksmoke16> got an example?
f1reflyylmao is now known as f1refly
maxpowa has quit [Ping timeout: 272 seconds]
maxpowa has joined #crystal-lang
_ht has joined #crystal-lang
<FromGitter>
<erdnaxeli:cervoi.se> Hi! I am still working on my macros, what am I missing here? https://carc.in/#/r/afp6
<FromGitter>
<HertzDevil> just noticed you can do this in crystal but not ruby (because `String` doesn't define `#to_ary` there)
zorp has joined #crystal-lang
<FromGitter>
<asterite> Interesting!
<FromGitter>
<asterite> And so cool you managed to implement splat on left hand side
<FromGitter>
<asterite> The only thing we are missing regarding splats is being able to put them in tuple, array, and generally in any "array-like" structure. And I think that's even simpler than anything else (for starters it can just translate to an `each` loop appending each of them to the result, and later on we could check if the target type responds to `concat`)
<FromGitter>
<asterite> And I say this just for completeness!
<FromGitter>
<HertzDevil> that's also probably not very hard but i'd wait until crystal-lang/crystal#10009 is merged
<yxhuvud>
hertzdevil: that make me wonder exactly why string implement to_ary, as that is not exactly expected behaviour (at least not by me)
<FromGitter>
<HertzDevil> no, `#to_ary` is an exclusively ruby thing that the language calls whenever something is being (single) splatted
<FromGitter>
<HertzDevil> and we don't have `String#to_a` either???
<FromGitter>
<asterite> I think the main issue there is defining what that is... is it bytes? It it codepoints? Is it graphemes? That's why probably Ruby doesn't have it. Same reason why there's no `each` for String
<FromGitter>
<asterite> I *think* it should be graphemes, but we don't have that concept yet...
<yxhuvud>
asterite: I think the main issue there is accidental parallel assignment. I'd expect an error.
avane has joined #crystal-lang
<yxhuvud>
in ruby the string ends up assigned to x, which at least follows the internal logic of parallel assignment there
<repo>
Blacksmoke16: hey there! i'm trying to work not being able to define regexes for the allow origin config of athena
<repo>
ah i think i'm getting somewhere
<FromGitter>
<asterite> yxhuvud: you mean, if you have `x, y = exp` and you expected `exp` to be an array but it turned out to be a string?
<yxhuvud>
indeed. Similar to how I wouldn't expect `x, y = 5` to destruct the integer into internal bits I wouldn't expect something like that out of string assignment.
<FromGitter>
<asterite> That's true... but I'm more inclined to think that if that failed and you didn't notice, you are missing a test
<FromGitter>
<asterite> Or maybe we do need a `to_ary` or similar... maybe `to_splattable`, I don't know
<FromGitter>
<oprypin:matrix.org> I'd normally be super excited about these developments ⏎ but the fact that `a, b = [1, 2, 3]` is not an error makes all of this useless
<FromGitter>
<asterite> Why it would be an error? `a, b` means you are only interested in the first two elements
<yxhuvud>
Not certain how it could be. perhaps for `a, b = {1, 2}`
<FromGitter>
<oprypin:matrix.org> where does it indicate first elements?
<FromGitter>
<asterite> I guess maybe you thought you had two elements and you got 3 and you have a latent error...
<FromGitter>
<asterite> that's what the syntax means :-)
<FromGitter>
<asterite> but I agree that it can be error-prone
<FromGitter>
<oprypin:matrix.org> how do you decide that it means "first" not "last" elements. could've been the other way and would've made exactly as much sense
<yxhuvud>
I could see an argument for being explicit and require `a, b, * = [1, 2,3]` or something. :shrug:
<FromGitter>
<oprypin:matrix.org> yes please
<yxhuvud>
But it is hard to do the general case in a nice way for compiletime checks of dynamic things like arrays. For tuples or the like with fix amount of fields it would make more sense
<FromGitter>
<oprypin:matrix.org> it doesn't need to be compile time
<FromGitter>
<oprypin:matrix.org> if no asterisk, assert size first
<FromGitter>
<oprypin:matrix.org> then you can have both `*, a, b =` and `a, b, * =` making sense
<FromGitter>
<asterite> you mean `*, a, b` expects exactly three elements?
<FromGitter>
<oprypin:matrix.org> without `a, b =` being an alias to one of them arbitrarily
<FromGitter>
<oprypin:matrix.org> no no no that's 2 or more, discard others
<FromGitter>
<asterite> Oh, you mean `*, a, b` means "get the last two elements"
<FromGitter>
<oprypin:matrix.org> for anything "exactly" there is no asterisk involved, that's how you tell them apart
<FromGitter>
<asterite> I think that could work... it's a breaking change, though, but it's probably a minor one
<FromGitter>
<asterite> I think that will also make `x, y = "hello"` fail at runtime... though it will work for `x, y = "ha"`
<FromGitter>
<oprypin:matrix.org> that's great!
<FromGitter>
<Blacksmoke16> repo: there's a to-do to support that, atm probably best off just enumerating all the options
<yxhuvud>
asterite: gah.
<FromGitter>
<oprypin:matrix.org> btw i would say strings should not be unpackable like that
<repo>
Blacksmoke16: yeah that's not a possibility for me. I'm using review apps in gitlab ci
<yxhuvud>
Why does it work in the first place? Is it because string implement #each or something like that?
<repo>
so basically my frontend is deployed to subdomain that reflects the current branch name
<FromGitter>
<oprypin:matrix.org> it doesn't implement each though
<repo>
*to a
<FromGitter>
<oprypin:matrix.org> it's because it implements [0]
<FromGitter>
<asterite> `x, y = exp` translates rougly to `x, y = exp[0], exp[1]`, that's why it works
<FromGitter>
<Blacksmoke16> Should actually be a lot easier now. Problem before was there wasn't a way to instantiate a regex from yaml. I'll put together a pr this afternoon
<FromGitter>
<asterite> I guess string destructuring is fancy but probably unexpected and inconvenient
<yxhuvud>
rather than inconvenient I would say not very commonly useful. It is probably quite convenient the few times it is useful :)
<repo>
mmh
<repo>
but we have no support for named tuple destructuring, right?
<repo>
or even objects :P
<repo>
also what about nested tuple destructuring?
<FromGitter>
<naqvis> i would say instead of hardcoding de structuring inside compiler, it would be more better to provide Extractors. The way Scala handles it
<FromGitter>
<naqvis> that will make it useful for people and allow them to provide Extractors even for their custom objects
<FromGitter>
<naqvis> just my two cents
<yxhuvud>
be that as it may with string destructuring, I'm really hyped for getting support for `x, *y, z = {1, 2, 3, 4, 5}` and the like
<repo>
is that planned?
<FromGitter>
<jrei:matrix.org> could we do `x, _, *y, _, z`?
<FromGitter>
<HertzDevil> yes
<repo>
what about `z, {y, z} = {1, {2, 3}}`?
<repo>
*x
<repo>
or `{foo, bar: {baz}} = {foo: 1, bar: {baz: 2}}`? :)
<FromGitter>
<Blacksmoke16> yes, its in the form of events, versus `HTTP::Handler` stack
<FromGitter>
<Blacksmoke16> extendable context in what regard? Like how you'd normally monkeypatch things into `HTTP::Server::Context`?
<watzon>
Basically. I'm thinking along the lines of how most frameworks in more dynamic languages do it. For instance, express.js. They have a context object included with each request which can be extended (by yourself or third party libraries) usually via middleware to pass information along.
<watzon>
The reason I ask is because I'm trying to think of a clean way to do a similar thing with my Tourmaline bot library. I want to have a middleware stack, but middleware is mostly useless unless you have some way to pass information from the middleware to the actual controller that's handling the response.
<watzon>
All I've managed to come up with so far is basically what you said. Have a `Context` object that can be monkey patched
<FromGitter>
<Blacksmoke16> then part of knowing which args should be passed to the controller action, is checking if they're in the request's attributes
<FromGitter>
<Blacksmoke16> like the example in the API docs, it can be used to store custom stuff too
<watzon>
Ok that's basically what I had tried at first, but data that can be stored on it is limited to certain types right? Generally primitives
<watzon>
Which is the problem I ran into
<FromGitter>
<Blacksmoke16> naw, it can handle whatever
<FromGitter>
<Blacksmoke16> data is stored as a `Hash(String, Param)` where `Parameter(T) < Param)`
<watzon>
Hmm interesting. I may have to steal this.
<FromGitter>
<Blacksmoke16> which makes use of implicit generic type instantiation, or allows passing `T` explicitly to be more type safe
<watzon>
I originally tried to imitate `Log::Context` I believe, end it ended up being pretty limited.
<FromGitter>
<Blacksmoke16> depending on what/how exactly you want this to work, having dedicated properties or something might be better
<watzon>
Unfortunately due to the nature of the problem I have 2 options as I see it. Have a base object that can be monkey patched, or do something like `ParameterBag`. I hate the idea of monkey patching as an API requirement, so I hope I can get the `ParameterBag` thing to work.
<FromGitter>
<Blacksmoke16> both have their pros and cons. Like `ParameterBag` you cant really document *what* things you could get from it as its dependent on how you use it, and more complex.
<watzon>
Right
<FromGitter>
<Blacksmoke16> alternative is you could have a `Context` option that accepts some other obj where your lib defines the base type
<FromGitter>
<Blacksmoke16> so you kinda just define the interface and let users implement what it could be?
<FromGitter>
<Blacksmoke16> main challenge there would be how to provide the custom type, and some stuff would need to be nilable given it wont all be set at once
<watzon>
Yeah there's that, and it wouldn't be very extendable. What happens if someone has a library with a custom middleware and wants to add to that custom type?
<watzon>
They wouldn't know what to monkey patch
<FromGitter>
<Blacksmoke16> ah so it kinda needs to be a global thing yea? I.e. not specific to a specific implementation
<watzon>
Yeah
<watzon>
I'm going to try and make the `ParameterBag` thing work. If it doesn't I'll stick to monkey patching a base object.
<watzon>
Thanks!
<FromGitter>
<Blacksmoke16> 👍 g
<watzon>
Knew you'd be the person to talk to haha
<FromGitter>
<Blacksmoke16> gl*
r0bby has quit [Remote host closed the connection]
sz0 has quit [Remote host closed the connection]
<FromGitter>
<oprypin:matrix.org> is there some kind of "standardized" benchmark for http routers?
r0bby has quit [Remote host closed the connection]
sz0 has quit [Remote host closed the connection]
<FromGitter>
<oprypin:matrix.org> omg i'm a genius
<FromGitter>
<oprypin:matrix.org> a router can be based on StringInterpolation literals
r0bby has joined #crystal-lang
<straight-shoota>
opyrpin, yeah that should work
<straight-shoota>
bruce perens works with that in his i18n shard
sz0 has joined #crystal-lang
<FromGitter>
<lirossarvet> Hm, now I have a testing question that I think I have an answer to but want to check with y 'all. We have a CLI that, at the moment, does a lot of calls to just shell commands with `Process.run`. It seems like the best way, in Crystal, to test that we're doing the right thing is pass in a `runner` argument that defaults to `Process` but could be overridden into something else that just stores the arguments
<FromGitter>
... given. Still kinda makes the return value a little tricky, but some harnessing and force-returns based on specific argument values may work. ⏎ ⏎ Does anybody have any thoughts about how best to test for `Process.run` calls?
<FromGitter>
<Blacksmoke16> could you test the output of your binary? It's possible to run your binary with `IO::Memory` IOs, then just ensure they contain what you'd expect?
<FromGitter>
<Blacksmoke16> depends on what you want to test exactly
<FromGitter>
<lirossarvet> I'd...rather not run the binaries given what side-effects they may have
<oprypin>
Blacksmoke16, i think you got the question in the reverse direction
<FromGitter>
<oprypin:matrix.org> @lirossarvet: seems like you got it
<FromGitter>
<Blacksmoke16> ohh, wants to ensure the right args are passed to the `Process.run`
<FromGitter>
<Blacksmoke16> how bad of an idea would it be to do like `class NoopProcess < Process`, which just collects the stuff then can run assertions within `.run`
<FromGitter>
<lirossarvet> That's more or less what I want to do 😅 Either run assertions within `run` or let me inspect after.
<FromGitter>
<lirossarvet> Nice to know this is at least the right path, so I can poke around and figure out what specific approach will be easiest to follow for others.
<FromGitter>
<Blacksmoke16> https://crystal-lang.org/api/master/Log.html#capture(source:String=%22*%22,level:Severity=Log::Severity::Trace,*,builder=Log.builder,&)-class-method works pretty great for the `Log` side of things
<FromGitter>
<Blacksmoke16> similar concept, not directly useable for this context tho
<FromGitter>
<lirossarvet> yeah. :D Alright, thanks for the help. Guess I know what I'll end up doing this weekend
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
<FromGitter>
<oprypin:matrix.org> @Blacksmoke16: how to use catchall in amber router? `r.add("/get/*", :catch_all); r.find("/get/foo")` - so how to get this foo?
<FromGitter>
<Blacksmoke16> hmm
<FromGitter>
<Blacksmoke16> wouldnt it just be in the `params` or `args` or whatever hash?
<FromGitter>
<oprypin:matrix.org> it's not in params as i see.
<FromGitter>
<oprypin:matrix.org> it is empty
<FromGitter>
<oprypin:matrix.org> oh youre supposed to specify some name