ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.33.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
<raz> personally i like the idea of having before & after middlewares on each route node
<raz> but not sure how it would work out in practice, don't know any framework that has that
<FromGitter> <j8r> Thanks raz, indeed inspiring
<FromGitter> <j8r> raz i have exactly what you said
postmodern has joined #crystal-lang
<FromGitter> <j8r> *done
<raz> i imagine there can be tricky corner cases. like /foo requires auth, but you want /foo/bar to be excluded from it.
<FromGitter> <j8r> So, a middleware can be a set of handlers?
<raz> but no idea if such would be relevant in practice
<FromGitter> <j8r> raz I solved this: inside a block, you set default hanlders
<raz> yes, middlewares are usually a stack (array). each request travels through each
<FromGitter> <j8r> They can be overriden
<FromGitter> <j8r> Or a recursive class?
<FromGitter> <j8r> I may rename handlers to middleware then
<raz> well, in e.g. Rack and WSGI each middleware calls the next one
<FromGitter> <Blacksmoke16> there is also two aspects of auth
<raz> i haven't used the crystal ones, so don't know what way they are done there
<FromGitter> <Blacksmoke16> which are kinda different
<FromGitter> <Blacksmoke16> in how they can/should be handled
<FromGitter> <j8r> 2 aspects?
<raz> yea auth is a bit of a rabbit hole
<FromGitter> <Blacksmoke16> authentication versus authorization
<FromGitter> <j8r> @Blacksmoke16 what does it implies for us?
<FromGitter> <Blacksmoke16> im just saying there is a difference between knowing who the authenticated user is during a request, and if that user has permission to access a specific route
<postmodern> hello, new to crystal and wanting a more in-depth overview of the C bindings API. For example, how do I map in the `FILE*` type or variable arguments (aka `foo(int x, ...)`)?
<FromGitter> <Blacksmoke16> for example, what symfony doe, (as thats what im familiar with) is you can define `firewalls` which group together routes that share common authentication logic
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e4737bf48ca2e2974510de0]
<FromGitter> <j8r> @Blacksmoke16 I guess the user can be in a header, query or path param, then the hanlders do the auth
<FromGitter> <Blacksmoke16> then they have the concept of user providers, whose job it is to set the authed user on a request
<FromGitter> <Blacksmoke16> which could be via however you define it, lookup user in db based on jwt token, or username password etc
<FromGitter> <Blacksmoke16> then from there they have extra stuff to define logic of if that user has access to x
<FromGitter> <Blacksmoke16> the crystal version of this could be like
<FromGitter> <Blacksmoke16> 1) resolve the user from the request, 2) determine the firewall to use based on request path, 3) determine if that user has access to a specific route within that "domain"
<FromGitter> <Blacksmoke16> i didnt really dive into how i want to handle all this yet, but probably will be some concept of roles and you can do like
<FromGitter> <Blacksmoke16> ```@[ART::Get("/some/route") ⏎ @[ART::Security("ROLE_ADMIN")] ⏎ def private_route : Nil ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e473911292ff243d3cacba9]
<FromGitter> <Blacksmoke16> so it could work well if you maybe store the auth "requirements" of a given route, then have a middleware that applies those requirements to see if it should continue or not
<FromGitter> <j8r> It sounds like this configuration file exists because of a language limitation?
<FromGitter> <j8r> Or a feature is to modify the file at runtime?
<FromGitter> <Blacksmoke16> they support yaml, xml, or php code to configure the stuff
<FromGitter> <j8r> Wow ok
<FromGitter> <Blacksmoke16> yea, prob could think of a better way to define all this
<FromGitter> <Blacksmoke16> some DSL or something idk
<postmodern> wow that is slick. variadic C function mappings use the same syntax as C, just `, ...)`
<FromGitter> <Blacksmoke16> main point i was trying to make is maybe have 2 separate middleware, one for authenticating the user, and the other for authorization of that user
<FromGitter> <Blacksmoke16> postmodern: not super familiar with c bindings, but indeed it is :p
<FromGitter> <j8r> Why not, one issue is to pass the info between them
<FromGitter> <j8r> *challenge I can say
<FromGitter> <j8r> Possible with generics
<FromGitter> <j8r> But it is simpler to put both in one handler/middleware
<postmodern> still wondering how to handle FILE*. Would likely need to map in fopen as well. FILE appears to be some struct called _IO_FILE under the hood.
<FromGitter> <Blacksmoke16> > Why not, one issue is to pass the info between them ⏎ ⏎ This is where a DI approach helpful imo, as you can store data in a service and access it in other services, versus putting everything in `HTTP::Server::Context` which you only have access to in controller action and its middleware
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <j8r> In act no authentication means no authorization – I don't see how we will just need one and not another
<FromGitter> <Blacksmoke16> like symfony's authentication set is like `$this->tokenStorage->setToken(...);` then other stuff can inject `TokenStorage` to access current token/user
<FromGitter> <j8r> Oh yes, different means of authentication
<FromGitter> <Blacksmoke16> yup
<FromGitter> <Blacksmoke16> also have diff types of tokens, like `Anonymous`, or whatever else you define to allow knowing where a user came from, like `JwtToken` or whatever
<FromGitter> <j8r> There is way
<FromGitter> <Blacksmoke16> ```lib X ⏎ fun variadic(value : Int32, ...) : Int32 ⏎ end ⏎ ⏎ X.variadic(1, 2, 3, 4)``` [https://gitter.im/crystal-lang/crystal?at=5e473c120d257250fdea0154]
<FromGitter> <Blacksmoke16> is what they have in the docs postmodern
<FromGitter> <j8r> I think, not ideal, but the main authentication handler can call a method of `@next`
<FromGitter> <j8r> (with the `HTTP::Handler` logix)
<FromGitter> <j8r> Handling multiple authentication means in only middlewares on a single route is not easy
<FromGitter> <j8r> But doable
<FromGitter> <j8r> Ho right, got it
<FromGitter> <Blacksmoke16> oh?
_whitelogger has joined #crystal-lang
<postmodern> aka so-called private structs
return0e_ has joined #crystal-lang
confact_ has joined #crystal-lang
badeball has joined #crystal-lang
<FromGitter> <j8r> Still don't get the diff between handler and middleware
return0e has quit [Read error: Connection reset by peer]
confact has quit [Read error: Connection reset by peer]
davic has quit [Ping timeout: 272 seconds]
dostoyevsky has quit [Ping timeout: 272 seconds]
confact_ is now known as confact
<FromGitter> <j8r> For me `HTTP::Handler` IS a middleware by essence
<FromGitter> <Blacksmoke16> i think their synonymous
<FromGitter> <Blacksmoke16> they're
<FromGitter> <dscottboggs_gitlab> handlers are a type of middleware? at least as far as I understand
dostoyevsky has joined #crystal-lang
davic has joined #crystal-lang
<FromGitter> <j8r> More or less
<FromGitter> <j8r> What I see is middlewares are more powerful
<FromGitter> <dscottboggs_gitlab> I mean, there are many types of useful middleware, which may or may not intercept a request, of which a "handler" is one
<postmodern> is there a project like ruby_crystal_codemod, but for converting C headers into crystal C bindings? not looking forward to mapping in all of linux/videodev2.h ...
<FromGitter> <oren> i want to save some state about my program. where is a typical place and what format is common? i am thinking of ~./config/<app-name>/config.json
<postmodern> oren, if your storing configuration that the user can mange from inside the app, then ~/.config/ makes sense. There's also ~/.cache/ and ~/.local/share/ if you want to just dump out state before exiting.
<FromGitter> <oren> yeah. it's a CLI that I want to run and it opens vim for me with some options. one of the options is where is the notes file to open. i want to store it somewhere so next time you run the CLI, it will default to that location.
<FromGitter> <oren> and is json the usual format for that?
<postmodern> oren, there's no format restrictions AFAIK. Looking at my own ~/.config/, I can see INI files, XML files, and shell env variable files.
<postmodern> when dealing with LibC, I notice the Crystal code base doesn't call strerror, but initializes their own Errno messages. Is this the preferred way of handling libc errors?
<FromGitter> <636f7374> YAML, TOML
<FromGitter> <636f7374> ENV[HOME]?
<FromGitter> <636f7374> i18n -> ENV[LANG]
<FromGitter> <636f7374> IpcSocket -> ENV[TMPDIR]
<FromGitter> <636f7374> and (similar CRUD).
<FromGitter> <636f7374> Create, read, update and delete.
<postmodern> i am kind of weary of TOML due to how it was created ad-hoc and without a formal RFC style ABNF parser spec for other implementations to implement off of. Crystal stdlib seems to support parsing INI, but not generating it.
<FromGitter> <636f7374> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e475fd2d56ddb68a4a73d40]
<FromGitter> <636f7374> Diesel is the most productive way to interact with databases in Rust because of its safe and composable abstractions over queries.
<FromGitter> <636f7374> I will try Diesel later. ORM
<FromGitter> <636f7374> TOML is great in Rust.
<FromGitter> <oren> is there a repl i can play with to try random things?
<FromGitter> <636f7374> May not actually.
<FromGitter> <636f7374> but it's probably like this.
<FromGitter> <636f7374> 1) part ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e4766b00d257250fdea484a]
<FromGitter> <636f7374> I write quite confusingly.
<FromGitter> <636f7374> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e4767be0d257250fdea49fd]
<FromGitter> <636f7374> goodluck.
_whitelogger has joined #crystal-lang
OvermindDL1 has quit [Quit: Connection closed for inactivity]
OvermindDL1 has joined #crystal-lang
sz0 has joined #crystal-lang
_whitelogger has joined #crystal-lang
<FromGitter> <watzon> @oren there's carc.in and icr
_whitelogger has joined #crystal-lang
_whitelogger has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 240 seconds]
_whitelogger has joined #crystal-lang
<FromGitter> <TheOnlyArtz> Hey, I have this code: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ For some reason I'm getting nothing back [https://gitter.im/crystal-lang/crystal?at=5e47ac6818ac9b0fb5c00aa3]
tangorri has joined #crystal-lang
_whitelogger has joined #crystal-lang
_ht has joined #crystal-lang
<oprypin> oren, my favorite is $XDG_CONFIG_HOME (falling back to ~/.config) / yourprogramrc, in INI format
<oprypin> don't expect a REPL, just try things in a file
ur5us has joined #crystal-lang
Nicolab has joined #crystal-lang
postmodern has quit [Quit: Leaving]
ur5us has quit [Ping timeout: 248 seconds]
<FromGitter> <636f7374> @TheOnlyArtz Since you include `http/client`, why don't you use it?
<FromGitter> <636f7374> Or why don't you use `HTTP::Request.to_io`?
<FromGitter> <636f7374> `! = nil`, `.nil?`, `unless` Which do you think is better.
<FromGitter> <636f7374> Crystal `STDOUT` doesn't seem to work on Heroku?
<FromGitter> <636f7374> Still need `flush`? I will check again later.
<FromGitter> <636f7374> Cloudflare AnyCast IP should improve Heroku network performance (SOCKS5 over WebSocket), but damn I didn't buy a domain name, `dot.tk` is no longer available for free, It seems I need to buy a domain name for $1.
Nicolab has quit [Quit: Leaving.]
darkstardevx has quit [Ping timeout: 272 seconds]
darkstardevx has joined #crystal-lang
tangorri has quit [Remote host closed the connection]
<oprypin> 636f7374, `if a != nil` can be written as `if a`.
<oprypin> *also* i recently had a thought that i never ever want to use `unless` and `until`
darkstardevx has quit [Ping timeout: 240 seconds]
darkstardevx has joined #crystal-lang
<FromGitter> <636f7374> @oprypin I know these, just a rhetorical question.
<FromGitter> <636f7374> @oprypin `unless` and `until` will make the expression clearer, `unless` can solve the nil problem in the first place.
postmodern has joined #crystal-lang
<FromGitter> <TheOnlyArtz> @636f7374 I want to use the socket library and not the http/client
alexherbo2 has joined #crystal-lang
<FromGitter> <636f7374> @TheOnlyArtz why don't you use `HTTP::Request.to_io`?
<postmodern> can you define methods in C lib structs, or are they only intended to be templates for the C struct's memory layout?
<postmodern> also i take it anonymous unions within structs is not currently possible with crystal's C lib syntax?
<postmodern> also odd that libs are not modules, and cannot be included into the namespace of a module. would be handy
<oprypin> postmodern, no, just how you can't define them in C structs.
<oprypin> postmodern, anonymous unions have to be non-anonymous
<oprypin> postmodern, `lib` are a low-level wrapper and aren't to be exposed directly
<postmodern> oprypin, grumble. i was hoping to define the union as FooUnion, then add methods so s.bar maps to s.foo_union.bar
<postmodern> guess i should submit an issue and start a discussion
<postmodern> i do appreciate that the crystal-lang issues i have found via google always include lengthy and thoughtful discussion
<sorcus> https://gist.github.com/MrSorcus/cbb4b603abcfcb6e5ac01f19af7301da - haha, `.ends_with?` much better than `extname` *CRAZY*
<sorcus> And `.extname` about `~16` slower than `ends_with?` if extensions with dot too. :-D
<oprypin> postmodern, if you're gonna start an issue about making `lib` more convenient, keep in mind that it's a non-goal
<postmodern> oprypin, what is the criteria for something becoming a goal?
alexherbo23 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 272 seconds]
alexherbo23 is now known as alexherbo2
<FromGitter> <asterite> sorcus it's because `extname` allocates a string, but `ends_with?` doesn't. Allocating vs. not allocating always make a huge difference
<sorcus> asterite: Yeah, i understand this, but it still looks cool :-D
FromGitter has quit [Read error: Connection reset by peer]
FromGitter has joined #crystal-lang
sagax has quit [Ping timeout: 240 seconds]
return0e has joined #crystal-lang
return0e_ has quit [Ping timeout: 240 seconds]
alexherbo22 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo22 is now known as alexherbo2
sagax has joined #crystal-lang
masterdonx2 has joined #crystal-lang
MasterdonX has quit [Ping timeout: 272 seconds]
<sorcus> Who want to criticize my script? :-D :-D :-D
<FromGitter> <tenebrousedge> what does it do?
<sorcus> tenebrousedge: symlinks :-D
<FromGitter> <tenebrousedge> AHHHH MY EYES! THE HORROR!
<sorcus> tenebrousedge: Little script for creating symlinks from `src` directory to `public` :-D X-)
<sorcus> tenebrousedge: Are you kidding me? :-D
<FromGitter> <tenebrousedge> I'm always super cereal
<sorcus> But yes, it can be terrible :-(
<FromGitter> <tenebrousedge> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e4829c2b401eb68a57cf254]
<FromGitter> <tenebrousedge> similarly, the explicit returns in `allowed_extension` should be unecessar
<FromGitter> <tenebrousedge> should `expand_directory` be a recursive method?
<FromGitter> <tenebrousedge> that is, safe for all filenames?
<FromGitter> <dscottboggs_gitlab> I think so
<FromGitter> <dscottboggs_gitlab> but still I'd use `Path#parent`
<FromGitter> <tenebrousedge> you're right
<sorcus> "is this safe?" - maybe...
<sorcus> dscottboggs_gitlab: But `Path#parent` doesn't return relative path.
<FromGitter> <dscottboggs_gitlab> why do you need the relative path? Why not use absolute?
<FromGitter> <dscottboggs_gitlab> although honestly your way works I wouldn't worry about it if it were me
Xeago has quit [Read error: Connection reset by peer]
Xeago has joined #crystal-lang
<sorcus> dscottboggs_gitlab: Why not use absolute? - don't really know. There is any benefits for `absolute` instead `relative`?
<FromGitter> <dscottboggs_gitlab> idk, not using ../?
<FromGitter> <dscottboggs_gitlab> I don't see the issue really tbh
<sorcus> dscottboggs_gitlab: Maybe... But what if website directory renamed? With absolute path symlinks could be broken.
<FromGitter> <dscottboggs_gitlab> Oh, no, you're totally right
<sorcus> dscottboggs_gitlab: But yes, they can be recreated... Haha...
<FromGitter> <dscottboggs_gitlab> this is one case where using ../ makes perfect sense
postmodern has quit [Quit: Leaving]
<FromGitter> <dscottboggs_gitlab> you *could* put it in a path and do like `pathstr.count('/').times { path = ".." / path }` but I don't think it matters for a script
<sorcus> Main idea is to not hosted website in public. Instead use `src` (/home/web.apps/example.com/www/src) for sources and `public` (/home/web.apps/example.com/www/public) for symlinks.
<sorcus> In `www` directory place `data.yaml` file with paths / directories, which should be symlinked from src to public.
<sorcus> This useful for me, because sometimes in `src` can be placed some files, that should not be visible for anyone.
<sorcus> And if someone upload bad file (like backdoor.php) inside upload directory (for example), this file can't be called, because `public/upload` doesn't have symlink to this file.
<sorcus> It's controlled by `allowed_extension`.
<sorcus> dscottboggs_gitlab: Hmmm... Only if it can be more faster than current. :-D
<FromGitter> <dscottboggs_gitlab> Nah, the point of Path is to make it work cross-platform. I don't even know if the .. path works on windows
<sorcus> dscottboggs_gitlab: "linker data.yaml 0.00s user 0.00s system 97% cpu 0.004 total" - this is repeated call for 640 directories in cache.
<FromGitter> <dscottboggs_gitlab> nice
<sorcus> dscottboggs_gitlab: But i don't use Windows on servers :-D :-D :-D
<sorcus> dscottboggs_gitlab: But you are right.
<FromGitter> <dscottboggs_gitlab> Yeah, and why would you? Haha. So using a string is fine IMO
<sorcus> tenebrousedge: Yeah, with multiple slash the can be something wrong... But currently i control all `data.yaml` files and i don't think i can have a trouble with this.
<sorcus> tenebrousedge: Maybe i need to check all paths from `data.yaml` for leading slash and if any has, raise exception.
<FromGitter> <tenebrousedge> that seems reasonable
<FromGitter> <tenebrousedge> and you could also use `squeeze("/")` to compress multiple slashes
<sorcus> And for directories, where files or directories can be created at any time, i use systemd unit `.path`. If any changes in `src` directory, linker will be called.
<sorcus> tenebrousedge: Or cut slashes from the beginning...
<sorcus> Fuck...
<sorcus> I've posted old code... X-)
<sorcus> dscottboggs_gitlab: looks good :-)
<FromGitter> <dscottboggs_gitlab> needs more examples and some CSS work I think but yes I'm pleased to finally have it up at least :)
<sorcus> dscottboggs_gitlab: Why not create a tutorial like https://svelte.dev/tutorial/basics ? Or maybe someone already created...
<FromGitter> <tenebrousedge> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e48370fd56ddb68a4a8f351]
<FromGitter> <tenebrousedge> it's probably also worth aliasing `Array(String)` to `PathArray`
<FromGitter> <tenebrousedge> or `Paths`
<FromGitter> <dscottboggs_gitlab> > Why not create a tutorial ⏎ ⏎ decided this would be easier haha. I was kinda hoping that since each example is kinda its own thing that other community members would also contribute to the examples
tangorri has joined #crystal-lang
<sorcus> tenebrousedge: "early returns not necessary" - hmmm. But why? Some kind of optimisation?
<FromGitter> <tenebrousedge> there are methods in the standard library that do what you want, without the early return
<sorcus> dscottboggs_gitlab: I think i've seen crystal examples somewhere before...
<sorcus> tenebrousedge: Ah, yours truth. I should be more attentive.
alexherbo27 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 272 seconds]
alexherbo2 has joined #crystal-lang
alexherbo27 has quit [Ping timeout: 260 seconds]
tangorri has quit [Remote host closed the connection]
<FromGitter> <j8r> is it common to have nested http route controllers?
<FromGitter> <Blacksmoke16> Example?
<FromGitter> <j8r> for instance, a controller for all routers related to users, and inside one for its settings, a other for its posts, an other fur its images, etc
ht_ has joined #crystal-lang
<FromGitter> <Blacksmoke16> I doubt it. No reason you can't define all your routes in one controller
<FromGitter> <Blacksmoke16> But if you wanted to separate them they would most likely be individual classes
<FromGitter> <j8r> its the purpose of controllers: group a logical set of routes
_ht has quit [Ping timeout: 272 seconds]
ht_ is now known as _ht
<FromGitter> <Blacksmoke16> `AppController`
<FromGitter> <Blacksmoke16> Has all the routes for my app :p
<FromGitter> <j8r> sure we can have everything in a single controller, meh
<FromGitter> <j8r> why not
<FromGitter> <tenebrousedge> yes, you can have nested controllers, and it's common
<FromGitter> <j8r> Great :)
<FromGitter> <tenebrousedge> usually it's more of a routing level concern
<FromGitter> <Blacksmoke16> wait you mean like
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e4862d00c50da598c124634]
<FromGitter> <Blacksmoke16> thats what i was imagining, which prob should make them separate types
<FromGitter> <j8r> I can implement a way to merge routes of controller inside another
<FromGitter> <j8r> and then inside the main server
<FromGitter> <Blacksmoke16> that might get super confusing super quick
<FromGitter> <tenebrousedge> why not separate the routes from the controller actions?
<FromGitter> <j8r> the routes are hidden, that's an implementation detail
<FromGitter> <j8r> doing `get "/mypath"` will add a Node under the ground
<FromGitter> <j8r> @tenebrousedge what do you mean?
<FromGitter> <j8r> declaring controller actions register route nodes (in my web server router)
<FromGitter> <tenebrousedge> in rails you would do like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e4863945f82805026dd2928]
<FromGitter> <tenebrousedge> `resources` generates the standard REST routes for the type
<FromGitter> <j8r> interesting, but can't be done on my side
<FromGitter> <j8r> what I have now is
<FromGitter> <j8r> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e4864550c50da598c12498f]
<FromGitter> <tenebrousedge> I should mention, that there's also a standard mapping of `GET` => Controller#index, DELETE => Controller#delete
<FromGitter> <tenebrousedge> but that these are defaults and can be changed
<FromGitter> <j8r> so, `R` is the result type of route actions.
<FromGitter> <tenebrousedge> what if you want `/users/images` and `images` to point to the same controller action?
<FromGitter> <Blacksmoke16> > so, `R` is the result type of route actions. ⏎ ⏎ result type meaning the return type of each method?
<FromGitter> <tenebrousedge> what if certain path elements should go to one controller over another?
<FromGitter> <j8r> yep @Blacksmoke16
<FromGitter> <Blacksmoke16> so `get` and `post` would both have to return the same type?
<FromGitter> <j8r> @tenebrousedge they can both call the same method
<FromGitter> <tenebrousedge> the same controller method?
<FromGitter> <j8r> @Blacksmoke16 yes
<FromGitter> <Blacksmoke16> that doesnt seem ideal tho?
<FromGitter> <tenebrousedge> and does this handle parameterized path segments?
<FromGitter> <j8r> yes @tenebrousedge , and they are casted
<FromGitter> <Blacksmoke16> like `GET /user/1` would return `User` while `GET /user` would return `Array(User)`
<FromGitter> <j8r> agree
<FromGitter> <j8r> this is due to the handler sending the response
<FromGitter> <j8r> I will try to do a `forall T`, it may work
<FromGitter> <Blacksmoke16> or union together each method's return type?
<FromGitter> <Blacksmoke16> idk the implementation
<FromGitter> <j8r> ho no, in fact that's the Proc
<FromGitter> <j8r> the Proc insides the Nodes must be typed
<FromGitter> <Blacksmoke16> right, should each method not get its own node?
<FromGitter> <j8r> yes you can have `Controller(String | Nil | User)`
<FromGitter> <j8r> it has its own node, but inside a tree of nodes
<FromGitter> <Blacksmoke16> gotcha
<FromGitter> <j8r> can be mitigated by unions, or the routes writing to the context IO, or an object wrapper
<FromGitter> <j8r> btw thanks,
<FromGitter> <Blacksmoke16> np
<FromGitter> <j8r> I realized it's possible to merge 2 trees, one of `T` and the other of `R` ⏎ A new hash will have to be created - not a big deal Crystal is fast :) ⏎ More importantly, it is possible to change the type of an ivar
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Hash.html#merge!(other:Hash)-instance-method ?
<FromGitter> <j8r> In my case both hashes can have a different type
<FromGitter> <j8r> for example a controller returning `User` and another `Group`
<FromGitter> <j8r> *actions of the routes inside the controller
<FromGitter> <j8r> not a big deal, small startup penalty
<FromGitter> <j8r> I don't think there will be any human - measurable diff
HumanGeek has joined #crystal-lang
Human_G33k has quit [Ping timeout: 265 seconds]
_ht has quit [Remote host closed the connection]
_ht has joined #crystal-lang
<FromGitter> <Blacksmoke16> prob