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
[gnubie] has joined #crystal-lang
* [gnubie] waves
<FromGitter> <Blacksmoke16> o/
<[gnubie]> i want to learn how to write in crystal. i only write in bash script. i want to have a simple web page to input a username and password then it will get the data from a remote api.
<[gnubie]> currently, i just do it in bash with curl like: curl -d '{"username":"$USERNAME", "password":"$PASSWORD"}' -X POST https://$FQDN:$PORT/api/...
<[gnubie]> my plan is to have a simple web page that when a user visits that page, the user needs to submit his/her username and password. when he/she clicks the submit button, the username and password will be used to connect to a remote api similar to the above curl command. if successful, the output will be printed on the page
<[gnubie]> can anyone share what should i need to read in order for me to achieve my objective? thanks!
<FromGitter> <Blacksmoke16> remote api that already exists?
<[gnubie]> yes
<[gnubie]> basically, i just want to have a similar curl client on the web page
<FromGitter> <Blacksmoke16> for personal use or public
<[gnubie]> personal use.
<FromGitter> <Blacksmoke16> and i assume the username/password, fdn, port, path are all static?
<[gnubie]> yes
<FromGitter> <Blacksmoke16> so prob new up one of these with the hostname
<FromGitter> <Blacksmoke16> can use https://crystal-lang.org/api/master/HTTP/Client.html#basic_auth(username,password)-instance-method for auth
<FromGitter> <Blacksmoke16> then use https://crystal-lang.org/api/master/HTTP/Client.html#post(path,headers:HTTP::Headers?=nil,body:BodyType=nil):HTTP::Client::Response-instance-method to make the request
<[gnubie]> so what i do now is: export USERNAME="abc" && export PASSWORD="123" && curl -d '{"username":"$USERNAME", "password":"$PASSWORD"}' -X POST https://$FQDN:$PORT/api/...
<[gnubie]> once the above command is successful, i will get the data in json format
<[gnubie]> i will read the docs you've suggested, Blacksmoke16. thanks!
<[gnubie]> do i need to have a web server running on the same crystal application?
<FromGitter> <Blacksmoke16> you would prob want to supply them using https://crystal-lang.org/api/master/ENV.html
<FromGitter> <Blacksmoke16> i mean do you need a web server?
<FromGitter> <Blacksmoke16> any reason this couldnt just be a cli app like curl?
<[gnubie]> so that i will not use the terminal when i want to get the value since most of the time i have a web browser already open
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <Blacksmoke16> could prob use the stdlib's http server, dont really need any routing so any request coming in just make the request and return the response
<[gnubie]> yes, that's basically what i wanted. once i post, just display the json response.
<[gnubie]> thanks for the links Blacksmoke16. i really appreciate it.
<FromGitter> <Blacksmoke16> you'd prob want something like
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fb86476bba6a3778b71d6e9]
<FromGitter> <Blacksmoke16> new up a client with your api domain (assuming its https)
<FromGitter> <Blacksmoke16> auth the client with username and password passed in via env vars (or could just make the constants really)
<FromGitter> <Blacksmoke16> define an HTTP server that when a request comes in sets the content type as JSON, does a request to your api, and streams the response body back to the client
<[gnubie]> let me try it out. thanks again Blacksmoke16.
<FromGitter> <Blacksmoke16> ofc doing a like `crystal build app.cr`
<FromGitter> <Blacksmoke16> then `USERNAME=FOO PASSWORD=BAR ./app`
<FromGitter> <Blacksmoke16> to run it
<[gnubie]> if i want to make a text field for entering the username and password on the web page similar to a login page, how should i do that?
<FromGitter> <Blacksmoke16> Now you're getting complex :p
<FromGitter> <Blacksmoke16> What about query params?
<[gnubie]> for now, the query params are static so i can just hardcode it for now
<[gnubie]> i just need to input username and password
<[gnubie]> the password field should be masked
<FromGitter> <Blacksmoke16> If they're static why bother needing to input them?
<FromGitter> <Daniel-Worrall> use query params from your login page to a POST route on the crystal server
<[gnubie]> the only thing may change is the username and password
<FromGitter> <Daniel-Worrall> not the backend query params
<[gnubie]> the web page may look like a normal login page where this is only an input text field for username and password only then a submit button
<FromGitter> <Daniel-Worrall> Then you want 2 routes, 1 to present the form, and the other to receive the login/pass and display the result
<FromGitter> <Blacksmoke16> Yea, actually won't be that hard I think
<[gnubie]> yes, something like that
<FromGitter> <Daniel-Worrall> Would be really nice to have a full tracked ruby vs crystal modules/methods and the official word on if they're included, to be included, intentionally left out, etc
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fb86b5b477a8b480c0a06b3]
<FromGitter> <Blacksmoke16> something like that ought to work eh?
<FromGitter> <Blacksmoke16> er minus the pp ;P
<FromGitter> <Daniel-Worrall> I don't think he wanted the basic auth, just to be passed to the api
<[gnubie]> yes, i don't need the basic auth on the web app itself
<FromGitter> <Blacksmoke16> well when you land on the form, the username and password are used as the username and password within the submit route
<FromGitter> <Blacksmoke16> which is what it was doing before no?
<FromGitter> <Daniel-Worrall> They want instead of, not also
<FromGitter> <Blacksmoke16> mm not sure i follow
<[gnubie]> if i open my web browser and type in http://localhost:8080 then a simple form with username and password text fields will be displayed. if i fill in the username and password then click the submit button, the username and password will be posted to a remote api. if it succeeded, i will get a json output
<FromGitter> <Blacksmoke16> right, whats what i did no?
<[gnubie]> on your first code, you have this line ~> CLIENT.basic_auth ENV["USERNAME"], ENV["PASSWORD"]
<FromGitter> <Blacksmoke16> right, now it gets those values from the form data
<[gnubie]> which the environment variables are required when executing the app itself
<FromGitter> <Blacksmoke16> notice i dont have the env vars anymore
<FromGitter> <Daniel-Worrall> the auth is going to be in a POST JSON body, not Authorization header
<FromGitter> <Daniel-Worrall> so not basic_auth
<FromGitter> <Blacksmoke16> i dont think thats accurate?
<FromGitter> <Daniel-Worrall> basic_auth uses Authorization header, gnubie wants POST JSON body
<[gnubie]> Daniel-Worrall is right. the username and password is part of the POST JSON body
<FromGitter> <Blacksmoke16> You want those to be used in the request to the remote api yea?
<[gnubie]> yes
<FromGitter> <Blacksmoke16> I'm pretty sure that's what it's doing
<[gnubie]> let me compile it again
<FromGitter> <Blacksmoke16> The firm isn't submitting directly to the remote api
<FromGitter> <Blacksmoke16> Firm
<FromGitter> <Blacksmoke16> Form
<[gnubie]> what does the "pp params" mean/do?
<FromGitter> <Blacksmoke16> puts params.inspect
<FromGitter> <Blacksmoke16> pretty print
<[gnubie]> i see. thanks again Blacksmoke16. i will try to understand and extend your code as i go along in my learning journey.. :)
<FromGitter> <Blacksmoke16> Was for me to debug, don't actually need it
<FromGitter> <Blacksmoke16> Np
<[gnubie]> :)
<[gnubie]> and also thank you Daniel-Worrall...
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
* [gnubie] waves... gtg now... thanks!
[gnubie] has quit [Quit: Leaving]
<FromGitter> <Blacksmoke16> o/
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 240 seconds]
chachasmooth has quit [Ping timeout: 240 seconds]
chachasmooth has joined #crystal-lang
chachasmooth has quit [Ping timeout: 260 seconds]
chachasmooth has joined #crystal-lang
avane has quit [Quit: ZNC - https://znc.in]
avane has joined #crystal-lang
<FromGitter> <HertzDevil> @3n-k1 use `Enumerable#to_h`
<FromGitter> <HertzDevil> ```code paste, see link```
f1reflyylmao is now known as f1refly
<raz> hmm, one thing i miss in vscode + crystal is refactoring support (mark block of code, hit shortcut, it's moved out of the current method and wrapped into a `def foo; end`)
<raz> </random-afternoon-rant>
wmoxam has quit [Ping timeout: 256 seconds]
<kevinsjoberg> Would it be of interest supporting passing implementation files to `crystal spec`? So given src/whatever.cr it would try to find spec/whatever_spec.cr and run that?
<oprypin> i dont think so
<oprypin> no one-size-fits-all approach here
<kevinsjoberg> oprypin: Care to elaborate? :) I was thinking that we've already have strong conventions in place for impl/spec, so it kind of makes sense.
<kevinsjoberg> It wouldn't break any of the existing features either.
<oprypin> i havent seen that those conventions are so strictly followed
<oprypin> yea but it's complexity and confusion and support requests
<kevinsjoberg> Well, isn't `crystal spec` following these conventions already?
<oprypin> it's just spec/**
<kevinsjoberg> E.g., running `crystal spec` is basically like passing `crystal spec spec/**/*_spec.cr`?
<kevinsjoberg> oprypin: Oh, really? Could have sworn it was spec/**/*_spec.cr.
<oprypin> hm maybe it is
<kevinsjoberg> The docs says the following
<kevinsjoberg> `crystal spec spec/my/test/` will do
<kevinsjoberg> `Run all specs in files matching spec/my/test/**/*_spec.cr`
<kevinsjoberg> Yeah, you see. So that's why I think it kind of makes sense. We've already make these assumptions.
<kevinsjoberg> So it's just nice to be able to run crystal spec over the current file, be it the implementation or the spec itself, and the tests for that file run.
<oprypin> it's not really the same to say '*_spec" and "<exactly name of a source file>_spec"
<oprypin> crystal compiler has src/box.cr -> spec/std/box_spec.cr
<kevinsjoberg> oprypin: Sure, that's true. But it would be an assumption it could make whenever you pass it something that's not *_spec.cr. If it exists, sweet, we can run the spec for you, otherwise, we just say it can't find a test for the given file.
<kevinsjoberg> It wouldn't break any existing workflow. It would just make it a little bit sweet when files map 1-1.
<oprypin> `function crspec { for f in "$@"; do f="${f#src/}"; echo spec/**/"${f%.cr}_spec.cr"; done | xargs -t crystal spec; }`
<oprypin> kevinsjoberg, here^. usage: `crspec src/box.cr` or `crspec box`
<oprypin> bonus: you can customize it however you want, dont need to change crystal
<kevinsjoberg> oprypin: Thanks for that, doing it myself is always an option I was just scouting for opinions on adding this as a default in Crystal itself. :)
<oprypin> thanks for the idea of the alias, it's actually a good one :p
<kevinsjoberg> oprypin: Glad I could help, I did indeed add it to my shell as well. :)
<kevinsjoberg> Quick question, have `crystal spec` ever accepted absolute paths? I'm using the Crystal TextMate bundle and it seem to provide crystal spec with the absolute path, which doesn't seem to work.
<kevinsjoberg> It looks like `crystal spec` assume files to be provided relative to the spec directory. Is there any technical reason for this?
<oprypin> no, probably just shitty implementation
<kevinsjoberg> Alright, then I'll dive into the code then, I want to support that. :)
<oprypin> kevinsjoberg, ah i see now. it is actually somewhat technical. crystal spec is implemented by writing out a program that has a bunch of `require "path_you_specified"`. and requires dont suppot absolute paths
<kevinsjoberg> Oh, yeah, that makes sense. I guess we could check if absolute paths were provided?
<kevinsjoberg> Would it make sense to normalise absolute paths, if provided? I guess we do have enough context to do that?
<oprypin> i think it just needs this
<oprypin> + %(require "./#{::Path[filename].relative_to(Dir.current).to_posix}")
<oprypin> kevinsjoberg, feel free to take this, check for corner cases, and pursue this in a pull request
<oprypin> - %(require "./#{::Path[filename].to_posix}")
<kevinsjoberg> oprypin: Thanks for that, appreciate it. Will do!
<oprypin> i can tell one edge case already: on Windows you won't be able to run a spec with an absolute path that happens to be on another drive πŸ˜‚ but not much can be done
<oprypin> umm while we're looking at that line, it really really should be `require #{"./#{::Path[filename].relative_to(Dir.current).to_posix}".inspect}`
<kevinsjoberg> oprypin: Seems to be working. Tests passing. Why inspect though?
<oprypin> kevinsjoberg, so that the file can have a " or a \ in its file name and not break this horribly
<oprypin> it's a pre-existing issue, not directly related
<kevinsjoberg> Oh, yeah, I see, since inspect escape stuff.
Stephanie has joined #crystal-lang
Stephanie has quit [Excess Flood]
Stephanie has joined #crystal-lang
Stephie has quit [Read error: Connection reset by peer]
<kevinsjoberg> oprypin: May I trouble you a bit? For some reason I fail to compile Crystal on my machine, could you try this branch out? https://github.com/KevinSjoberg/crystal/tree/spec-abs-paths
<kevinsjoberg> I thought we could add the inspect case as a different pull request to keep it dead simple.
<oprypin> kevinsjoberg, well i had compiled the exact same code so thats probably not it. try without any changes lol
<kevinsjoberg> oprypin: I get the problem, and can't really find out why.
<kevinsjoberg> Make just dies on me when I compile.
<kevinsjoberg> No ouput.
<oprypin> show the problem, not your branch
<oprypin> oh
<oprypin> i usually do make clean; make
<kevinsjoberg> Just "Killed; Error 137"
<kevinsjoberg> I'll try again
<oprypin> google >> Exit code 137 - Out of memory
<kevinsjoberg> oprypin: Oh, *face palm*. My bad.
<kevinsjoberg> Well, that sucks.
<kevinsjoberg> oprypin: Alright, managed to get it to run. Really need to get more memory. PR up. Thanks for all the help!
<oprypin> :>
<FromGitter> <j8r> Hash is not Indexable?
<FromGitter> <j8r> Strange because it has `#first_key` and `#first_value`
<FromGitter> <j8r> also `#key_index`
<oprypin> j8r, wow key_index is a really weird one. could open an issue to drop it
<FromGitter> <j8r> The question is even broader
<FromGitter> <j8r> do we assume Hash is Indexable, then we can add methods with indexes
<FromGitter> <j8r> Or we don't, then drop everything related to
<FromGitter> <j8r> I create an issue, ok
<oprypin> we dont, of course
<oprypin> although yea it would be nice in many ways
<FromGitter> <j8r> We could have an OrderedMap, something like that
<FromGitter> <j8r> oprypin: note that the public API states that the insertion order is preserved
<oprypin> i know
<oprypin> j8r, u realize that it actually can't be indexable?
<oprypin> foo[Int] would be conflicting
<FromGitter> <j8r> yeah...
<FromGitter> <j8r> That's a bit like `YAML::Any` or `JSON::Any`
<FromGitter> <j8r> won't be ideal
<FromGitter> <j8r> oprypin: not sure about the conflict
<FromGitter> <j8r> because we will be good if the Hash implementation overrides the Indexable#[] one
<FromGitter> <j8r> and in Indexable, ensure that `#fetch` is used
<FromGitter> <j8r> ha, fetch is also present in Hash... ok πŸ˜…
<oprypin> j8r, no, what is `{1: "a", 0: "b"}[0]`
<oprypin> j8r, no, what is `{1 => "a", 0 => "b"}[0]`
<FromGitter> <j8r> yes sure
<FromGitter> <HertzDevil> it's `"b"` because that doesn't affect `#unsafe_fetch`, but that doesn't mean `Hash` needs to be `Indexable` either
<FromGitter> <j8r> oprypin: it will be as today
<FromGitter> <HertzDevil> oh there's actually a conflict elsewhere
<FromGitter> <HertzDevil> `Indexable#values_at` and `Hash#values_at`
<FromGitter> <HertzDevil> but more importantly both `#key_index` and lookup using those indices are O(n)
<FromGitter> <HertzDevil> that's a huge sign you shouldn't make `Hash` indexable even if it is doable
<FromGitter> <j8r> maybe, bust having `#last_*` and `#first_*`
<FromGitter> <j8r> it must be possible to efficiently get the second or before last one
<FromGitter> <HertzDevil> for what
<FromGitter> <j8r> I suppose the same reasons than last and first
<FromGitter> <j8r> that's how the internal implementation does https://github.com/crystal-lang/crystal/blob/605ec43fc/src/hash.cr#L833
<FromGitter> <j8r> `get_entry(index)`
<FromGitter> <HertzDevil> and for what?
<FromGitter> <HertzDevil> does implementing `Hash` internally as an `Indexable` make you happier?
<FromGitter> <j8r> That's not the question
<FromGitter> <j8r> Hash is partially assumed to be indexable in some places, and in others not
<FromGitter> <j8r> I just want to clarify that
<FromGitter> <j8r> If we don't want to be indexable/ordered
<FromGitter> <HertzDevil> `get_entry(index)` does not imply `Hash` is assumed to be indexable
<FromGitter> <j8r> really?
<FromGitter> <j8r> sure, for the module
<FromGitter> <j8r> but it means Hash has an index somehow
<FromGitter> <HertzDevil> not one that fits into `(0...size)`
<FromGitter> <j8r> that's more assuming if Hash is ordered, rephrased
<FromGitter> <HertzDevil> that `i` is *not* the internal index
<FromGitter> <HertzDevil> it has nothing to do with enumeration order
<FromGitter> <j8r> not sure to follow
<FromGitter> <j8r> the insertion order is preserved
<FromGitter> <HertzDevil> insertion order has nothing to do with whether a type should satisfy `Indexable`, either
<FromGitter> <j8r> yes
<FromGitter> <j8r> but we could have `get_entry(index)` exposed, I don't know
<FromGitter> <j8r> currently we do `.values[index]`
<FromGitter> <HertzDevil> i think you're misunderstanding `#get_entry`
<FromGitter> <HertzDevil> it's an index into the underlying hash table
<FromGitter> <j8r> yes, and? ⏎ ⏎ > Returns the entry in `@entries` at `index`.
<FromGitter> <HertzDevil> it is not the same as `.values[index]`
<FromGitter> <HertzDevil> and how does that make `Hash` a candidate for `#bsearch` and a semantically unsound `#equals?`?
<yxhuvud> j8r: Hash IS ordered.
<FromGitter> <j8r> yxhuvud: and not officially indexed?
<yxhuvud> yes? Because what would the use case be?
<FromGitter> <j8r> even if there is `Hash#key_index`?
<FromGitter> <j8r> just the point that was confusing me πŸ˜…
<yxhuvud> :shrug: It is used in a few places internally (based on the commit that added it).
<FromGitter> <mattrberry> If I just have a macro like this ⏎ ⏎ ```macro set_bit(value, bit) ⏎ ({{value}} | 1 << {{bit}}) ⏎ end``` ⏎ ⏎ Is there any advantage to making that a macro rather than just making it a function with the `@[AlwaysInline]` annotation? The function is nice because then I get proper type restrictions, but I'm just curious if there's any performance impact with an inlined function instead
<oprypin> mattrberry, the common wisdom has been to avoid macros if at all possible. but i'm not sure if it's backed by any assertion that there's no performance difference whatsoever
<FromGitter> <mattrberry> Good to know, thanks @oprypin
<FromGitter> <mattrberry> I overuse macros for sure
<FromGitter> <mattrberry> I also have been using these macros for months, but I recently realized that Int has effectively the same methods already ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ but I haven't measured the performance impact of switching to those yet [https://gitter.im/crystal-lang/crystal?at=5fb95f6ebba6a3778b7405cb]
<FromGitter> <mattrberry> My `bits` macro is definitely faster than Int.bits though, since Int.bits does bounds checks and other stuff, and checks the range's bounds at runtime
<FromGitter> <mattrberry> I'm curious what the performance impact is when I'm running this ~45m+ times per second
HumanG33k has quit [Ping timeout: 260 seconds]
<oprypin> mattrberry, oh wow do i have news for you
<oprypin> mattrberry, `def` and `macro` produce an identical binary. https://gist.github.com/99b7fa4cecaabe79883286c8b62a66aa
<oprypin> `alwaysinline` somehow makes it different tho
<FromGitter> <mattrberry> That's awesome!
<FromGitter> <mattrberry> Thanks for checking :)
<FromGitter> <mattrberry> I assume that `exe_test_def` is `exe_macro` and you just changed the name?
<yxhuvud> oprypin: that is a bit weird, I'd have assumed the debug and dwarf stuff would be different
<yxhuvud> regardless of if the actual executed code ends up identical
<oprypin> mattrberry, yes. oops i messed up the output, updated now.
<yxhuvud> actually, perhaps it is expected when the defs and macros are on the same line. adding an extra line for alwaysinline would throw off the dwarf and debug stuff though and that would make the shasum differ
<yxhuvud> @oprypin: what happens if you add a newline on the line alwaysinline is for the other examples? Are all three identical after that?
<oprypin> u can try yourself :o
<oprypin> yxhuvud, but wow great idea, it is actually identical
<oprypin> kevinsjoberg, wait what's going on with https://github.com/crystal-lang/crystal/pull/9951/files - where did the `relative_to` call go?
<FromGitter> <mattrberry> Hmm super interesting. Would set_bit always be inlined there anyway, even without the annotation? What’s the general approach the compiler uses when deciding to inline functions?
<oprypin> mattrberry, it's llvm deciding. it's smart apparently.
<oprypin> mattrberry, as you can see, yes, it's inlined. almost sure that it's always
<FromGitter> <mattrberry> Interesting, good to know. I wonder what llvm decides that based on
<FromGitter> <mattrberry> Also, do you know why adding the new lines changed the compiled output? I’d have assumed that wouldn’t matter
<yxhuvud> mattrberry: the executable have debug info that includes line numbers.
<FromGitter> <mattrberry> Ahh
<FromGitter> <mattrberry> So presumably it wouldn’t matter if you built with β€”no-debug?
<FromGitter> <mattrberry> I’ll be back at my computer in 5 mins to check
<yxhuvud> don't think so, you'd still have stack traces etc
<yxhuvud> ugh. it is funny how it always is some other issue is hiding behind every one I fix. turns out monkeypatching the scheduler to not use libevent is a pretty deep hole to dig into. Perhaps not so surprising.
<FromGitter> <mattrberry> ```code paste, see link``` ⏎ ⏎ Fyi, `--no-debug` does it even without the newlines :) [https://gitter.im/crystal-lang/crystal?at=5fb96821b03a464f08243f0b]
<FromGitter> <mattrberry> Thanks for the info :)
<FromGitter> <oprypin> πŸ‘
HumanG33k has joined #crystal-lang
<kevinsjoberg> oprypin: got some feedback that it would not work for all cases, if you for instance gave them an abs path that was not relative to the project.
<kevinsjoberg> or cwd, more precisely.
<oprypin> then make it work, i guess? right now as it is there's 0 effect from your PR
<oprypin> i forgot that relative_to is useless
<kevinsjoberg> It's working properly right now, I'm just addressing some other points that was brought up. :)
<oprypin> i have no idea how it can work
<oprypin> so i guess absolute includes work after all?
<oprypin> no, it definitely doesn't work
<kevinsjoberg> oprypin: before it was always prefixed with "./".
<kevinsjoberg> No we only prefix non-absolute path with that.
<kevinsjoberg> And tests still passing for absolute and relative paths
<oprypin> no wait, relative_to does work
<kevinsjoberg> oprypin: You're right though, it did fail now, after the latest changes I did from the suggestions. Nice catch! :)
<kevinsjoberg> I've reverted my changes to the original implementation, I'll address the comments on GitHub as well.
<FromGitter> <Blacksmoke16> so i had a thought of adding a new `undefined` type
<FromGitter> <Blacksmoke16> to solve this problem
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/9zgp
<FromGitter> <Blacksmoke16> not really a "problem" but just annoying
<FromGitter> <Blacksmoke16> i.e. that you have to define the same defaults for overloads
<FromGitter> <Blacksmoke16> versus `message : String = undefined`, which would be equivalent as if it wasn't passed at all
<erdnaxeli> are keys in hash ordered? I need to give a hash to a method and rely on the keys order.
<erdnaxeli> it seems so: https://crystal-lang.org/api/0.35.1/Hash.html#key_index(key)-instance-method
<straight-shoota> yes, kv-pars in Hash are insertion ordered
postmodern has joined #crystal-lang
<postmodern> how do shards define their own additional build steps? like what if a shard needs to also compile some additional C code that gets embedded into the final output?
<FromGitter> <Blacksmoke16> which could call like `make build` or whatever
hightower4 has joined #crystal-lang
<FromGitter> <franciscoadasme> hey everyone, having a generic module `Foo(T)`, is there a way to get the includers for a specific concrete type, let say, only those that include `Foo(String)`?
* raz scratches head
<raz> but why?
<FromGitter> <Blacksmoke16> try against master
hightower4 has quit [Ping timeout: 246 seconds]
<raz> are consts just slow in 0.35.1?
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang/crystal/pull/9801 maybe related?
<raz> kk cool. it doesn't really matter for my use-case, was just surprised. expected either the opposite or no diff, but not this ;)
<raz> errr...
<raz> looks like Regex.new is just a bad idea
<FromGitter> <Blacksmoke16> :shrug:
<postmodern> Blacksmoke16, cool. Does the postinstall command(s) get executed by all shards that are pulled in before compiling the main project targets?
<FromGitter> <Blacksmoke16> After that shard has been installed
<straight-shoota> raz, regex literals are cached
<raz> ah, gtk