ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.32.1 | 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
ua has quit [Ping timeout: 260 seconds]
repo has quit [Ping timeout: 260 seconds]
repo has joined #crystal-lang
ua has joined #crystal-lang
<FromGitter> <Daniel-Worrall> ```class Foo ⏎ @bar = Hash.new(String, String) ⏎ end``` ⏎ ⏎ How is this not inferred??? [https://gitter.im/crystal-lang/crystal?at=5e337cdf1594133558431017]
<FromGitter> <Blacksmoke16> `Hash(String, String).new`?
<FromGitter> <Daniel-Worrall> I'm
<FromGitter> <Blacksmoke16> :p
<FromGitter> <Daniel-Worrall> I mean, yes, that was my problem in my playground example I tried to reduce it to. Turns out I was trying Foo::Bar::Baz when my object is just Foo::Baz
<FromGitter> <Blacksmoke16> ah that would do it
<FromGitter> <Daniel-Worrall> Could it be a more specific error message perhaps
<FromGitter> <Daniel-Worrall> like undefined contstant
<FromGitter> <Daniel-Worrall> constant
<FromGitter> <Blacksmoke16> :shrug: maybe?
<FromGitter> <eliasjpr> Is there a way to set the timeout limit for all threads
<FromGitter> <tenebrousedge> you could maybe override Thread#start
<FromGitter> <tenebrousedge> but that sounds like a bad idea
<FromGitter> <watzon> Definitely a bad idea
sagax has joined #crystal-lang
<FromGitter> <tenebrousedge> @watzon got a better one?
<FromGitter> <confact> How do i add headers to response? I get undefined method on Hash, tried with `headers[] =` and `headers.add()`
<FromGitter> <tenebrousedge> strangely that seems not to be a thing
<FromGitter> <tenebrousedge> wait
<FromGitter> <tenebrousedge> no, getter should expose the hash
<FromGitter> <tenebrousedge> what exactly did you try?
<FromGitter> <grkek> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e33cca1dc52c34ace34e599]
<FromGitter> <grkek> this is how I do it
<FromGitter> <confact> I want to set it, so I guess that is the issue
<FromGitter> <grkek> req being the `HTTP::Server::Context`
<FromGitter> <tenebrousedge> you want to merge the existing one
<FromGitter> <tenebrousedge> you can't set the property directly
<FromGitter> <grkek> using merge is really handy
<FromGitter> <confact> Ah, so merge will work? I have to do a macro like @grkek ?
<FromGitter> <grkek> headers({"Content-Type" => "application/json"})
<FromGitter> <grkek> ```headers({"Content-Type" => "application/json"})```
<FromGitter> <grkek> keep in mind that is in context of my framework
<FromGitter> <grkek> you would have to replace the `req`
<FromGitter> <grkek> with your `HTTP::Server::Context` instance
<FromGitter> <tenebrousedge> macros aren't necessary
<FromGitter> <grkek> > macros aren't necessary
<FromGitter> <grkek> it looks a lot more cleaner
<FromGitter> <confact> What can I do instead?
<FromGitter> <confact> What is the alternative?
<FromGitter> <tenebrousedge> use `merge!` with a hash argument
<FromGitter> <grkek> @confact `YOUR_CONTEXT_HERE.response.headers.merge!({"a-header" => "b-content"})`
<FromGitter> <grkek> ```context.response.headers.merge!({"Content-Type" => "application-json"})``` ⏎ ⏎ The macro above simply converts to that [https://gitter.im/crystal-lang/crystal?at=5e33cdc3dc52c34ace34e9fe]
<FromGitter> <confact> Ah, make sense. Classic !-method. Too early in the morning to think ^^
<FromGitter> <tenebrousedge> in which case you could use a constant instead of a macro
<FromGitter> <grkek> Constant ? what do you mean ?
<FromGitter> <tenebrousedge> ```ADDITIONAL_HEADERS = {"Content-Type" => "application/json"}```
<FromGitter> <grkek> Oh but why
<FromGitter> <confact> Yea, for some headers it will make sense. But others not.
<FromGitter> <tenebrousedge> because using macros for static content is not necessary
<FromGitter> <grkek> I mean what if I want to add more headers
<FromGitter> <grkek> customize something
<FromGitter> <grkek> instantly
<FromGitter> <confact> Most of my headers are not static, they change depending on paths and method
<FromGitter> <grkek> > See ^ that is what I mean
<FromGitter> <tenebrousedge> if you can use a constant, use a constant. If you can't use a constant, but you can set the headers at compile-time, use a macro. If you need to set them at runtime, use a normal hash
<FromGitter> <confact> Normal hash then ;)
<FromGitter> <grkek> Still
<FromGitter> <grkek> with a macro it will look better
<FromGitter> <grkek> and you would get the same code before
<FromGitter> <grkek> instead of writing something like
<FromGitter> <grkek> `req.response.headers.merge!({"a" => evaluatedValue})`
<FromGitter> <grkek> you write
<FromGitter> <grkek> `headers({"a" => evaluatedValue})`
<FromGitter> <grkek> which is literally the same
<FromGitter> <tenebrousedge> I'm glad it works that way in your framework
<FromGitter> <grkek> 😆
<FromGitter> <grkek> I am not trying to shill my framework
<FromGitter> <grkek> it just looks good and more readable
<FromGitter> <grkek> sorry if I offended or anything @tenebrousedge
<FromGitter> <tenebrousedge> I admit to having rolled my eyes a little bit, but there's nothing wrong with things working that way in your framework. It makes sense and it's convenient
<FromGitter> <tenebrousedge> I might even go for `headers('a', 'value')`
<FromGitter> <grkek> I had that but since it would be cumbersome to use with multiple headers I went with the hash merge
<FromGitter> <tenebrousedge> well, you could do both, no?
<FromGitter> <grkek> I might be known for shilling but still its just an act of social interaction where I try to share something I found exciting :)
<FromGitter> <grkek> Yes I could do both I even had it before I removed it
<FromGitter> <grkek> `req.response.headers[{{header}}] = {{value}}`
<FromGitter> <grkek> this does the job
<FromGitter> <tenebrousedge> you're well within the bounds of politeness as far as self-promotion goes, in my opinion
<FromGitter> <tenebrousedge> but, I'mma sleep 👋
<FromGitter> <grkek> Good night mate ❤️
_whitelogger has joined #crystal-lang
alex`` has quit [Ping timeout: 265 seconds]
f1refly has joined #crystal-lang
alex`` has joined #crystal-lang
alexherbo2 has joined #crystal-lang
<alex``> hi
<alex``> it is not purely related to crystal but I want to convert my dotfiles/bin ruby scripts to crystal. but now I have to compile I cannot store them in bin. do you have a suggestion where to store, and if using shards or just crystal to build them?
<alex``> I thought to dotfiles/src/<file>.cr, but when compiling they will be stored in bin/ using shards
<alex``> maybe dotfiles/src/crystal/src/<file>.cr to have the bin in dotfiles/src/crystal/bin and gitignore
<alex``> is there a way to specify in shards.yml the src/ and bin/ paths?
<repo> not that i know of
<repo> but you could also try if crenv works for you
<repo> sorry not cren
<repo> crenv
<repo> what was it again
<repo> crun
<repo> alex``: ^
<alex``> repo: how does it work?
<repo> like any env i guess.
<alex``> it does `crystal eval`?, or `crystal build` and compile the first time, and run the compiled after
<repo> yeah it caches the bins
<alex``> how updates are handled
<alex``> does it still very speed?
<repo> well it notices the file has changed and compiles it again
<repo> the first time you run it (and after changes) it's obviously slow
f1refly has quit [Ping timeout: 272 seconds]
<raz> hm. i agree with most of what straight shoota does, but shardbox is a mistake
<raz> it will only ever contain an outdated subset of available shards and mislead esp. newcomers to crystal
<raz> does he hang out here so i can scold him?
* raz grumpy face
<FromGitter> <Blacksmoke16> @confact you dont have to use `merge!` just to add a single header
<FromGitter> <Blacksmoke16> `ctx.response.headers["foo"] = "bar"` should work fine
<repo> what's shardbox?
<FromGitter> <confact> @Blacksmoke16 it complains on that actually. Undefined method. `[]=`
<raz> repo: exactly!
<repo> raz: :D
<raz> i think it's a nice idea but the way it presents itself at the moment is a problem
<raz> it covers only 10% of the available shards. so if someone new to crystal stumbles on it via google, they may think that's all we have :(
<repo> why does it cover only 10% of the available shards?
<raz> i think it's a manual catalog. your shard only appears if you add it with a github PR, or if it's mentioned as a dep in another shard
<repo> oh wow
<repo> yeah
<repo> not one of mine is there
<repo> well, one is
<repo> with my old github username
return0__ has joined #crystal-lang
return0e_ has quit [Ping timeout: 265 seconds]
<FromGitter> <Blacksmoke16> @confact got some example code that reproduces it?
<FromGitter> <Blacksmoke16> because i use the same syntax and its fine
<FromGitter> <Blacksmoke16> fwiw a header value can only be a string so it'll fail if its not
<repo> raz: i wonder why it didn't scrape the github api to include all current shards
<repo> *he
<repo> s/scrape/use/
<raz> dunno, but agree, manual curation seems like a questionable approach
<repo> at least as long as there's no builtin helper
<raz> yup, i mean the only problem with https://crystalshards.xyz seems to be that it only(?) covers github
<repo> yeah and the search sucks ass
<raz> would rather extend that to cover other hosts as well, it's not like there are many of them (gitlab and... hm... is there even another one? ;))
<repo> but tbh i find shards like this in duckduckgo: !gh language:crystal thing i need
<raz> yeh the search could be better, but as long as the shard name or desc contains a reasonable keyword i usually find what i need
<raz> i think the important bit is that shards show up w/o the authors having to do anything extra
<repo> well they don't with rubygems either
<repo> but otoh bundler uses rubygems
<raz> yeh but rubygems is centralized. which i don't consider a big problem per se.
<raz> but decentralized is nicer
<repo> agreed
<raz> all things considered crystal looks very good on the pkg mgmt front anyway
<raz> i mean just look at the trainwrecks that python and js are still stuck with :D
<repo> i also don't like that shardbox uses categories
<repo> tags would be much more flexible
<raz> agree... but both are doomed to never fit right
<raz> ppl will invent different tags for the same things, disagree on which category something belongs, etc.
<repo> true
duane has quit [Ping timeout: 240 seconds]
return0__ has quit [Read error: Connection reset by peer]
return0e_ has joined #crystal-lang
<FromGitter> <confact> How can I send a http request body to a Proccess? I am doing this now: `Process.run(command, shell: true, input: @context.request.body, output: @context.response)`
<FromGitter> <Blacksmoke16> is it not working?
<FromGitter> <Blacksmoke16> prob should also send error output to the response io
<FromGitter> <confact> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e3437e7fe0e6f74e9f1a21b]
<FromGitter> <confact> I guess request.body can be nil?
<FromGitter> <Blacksmoke16> yes
<FromGitter> <Blacksmoke16> so would prob not want to run the process if its not, or raise an error or whatever makes sense in the context of your app
duane has joined #crystal-lang
<alex``> How to define a class for
<FromGitter> <confact> @Blacksmoke16 made it worked. :D
<alex``> Hash(String, Array(String)).from_yaml(string)
<alex``> I would like
<FromGitter> <confact> I can now push, fetch and pull my git repo from my crystal http server! :D
<alex``> Passwords.from_yaml(string)
<alex``> but YAML.mapping receives named arguments
<FromGitter> <Blacksmoke16> `alias Passwords = Hash(String, Array(String))`
<alex``> what is alias :O
<FromGitter> <Blacksmoke16> dont do recursive types tho
<alex``> it's only for types then?
<FromGitter> <Blacksmoke16> yes
<alex``> cool
<alex``> I was unsure of the alias usage
<alex``> it's for named types then
<FromGitter> <Blacksmoke16> it just allows you to reference another type
<alex``> it could be nice to add this example alongise JSON / Hash api doc
<FromGitter> <Blacksmoke16> like `alias Foo = Namespace::SomeModule::Classes::Foo`
<alex``> alongside JSON/YAML.mapping
<alex``> I wonder what do you think of Algolia, to have a browser extension to search the documentation
<alex``> directly in the search bar
return0__ has joined #crystal-lang
return0e_ has quit [Ping timeout: 268 seconds]
return0__ has quit [Read error: Connection reset by peer]
return0e_ has joined #crystal-lang
duane has quit [Ping timeout: 248 seconds]
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
alex`` has quit [Quit: WeeChat 2.7]
duane has joined #crystal-lang
<FromGitter> <trejkaz> I don't suppose there is a cucumber-like tool for crystal?
<FromGitter> <tenebrousedge> I don't think so. I'd help write one
<FromGitter> <trejkaz> I think I could probably do it ... the actual goal is to do the ray tracer challenge but it wouldn't be the first time I had to shave a giant yak before even writing one line of code
<FromGitter> <tenebrousedge> I'm sure you're quite capable. I'm somewhat at loose ends at the moment
<FromGitter> <trejkaz> oh?
<FromGitter> <tenebrousedge> I have a side project, but it's got to the point of needing a bunch of JS work, and I'm not thrilled about continuing it. Also, I'd like to contribute a shard to Crystal
<FromGitter> <trejkaz> hmm web stuff ..
<FromGitter> <trejkaz> or perhaps not, these days
<FromGitter> <trejkaz> my main project is stalled for a month or so because I have to wait for collaborators to free up some time
<FromGitter> <trejkaz> I see someone has *started* a microcuke port...
<FromGitter> <j8r> I'm seeking a "Crystal web dev" to hire, PM me if interested 😉
<FromGitter> <j8r> More web dev, with Crystal knowledge
return0e_ has quit [Read error: Connection reset by peer]
return0e_ has joined #crystal-lang
<FromGitter> <elorest> @j8r I might know a couple people. Remote?
<FromGitter> <j8r> Yes @elorest , thanks :)
<FromGitter> <elorest> @faustinoaq would be a great option if he's open.
<FromGitter> <j8r> The project is https://github.com/DFabric/dppm-rest-api
<FromGitter> <elorest> He wrote much of the amberframework.com website which is html/js on top of amber/crystal.
<FromGitter> <j8r> This is the API, a good part is done but there is still work. I can work a bit on it. ⏎ What's remaining is a web frontend
<FromGitter> <elorest> I've asked this question before but is there any good way to read/write from COM ports in crystal. We're setting the baud rate and other params and then opening it as a File. This sort of works but it's not a blocking call so it just waits forever instead of yielding to other fibers like udp, tcp, socket etc.
<FromGitter> <elorest> @j8r when you say frontend you mean like react or just html/css?
<FromGitter> <j8r> @elorest I would prefer a modern frontend for the API
<FromGitter> <j8r> since it's a new project, I am quite open on the technology
<FromGitter> <elorest> Ok. I was just thinking if the api's are pretty much written you could almost just find any dev camp kid who is good at react and has maybe touched ruby and they could probably do a decent job.
<FromGitter> <elorest> @j8r Do you have any suggestions on my Serial/COM port question?
<FromGitter> <confact> @grkek here is the grack for crystal that kinda works: https://github.com/confact/grack.cr
<FromGitter> <confact> @Blacksmoke16 used a lot of yours input in that repo. thanks for the help.
<FromGitter> <elorest> How does blocking on crystal gets actually work when it does? Is it essentially check if there's anything new and then `sleep x`?
<FromGitter> <Blacksmoke16> 👍
alex` has joined #crystal-lang
alex` is now known as Guest88106
_ht has joined #crystal-lang
alexherbo2 has joined #crystal-lang
f1refly has joined #crystal-lang
f1refly has quit [Ping timeout: 268 seconds]
Guest88106 is now known as alex``
<alex``> how to keep alnum, digit, etc.?
<alex``> with tr, I can do `tr -c -d "[:$1:]"`, where `$1` can be a character class, like `alnum`
<FromGitter> <tenebrousedge> Crystal has `tr`
<FromGitter> <tenebrousedge> also `gsub` and `delete` and `scan`
<alex``> tr receives a string literal
<alex``> so I guess it will not work
<FromGitter> <Blacksmoke16> hm?
<alex``> then gsub with a regex?
<FromGitter> <tenebrousedge> Crystal supports POSIX extensions for regexes
<alex``> string.gsub(/[^[:alnum]]/, '')
<FromGitter> <tenebrousedge> e.g. `:alnum:`
<FromGitter> <tenebrousedge> `[^[:alnum:]]`
<alex``> yes, but gsub is the best method?
<alex``> or tr, delete could be used
<FromGitter> <tenebrousedge> I'd probably do `delete("^a-zA-Z0-9")`
<FromGitter> <Blacksmoke16> whats the goal?
<FromGitter> <Blacksmoke16> delete all char/numeric values?
<alex``> the use case is to create a tiny program to filter non alphanumeric character
<alex``> to generate a password and pipe to that, for sites that don't allow other than alphanum
<alex``> make-password alex github.com
<alex``> make-password alex github.com | alnum | wl-copy
<alex``> something like that
<FromGitter> <Blacksmoke16> gotcha
<bougyman> opr gen --no-chars
<bougyman> oDWcypusgTOR69
<bougyman> take a look at opr. it's in ruby but the tool does the needful.
<FromGitter> <Blacksmoke16> `"Fa23--#28F".gsub /[^a-zA-Z\d]/, "" ⏎ `
<FromGitter> <Blacksmoke16> `String#delete` doesnt take `Regex` :/
<FromGitter> <tenebrousedge> but it does take character ranges
<FromGitter> <Blacksmoke16> does it?
<FromGitter> <tenebrousedge> `delete("^a-zA-Z0-9")`
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/String.html#delete(*sets)-instance-method oh
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <tenebrousedge> but I'd probably do `(0..rand(8,20)).join(&->ALLOWED_CHARS.sample)`
<bougyman> that's similar to what I do in opr, tenebousedge
f1refly has joined #crystal-lang
<alex``> if I have src/program1.cr and src/program2.cr, what is the best way to require configuration (like the config file path)?, should the file be in src/ or lib/?
<FromGitter> <kinxer> @alex`` Are you you talking about compile-time configuration in a non-Crystal file or a Crystal configuration file with things like an OptionParser?
<FromGitter> <tenebrousedge> for compile-time stuff you could stick something in a /config directory
<alex``> src/program1 and src/program2 will use XDG_CONFIG_HOME/program/config.yml for config, I want kinda share variables accross the 2 programs
<alex``> instead of repeating the get config path
<alex``> I hesitate also between the approach of sub-command
<alex``> in a single program
<alex``> not sure the best way to handle that
<alex``> or if it's simpler to just separate into different program
<alex``> there is a builtin way to create command-line program with sub commands
duane has quit [Ping timeout: 268 seconds]
ur5us has joined #crystal-lang
ur5us has quit [Quit: Leaving]
duane has joined #crystal-lang
duane has quit [Ping timeout: 272 seconds]
_ht has quit [Ping timeout: 252 seconds]
_ht has joined #crystal-lang
<FromGitter> <dscottboggs_gitlab> Is there any reason why calling a type doesn't call it's `new` classmethod like Pony's `new create`? ⏎ ⏎ A Constant could be either a type or a proc, in both cases it makes sense to me (although maybe I'm wrong, which is why I'm asking) to have syntax available so all the following examples would be equivalent ⏎ ⏎ ```Complex.new(0, 1) ⏎ Complex.new 0, imag: 1 ⏎ Complex(real: 0, imag: 1)
<FromGitter> <tenebrousedge> I think you can do that, but it's not done automatically for most types
<FromGitter> <tenebrousedge> e.g. `Hash(Int32, String|Int32){1 => 1}`
<FromGitter> <dscottboggs_gitlab> that's a generic type with a `macro {}` defined on it. I'm checking now to see if you can define `macro ()`
<FromGitter> <dscottboggs_gitlab> https://carc.in/#/r/8hls nope
<FromGitter> <dscottboggs_gitlab> In fact, I don't see how `Set{}` is implemented, I'm thinking it may be compiler magic
<FromGitter> <dscottboggs_gitlab> this works, but not really what I was talking about https://carc.in/#/r/8hlv
<alex``> how to strip string indent begin?
<FromGitter> <dscottboggs_gitlab> in a literal or received string?
<alex``> maybe <<~EOF I'm looking for
<alex``> it's for a docstring
<FromGitter> <tenebrousedge> that works, yeah
<FromGitter> <dscottboggs_gitlab> what's `<<~`? I thought `<<-` did that?
<alex``> where is the doc for <<~?
<alex``> I try to search in api/
<FromGitter> <tenebrousedge> near the bottom, "heredoc"
<FromGitter> <ezrast_gitlab> @dscottboggs_gitlab Pretty sure `Set{a, b}` is compiler magic; it's roughly syntactic sugar for `Set.new.tap{ |obj| obj << a; obj << b}` (as in, define `<<` and you get `{}` for free)
<FromGitter> <straight-shoota> @ezrast_gitlab correct
<FromGitter> <dscottboggs_gitlab> yeah. makes sense. Just...not what I was talking about haha
_ht has quit [Remote host closed the connection]
_ht has joined #crystal-lang
<alex``> how to parse ARGV to typed arguments?
<alex``> I want to pass make(key, password = get("master"), length = 10)
<FromGitter> <tenebrousedge> did you look at this? https://crystal-lang.org/api/latest/OptionParser.html
<alex``> it's not an option but arguments
<FromGitter> <dscottboggs_gitlab> you need to manually convert to the appropriate type
<alex``> :(
<alex``> key, password, length = ARGV[0], ARG[1], ARGV[2].to_i ?
<FromGitter> <tenebrousedge> hmm. Maybe I should try writing `scanf` again
<FromGitter> <lbarasti> Has anyone had any luck in passing generics types to macros? ⏎ ⏎ `````` [https://gitter.im/crystal-lang/crystal?at=5e34b98015941335584b753c]
<FromGitter> <tenebrousedge> do you need to use `record`, or can you define a struct manually?
<FromGitter> <lbarasti> it's a minimal example I came up with, defining the struct manually would look quite bloated, not using any macro
<FromGitter> <lbarasti> something like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e34baf958f02e349756c1ea]
oprypin has quit [Quit: Bye]
oprypin has joined #crystal-lang
<FromGitter> <lbarasti> Thanks @tenebrousedge! I was looking for an open issue and I completely missed THE ONE :D
<FromGitter> <tenebrousedge> you're welcome, sorry it's not more useful
<FromGitter> <lbarasti> I mean, there is hardly a better answer at this point, so much appreciated