<FromGitter>
<Blacksmoke16> add the worker as a target to your shard.yml, then use the same base docker image as you do for your webapp (i.e. that has crystal and stuff) but just uses a diff command
<FromGitter>
<tenebrousedge> π
<FromGitter>
<nsuchy> I can run multiple files?
<FromGitter>
<nsuchy> can you show an example?
<FromGitter>
<nsuchy> assume the worker is named worker.cr
<FromGitter>
<tenebrousedge> you can always use `reduce` in some way. It can be used to write all other higher-order iterators
<FromGitter>
<tenebrousedge> but sometimes it ain't pretty
<FromGitter>
<Blacksmoke16> dont actually need the `|| 0`
<FromGitter>
<Blacksmoke16> but i just realized thats not what you want
<dwdv_>
Hm, this might be a good candidate for a PR, right? Want would you call it? Rust and haskell go with `scan`, others call it `cumulativeFold/-sum`.
<FromGitter>
<Blacksmoke16> `arr..map_with_index { |v, idx| v + arr[0...idx].sum }`
<FromGitter>
<Blacksmoke16> what about that? :p
<FromGitter>
<tenebrousedge> I think a `cumulativeFold` wouldn't necessarily go amiss. What would you implementation be?
<FromGitter>
<Blacksmoke16> id make an issue first
<FromGitter>
<tenebrousedge> if you want an infinite list, I would write an `Iterator`
<FromGitter>
<Blacksmoke16> `1..Int64::MAX`
<dwdv_>
I settled on a sum var even though you hate it, rather clean. ;)
<FromGitter>
<Blacksmoke16> er well i guess thats not infinite
<FromGitter>
<Blacksmoke16> dont mind me imma go back to eating my π
<FromGitter>
<tenebrousedge> I don't mind sum vars. I think `each` should only be used when there are no alternatives
<dwdv_>
Sum var holds the intermediate sum, Blacksmoke16.
<dwdv_>
ALright, thanks for your time you two.
<FromGitter>
<tenebrousedge> dwdv have you done more exercisms?
<dwdv_>
Not yet, doing AoC18 atm. Maybe tomorrow. Is your mentoring queue empty? :)
<FromGitter>
<tenebrousedge> it usually is
<FromGitter>
<tenebrousedge> someone submitted ten at once yesterday, kept me busy for a whole half hour
<dwdv_>
Via mentoring requests?
<FromGitter>
<tenebrousedge> yes
cpt_yossarian has quit [Ping timeout: 265 seconds]
woodruffw has joined #crystal-lang
dwdv_ has quit [Ping timeout: 240 seconds]
f1refly has joined #crystal-lang
f1reflyylmao has quit [Ping timeout: 240 seconds]
chemist69 has quit [Ping timeout: 276 seconds]
chemist69 has joined #crystal-lang
DTZUZU has quit [Quit: WeeChat 2.2]
DTZUZU has joined #crystal-lang
DTZUZO_ has quit [Quit: WeeChat 2.0]
DTZUZO has joined #crystal-lang
absolutejam4 has joined #crystal-lang
ht_ has joined #crystal-lang
<FromGitter>
<andrius> Say we have an app, that listening on TCP socket or whatever and trigger some action based on certain events. Like `on_ping`, `on_connect`, whatever... When and why you will call it a hooks, callbacks or observers? ;)
<FromGitter>
<andrius> It is more about style. My app does use a lot of individual event handlers
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Remote host closed the connection]
absolutejam4 has quit [Ping timeout: 250 seconds]
absolutejam4 has joined #crystal-lang
ht_ has quit [Quit: ht_]
absolutejam4 has quit [Ping timeout: 265 seconds]
absolutejam4 has joined #crystal-lang
<FromGitter>
<mavu> morning, how do I disable certificate checking in a http/client?
<FromGitter>
<sam0x17> I'm getting this on alpine with crystal 0.31.0 and 0.31.1 (doesn't happen in previous versions): β β ```code paste, see link``` β β When I ld each of those, it just warns that symbol_entry cannot be found. openssl-dev, etc, are all installed. What should I try? [https://gitter.im/crystal-lang/crystal?at=5d9f014d37073b36a0a229f9]
<FromGitter>
<sam0x17> aha I got it!! seems like alpine has made some changes and separated out some packages into distinct -static versions, so the following dockerfile worked: β β ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d9f064a97358746732b03c1]
_whitelogger has joined #crystal-lang
hypercore has quit [Remote host closed the connection]
user2 has joined #crystal-lang
<FromGitter>
<asterite> dwdv_ please create an issue for cumulative fold, we can probably add cumulative reduce. It's not the first time someone asks for it, and it seems pretty straightforward to implement :)
<dwdv_>
How about cumulativeSum/Product helpers in the spirit of enumerable#sum/product?
user2 has quit [Ping timeout: 260 seconds]
<FromGitter>
<yxhuvud> isn't reduce already cumulative? That is sortof the point of it, no?
<FromGitter>
<ilanpillemer> could scratch work as well as alpine?
<FromGitter>
<Daniel-Worrall> Once you have a static binary, yeah
user2 has quit [Ping timeout: 260 seconds]
user2 has joined #crystal-lang
alex`` has joined #crystal-lang
alex`` has quit [Ping timeout: 240 seconds]
alex`` has joined #crystal-lang
masterdonx2 has joined #crystal-lang
MasterdonX has quit [Ping timeout: 240 seconds]
alex`` has quit [Ping timeout: 265 seconds]
alex`` has joined #crystal-lang
user2 has quit [Ping timeout: 260 seconds]
<FromGitter>
<repromancer_gitlab> looking for help with compiler error beautification
<FromGitter>
<repromancer_gitlab> I've written up an example with a spec to sort of describe my goal (this compiles and runs successfully): https://play.crystal-lang.org/#/r/7rfz
<FromGitter>
<repromancer_gitlab> If I pass the wrong number of arguments to an OrderRequest, I get a pretty informative message which points out the location of the error: https://play.crystal-lang.org/#/r/7rg4
<FromGitter>
<repromancer_gitlab> However, passing in the wrong type for one argument gives an error pointing to the abstract class definition, not the location of the mistake: https://play.crystal-lang.org/#/r/7rg9
<FromGitter>
<repromancer_gitlab> If I move the type annotations from the `property` statements to the initializer, I again get a better error pointing to the actual mistake: https://play.crystal-lang.org/#/r/7rgo
<FromGitter>
<tenebrousedge> that seems correct to me
<FromGitter>
<repromancer_gitlab> Right. My only gripe now is that this error says that the `data` argument must be of type `T`, not `Order`.
Human_G33k has joined #crystal-lang
<FromGitter>
<tenebrousedge> because that's how it's defined
<FromGitter>
<repromancer_gitlab> I wish I could get an error in between the first (non-informative regarding where the error is, but tells exactly which type is required) and the last (points out the location, but you have to go looking for what the type should actually be)
Human_G33k has quit [Remote host closed the connection]
Human_G33k has joined #crystal-lang
<FromGitter>
<tenebrousedge> it's like that because you could define another initializer as `initialize(data : Order, time : Timestamp)`
<FromGitter>
<repromancer_gitlab> it feels like I may have to write a macro which expands to a non-generic class definition in order to achieve this
<FromGitter>
<tenebrousedge> it's pointing to the actual implementation. It can't do otherwise
<FromGitter>
<tenebrousedge> you could use a macro, certainly
HumanG33k has quit [Ping timeout: 268 seconds]
<FromGitter>
<r00ster91> How does this work? https://carc.in/#/r/7ri4 β Is `hello` copied before it's being iterated through?
<FromGitter>
<tenebrousedge> blocks create a new scope
<FromGitter>
<tenebrousedge> you're creating a local variable inside the loop which is nil, shadowing the outer variable
<FromGitter>
<r00ster91> oh, right yeah
<FromGitter>
<r00ster91> although when printing the variable outside then it is `nil` which makes it seem like that it did actually modify the existing variable instead of creating a new one: https://carc.in/#/r/7rib
<FromGitter>
<tenebrousedge> hmm. So let's look at the `each_char` source then
<FromGitter>
<r00ster91> I guess when the method finished then the state of the `hello` in the new scope is translated over to the old `hello`
<FromGitter>
<tenebrousedge> no, it's calling `to_slice` internally
<FromGitter>
<r00ster91> ah so it is actually making a copy
<FromGitter>
<tenebrousedge> looks like it
<FromGitter>
<tenebrousedge> and for non-ascii strings it uses a reader
<FromGitter>
<tenebrousedge> which I guess means that it traverses the entire string and makes a copy before iteration begins
<FromGitter>
<r00ster91> well the `to_slice` doesn't really mean anything actually: https://carc.in/#/r/7rjk β the same thing happens without a `to_slice`
<FromGitter>
<tenebrousedge> ...huh
<FromGitter>
<r00ster91> I think it's related to that internally when the function is called, the arguments are pushed to a stack
<FromGitter>
<r00ster91> or maybe the compiler simply prevents the `string = nil` silenty
* FromGitter
* tenebrousedge pokes it with a stick
<erdnaxeli>
but the final print shows that 'string = nil'
<FromGitter>
<r00ster91> it's probably doing the `string = nil` when the method finishes
<FromGitter>
<r00ster91> wait nevermind
<FromGitter>
<r00ster91> I think it's really creating a new variable but then passing the state of the new variable back to the old variable
<FromGitter>
<tenebrousedge> that would be weird
<FromGitter>
<r00ster91> ..at the end
<FromGitter>
<r00ster91> weird? why?
<FromGitter>
<r00ster91> that would probably be the smartest way to do it
<repo>
i think i've asked about this already but maybe there's been some development on the matter: running a crystal program inside docker ignores any signint
<FromGitter>
<wontruefree> I ahve been trying to run the crystal debugger in vscode
<FromGitter>
<wontruefree> it is really hard to get it all to work on OSX
<FromGitter>
<wontruefree> has anyone else gotten it to work
<repo>
if you add Signal::INT.trap { exit } to your code manually it will work
<FromGitter>
<Daniel-Worrall> I feel like I've run into that before repo
<FromGitter>
<Daniel-Worrall> Which Docker
<repo>
?
<repo>
version?
<FromGitter>
<Daniel-Worrall> OS
<repo>
Docker version 19.03.2-ce, build 6a30dfca03
<FromGitter>
<Daniel-Worrall> Since Windows and *nix work very different in docker engining
<repo>
arch
<repo>
(linux)
<repo>
it's very easy to reproduce
<FromGitter>
<Daniel-Worrall> Oh wait I think I reproduced it
<FromGitter>
<Daniel-Worrall> `Content-Length header is 207 but body had 0 bytes`
<FromGitter>
<Daniel-Worrall> oh wait
<repo>
also there's some other weirdness with docker
<repo>
stdout and stderr not being flushed
<FromGitter>
<tenebrousedge> there might be an issue related to that
<FromGitter>
<Daniel-Worrall> I'm confused, this wasn't happening a couple weeks ago
<FromGitter>
<Daniel-Worrall> and I don't think I changed anything
<FromGitter>
<tenebrousedge> your openssl version may have changed
<FromGitter>
<tenebrousedge> they occasionally deprecate or remove ciphers
<FromGitter>
<tenebrousedge> docker would probably help you keep tabs on this sort of thing
<FromGitter>
<Daniel-Worrall> it's on docker tho
<FromGitter>
<tenebrousedge> so if you have an image from two weeks ago, check what openssl version it's using
<FromGitter>
<Daniel-Worrall> which is why I'm extra confused
<FromGitter>
<tenebrousedge> if necessary, pin it to a specific version
<FromGitter>
<Daniel-Worrall> Actually, I'm technically using alpine:latest
<FromGitter>
<Daniel-Worrall> so let's fix that
<FromGitter>
<Daniel-Worrall> But it happens on static builds
<FromGitter>
<tenebrousedge> did the openssl version change?
<FromGitter>
<Daniel-Worrall> I don't believe so
<FromGitter>
<j8r> @bararchy I think I did it, I submit a PR soon
ht__ has joined #crystal-lang
<FromGitter>
<kinxer> @ImAHopelessDev_gitlab Good morning.
<FromGitter>
<kinxer> @Blacksmoke16 Have you done anything with JSON schema in Crystal?
<FromGitter>
<Daniel-Worrall> It happened again.
<FromGitter>
<Daniel-Worrall> I didn't change anything and now it works
<FromGitter>
<kinxer> Y'all asked for magic, and lo!
<FromGitter>
<Blacksmoke16> not really no, not too familiar with it
<FromGitter>
<kinxer> Gotcha. It looks like quicktype (https://app.quicktype.io/#l=schema) has support for generating Crystal from a JSON schema.
<FromGitter>
<kinxer> It looks like JSON Schemas are used to validate json data, so I thought you might've come across it, since JSON validation is in your wheelhouse.
<FromGitter>
<Daniel-Worrall> I like the idea of JSON schemas, but I see so many applications violate them
<FromGitter>
<Daniel-Worrall> Damned lazy js devs
<FromGitter>
<Blacksmoke16> maybe something for the future
<FromGitter>
<ilanpillemer> SOAP required a schema.
<FromGitter>
<Blacksmoke16> currently the validation lib is generic enough that it shouldn't be tied to JSON
<FromGitter>
<kinxer> I've been looking at Rust for the first time recently... Am I remembering correctly that you and someone else (maybe \@j8r) were thinking of making a shard along the lines of Serde?
<FromGitter>
<kinxer> (Trying not to ping them, but I don't know if it worked...)
<FromGitter>
<Blacksmoke16> he has a gist of a prototype
<FromGitter>
<kinxer> It's an appealing idea, for sure.
<FromGitter>
<Blacksmoke16> my shard is still a WIP a bit, serialization side of things is pretty much complete, however it only supports JSON atm
<FromGitter>
<kinxer> @tenebrousedge No, I haven't. I've (thankfully) avoided javascript for the most part, since I don't do web work (and so have not used TypeScript).
<FromGitter>
<kinxer> I've actually never used an ORM.
<FromGitter>
<tenebrousedge> typescript is optional
<FromGitter>
<kinxer> Right, but it's for use in JavaScript or TypeScript, right?
<FromGitter>
<tenebrousedge> yes
<FromGitter>
<kinxer> The link to their docs is broken...
<FromGitter>
<tenebrousedge> yeah, I think they do have docs online somewhere
<FromGitter>
<kinxer> @Blacksmoke16 I think the docs aren't building right for some reason:
<FromGitter>
<Blacksmoke16> π¬
<FromGitter>
<Blacksmoke16> whats under them?
<FromGitter>
<Blacksmoke16> as i said its a WIP so prob just didnt do a doc pass on the deserialization stuff yet
<FromGitter>
<Blacksmoke16> i.e. add `:nodoc`
<FromGitter>
<tenebrousedge> but it's a neat project if you're working with a JS frontend and something vaguely like ActiveRecord on the backend
<FromGitter>
<kinxer> @tenebrousedge I'll keep that in mind. Thanks.
<FromGitter>
<kinxer> @Blacksmoke16 Lots of links to nonexistent pages (e.g. `CrSerializer::Annotations`).
<FromGitter>
<Blacksmoke16> really?
<FromGitter>
<Blacksmoke16> sec
<FromGitter>
<Blacksmoke16> i pushed a fix
<FromGitter>
<Blacksmoke16> at least makes it work :S
<FromGitter>
<Blacksmoke16> had a rouge `:nodoc:` on the modules that broke everything
<FromGitter>
<kinxer> I just used `sed` to get rid of all the `:nodoc:` :P
<FromGitter>
<kinxer> Your solution is probably better.
<FromGitter>
<Blacksmoke16> that works too
<FromGitter>
<kinxer> Your fix works. :)
<FromGitter>
<Blacksmoke16> π
<FromGitter>
<kinxer> So in order to define a serialization format you have to `include CrSerializer::Format` and implement some functions?
<FromGitter>
<Blacksmoke16> pretty much yea
<FromGitter>
<kinxer> That seems pretty straightforward.
<FromGitter>
<kinxer> Though I'm sure it's not exactly trivial.
<FromGitter>
<Blacksmoke16> look at the json one
<FromGitter>
<Blacksmoke16> basically just adding a bunch of methods to various types to support it
<FromGitter>
<Blacksmoke16> some of it might be reusable between formats tho, but for now been mainly going off of what the current JSON::Serializable did
<FromGitter>
<Blacksmoke16> the actual implementation of it is kept separate from the shard, i.e. all the annotations/exclusion strategies are used between all formats
<FromGitter>
<Blacksmoke16> from the format*
<FromGitter>
<Blacksmoke16> i.e. don't need `JSON::Field` and `YAML::Field`
<FromGitter>
<Blacksmoke16> `@[CRS::Name(serialize: "myAddress")]` would work for both
<FromGitter>
<kinxer> That's pretty cool.
<FromGitter>
<Blacksmoke16> the exclusion strategies are one of the cooler parts of it, as you can define custom ones
<repo>
Blacksmoke16: good point. will do
<FromGitter>
<Blacksmoke16> at work we use the PHP version that it was inspired from with some custom strats, where you can do `@IgnoreOnUpdate` on a property which will prevent that value from changing on PUT
<FromGitter>
<Blacksmoke16> but allows it to be set on POST
<repo>
hm although
<repo>
nah i'll rather leave it
<repo>
it's nicer to assign the trap procs with a block
<FromGitter>
<Blacksmoke16> fair enough
<FromGitter>
<kinxer> `CrSerializer::ExclusionStrategies::Version` is very cool.
<FromGitter>
<Blacksmoke16> also groups ^
<FromGitter>
<kinxer> Yeah. This is a really slick interface.
<FromGitter>
<Blacksmoke16> well yea, you should have 1 container for each service you want to run
<FromGitter>
<Blacksmoke16> i.e. web app, db, worker
<FromGitter>
<nsuchy> That leads me with Web App, Redis Cache, Redis Job Queue, Worker, we have a centralized database server for auditing purposes (not dockerized).
<FromGitter>
<nsuchy> just seems like a lot of containers
<FromGitter>
<lsymonds_gitlab> It's also worth noting that layers (basically each separate line in a Dockerfile) are also cached. So if you have `RUN apt update` in more than one Dockerfile (which you probably do), that layer will be cached and shared amongst all images.
<FromGitter>
<jwoertink> > undefined constant T
<FromGitter>
<jwoertink> My guess is because I'm calling the `go` method before it has a chance to define what `T` is
<FromGitter>
<jwoertink> but I'm not sure another way to write this
<FromGitter>
<tenebrousedge> does H need to be a class constant?
<FromGitter>
<tenebrousedge> can you maybe use a method instead?
<FromGitter>
<jwoertink> hmm... I think it makes most sense as either a constant or a class variable... but maybe I could do a class instead of a module, and then use an instance variable?
<FromGitter>
<tenebrousedge> it probably would make the most sense, but there's no way for T to exist when the macro is being expanded, as far as I know
<FromGitter>
<tenebrousedge> you could maybe write a bigger macro rather than using generics
<FromGitter>
<jwoertink> alright, did a little test, and that might work. Gonna give that a shot. Thanks!
<FromGitter>
<tenebrousedge> general web app question: so I wasn't planning on having an admin user role. Now I need a way for certain user actions to be approved. So I want to introduce an admin user system to do that, and I am thinking about using two separate models for this, and potentially later splitting this into its own app or micro-service. If anyone has any horror stories about a web app with two user models (not roles, but
<FromGitter>
... separate classes) then it would be great to hear about it before I do something potentially stupid
<FromGitter>
<jwoertink> @tenebrousedge I have an app that uses a `User` and a `Admin` as separate models with separate tables in the DB, and it works great for what I do. They log in to different systems though
<FromGitter>
<tenebrousedge> yes, I was thinking of insisting on 2FA for admins
<FromGitter>
<tenebrousedge> it's probably only going to be me for the forseeable future
<FromGitter>
<Blacksmoke16> why not just have an admin roel?
<FromGitter>
<Blacksmoke16> could always just add a column to the users table like `is_admin` :shrug:
<FromGitter>
<tenebrousedge> because the admin user has zero to do with the rest of the app
<FromGitter>
<Blacksmoke16> quick, simple
<FromGitter>
<tenebrousedge> approval is literally the only functionality planned, and I wouldn't even go that far if there was another way to do it
<FromGitter>
<tenebrousedge> hey, I need those fingers!
<FromGitter>
<tenebrousedge> dangit
<FromGitter>
<elorest> lol. It's not exactly pry but it has some of my favorite features of it.
<FromGitter>
<tenebrousedge> created by some guy named @elorest
<FromGitter>
<elorest> The ability to edit and execute code repeatably.
<FromGitter>
<tenebrousedge> I don't know if I can trust that sort of thing
<FromGitter>
<tenebrousedge> so how does it work?
<FromGitter>
<elorest> Rather well. You can also import include your application file if you want to use it like a console for Amber or probably lucky.
<FromGitter>
<tenebrousedge> ah, I mean mechanics rather than quality
<FromGitter>
<tenebrousedge> `icr` continually recompiles things
<FromGitter>
<elorest> Yes. In amber we were originally using ICR. This was a huge problem because if someone were to run `User.last.delete` as their first statement it would get called every time without the users knowledge.
<FromGitter>
<elorest> For every new line I mean.
<FromGitter>
<elorest> So we wrote Cry to bring up and editor and let you run commands against your code and run as soon as you exited.
<FromGitter>
<elorest> It also has a command to come back to the editor after it runs so you can modify it and go again.
<FromGitter>
<elorest> It's about the best case scenario I can think of for a compiled language.
<FromGitter>
<elorest> Plus the edit command is pretty much how I use Pry anyway.
<FromGitter>
<tenebrousedge> I use `pry` as a step-by-step debugger, with the ability to poke at any value in memory
<FromGitter>
<tenebrousedge> so in this case I would be following the execution of the query and making sure that values were hitting the query cache, or finding out why not by examining it between queries
MasterdonX has quit [Ping timeout: 240 seconds]
MasterdonX has joined #crystal-lang
return0e has quit [Remote host closed the connection]