ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.30.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
<FromGitter> <dscottboggs_gitlab> > dont think it should be in the std lib ⏎ ⏎ I don't see why not. I mean, I don't think YAML should be in stdlib anyway, but if it is why not all the features?
<FromGitter> <watzon> I was going to say the same thing
<FromGitter> <watzon> Might as well include as many libyaml features as we can
<FromGitter> <Blacksmoke16> well this isnt a libyaml feature
<FromGitter> <dscottboggs_gitlab> although there's no reason a shard couldn't extend the benefits the stdlib already provids
<FromGitter> <watzon> It'll probably get moved into its own shard anyway
<FromGitter> <watzon> > well this isnt a libyaml feature ⏎ ⏎ Oh it isn't?
<FromGitter> <Blacksmoke16> not natively
<FromGitter> <Blacksmoke16> prob easier to just not do the libYaml stuff
<FromGitter> <Blacksmoke16> and make it some class level hash
<FromGitter> <dscottboggs_gitlab> I don't get it
<FromGitter> <bew> Agree :) what are you working on @Blacksmoke16 ?
<FromGitter> <meltheadorable> do any of the crystal web frameworks have a good story for uploading files yet
<FromGitter> <Blacksmoke16> allowing to register handlers for custom tags
<FromGitter> <bew> Crap i didn't have all the messages ><
<FromGitter> <watzon> @meltheadorable not yet as far as I know. I want to create an ActiveStorage type library for Lucky
<FromGitter> <watzon> It's going to be the most likely framework to have something like that soon
<FromGitter> <dscottboggs_gitlab> @meltheadorable Kemal has a FileUploadHandler built in
<FromGitter> <meltheadorable> what about user registration
<FromGitter> <meltheadorable> & auth
<FromGitter> <watzon> @meltheadorable Lucky does have an Auth shard
<FromGitter> <dscottboggs_gitlab> https://github.com/dscottboggs/kemal-jwt-auth 😉
<FromGitter> <Blacksmoke16> making a JSON API? :P
<FromGitter> <Blacksmoke16> throw my hat in the ring
<FromGitter> <meltheadorable> not an api no
<FromGitter> <Blacksmoke16> rip
<FromGitter> <watzon> 😂
<FromGitter> <meltheadorable> not sure if im making anything, not without a really good solution for file uploads
<FromGitter> <watzon> Yeah that's a problem I'm having right now too
<FromGitter> <dscottboggs_gitlab> https://kemalcr.com/guide/#file-upload ⏎ ⏎ oof, I guess it doesn't have a FileUploadHandler
<FromGitter> <watzon> When I get some free time I'll probably start working on a LuckyStorage shard
<FromGitter> <meltheadorable> but i wanna divest myself from my dependence on imgur and a small-scale replacement without all the social features would be an achievable weekend project, trying to decide whether to do it in crystal, ruby, elixir, or not at all for a while longer
<FromGitter> <dscottboggs_gitlab> oh that's definitely doable in Kemal, Lucky, or Amber, I'm sure
<FromGitter> <meltheadorable> yeah but it’s less pleasantly doable in anything that doesn’t let me abstract away all the painful parts of file storage
<FromGitter> <meltheadorable> and preferably also hook into postprocessors
<FromGitter> <watzon> They all have the ability to store files, but none have anything on par with ActiveStorage yet
<FromGitter> <meltheadorable> yeah, and i really don’t want to have to write all the glue myself just now, it balloons the scope
<FromGitter> <dscottboggs_gitlab> Lucky would probably be the easiest, if you already knew lucky.... it's kinda a lot, but the docs are really good. ⏎ ⏎ I've never been able to get Amber to work right on Firefox, so I never get very far. ⏎ ⏎ Kemal doesn't provide a lot of abstraction but has a super low learning curve. You can basically just start using it. [https://gitter.im/crystal-lang/crystal?at=5d437f8726e2732446fd77a5]
<FromGitter> <meltheadorable> i could probably write something on par with early paperclip without too much trouble
<FromGitter> <meltheadorable> but paperclip has a lot of problems
<FromGitter> <dscottboggs_gitlab> @Blacksmoke16 what were you saying about libyaml integration?
<FromGitter> <meltheadorable> and activestorage has a lot going on
<FromGitter> <watzon> Yeah, I want something easier to use than ActiveStorage but just as powerful
<FromGitter> <watzon> We'll see if I can come up with something
<FromGitter> <meltheadorable> id wanna combine the APIs of like, activestorage and carrierwave
<FromGitter> <Blacksmoke16> @dscottboggs_gitlab that it would prob be easier to just bypass it?
<FromGitter> <meltheadorable> carrierwave is great except its leaky DSL and its handling of multiple file uploads
<FromGitter> <Blacksmoke16> im not sure its used for the parsing
<FromGitter> <meltheadorable> in terms of defining different processors and laundering your media through them
<FromGitter> <meltheadorable> those kinds of hooks are great
<FromGitter> <watzon> Yeah carrierwave is nice
<FromGitter> <Blacksmoke16> something like
<FromGitter> <meltheadorable> in crystal i think you could even maybe do better in terms of plugins for processors, because you could declare an interface for them and have that checked
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d43807426e2732446fd7dc7]
<FromGitter> <meltheadorable> i don’t like shrine, which everyone else seems really enamored with, but it would probably be pretty straightforward to port that
<FromGitter> <watzon> You mean an `abstract class`?!?! 😮
<FromGitter> <watzon> Lol
<FromGitter> <tenebrousedge> no, no one uses those
<FromGitter> <meltheadorable> in part just because its core is so small
<FromGitter> <watzon> They are useless really
<FromGitter> <meltheadorable> lol
<FromGitter> <watzon> /s
<FromGitter> <watzon> Hahaa
<FromGitter> <meltheadorable> but in all seriousness
<FromGitter> <watzon> No for sure, Crystal is great for defining adapters like that
<FromGitter> <meltheadorable> a combination of carrierwave & activestorage would hit a pretty good sweet spot for me
<FromGitter> <meltheadorable> in terms of user facing API and general power
<FromGitter> <watzon> Yeah I agree
<FromGitter> <dscottboggs_gitlab> > You mean an `abstract class`?!?! 😮 ⏎ ⏎ ROFL
<FromGitter> <watzon> I feel like that's going to be funny for a while
<FromGitter> <watzon> I just can't even
<FromGitter> <meltheadorable> I legitimately would write something for that but i’m not sure which web framework I like for crystal yet, if any of them, and again, the entire point of this project is that I wanna keep it down to like 3 days of development’s worth of scope initially
<FromGitter> <meltheadorable> and writing a powerful file upload handling plugin for a webframework i have not learned is a scope explosion
<FromGitter> <meltheadorable> 😂
<FromGitter> <watzon> Personally Lucky is my favorite. It is the closest thing we have so far to Rails, without actually trying to recreate Rails
<FromGitter> <watzon> And the main devs are super responsive in Gitter
<FromGitter> <meltheadorable> I vaaaugely like the look of it, but I really don’t like the decision to abandon templating languages
<FromGitter> <Blacksmoke16> *one day someone will want to make an API and i'll be relavent* 😛
<FromGitter> <meltheadorable> I understand it, and I’m sure there’s power in it, I just don’t like it.
<FromGitter> <watzon> I feel like that's only temporary. Eventually I'm sure templating languages will be supported.
<FromGitter> <watzon> Personally I've grown to love it
<FromGitter> <meltheadorable> I mean you can replace the render method or whatever to a call to a templating language
<FromGitter> <meltheadorable> so you can still do it if you want it’s just ugly
<FromGitter> <watzon> @Blacksmoke16 last time I wanted to make one Athena was broken and I couldn't use it 😂
<FromGitter> <Blacksmoke16> i mean i did fix it like that morning :P
<FromGitter> <watzon> Yeah, but I had already finished my project by then lol
<FromGitter> <Blacksmoke16> rip
<FromGitter> <meltheadorable> I very very very infrequently want an API that isn’t mirroring a server-rendered app
<FromGitter> <Blacksmoke16> figured it was best to find a niche
<FromGitter> <watzon> And now look at it
<FromGitter> <watzon> This is insane lol
<FromGitter> <Blacksmoke16> vs competing with other more mature frameworks
<FromGitter> <watzon> Yeah it makes sense
<FromGitter> <watzon> Do something very few other people are doing and do it better
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <watzon> Or at least different enough to be relevant
<FromGitter> <Blacksmoke16> next up on my list is ability to inject params into a service
<FromGitter> <Blacksmoke16> i.e.
<FromGitter> <kniknoo> Why I'm not even thinking about jumping into web stuff here and want to focus on cli utilities.
<FromGitter> <meltheadorable> What’s the i18n story look like for frameworks so far? Totally irrelevant to my weekend project but we’ll not be able to switch to crystal for anything I do at work, for instance, without that
<FromGitter> <Blacksmoke16> #athena.yaml ⏎ ⏎ ... ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d4382b7ff59f961b4fb3788]
<FromGitter> <Blacksmoke16> where the params can be assigned on per env basis and merged via yaml `<<: *development` feature
<FromGitter> <watzon> @meltheadorable I think Amber just added I18n if I remember right
<FromGitter> <watzon> It may have been something else though, idk
* FromGitter * meltheadorable nods
<FromGitter> <watzon> Lucky has it planned, but it hasn't been implemented yet
<FromGitter> <watzon> Right now the Lucky team is focusing on Avram, the ORM
<FromGitter> <meltheadorable> Suppose theres definitely no shards for i18n-ing user-generated content
<FromGitter> <watzon> They want to get it complete
<FromGitter> <meltheadorable> lol
<FromGitter> <dscottboggs_gitlab> looks like there are a few options? http://crystalshards.xyz/?filter=i18n
<FromGitter> <watzon> Yeah there's one that's particularly good
<FromGitter> <dscottboggs_gitlab> lol that would be nuts @meltheadorable
<FromGitter> <meltheadorable> @dscottboggs_gitlab there’s a couple for ruby/rails, but i’ve also had to roll my own enough times that im actually fairly familiar with the problem space
<FromGitter> <meltheadorable> i think it’d be really hard to do in crystal though without metaprogramming stuff I don’t know how to replicate
<FromGitter> <meltheadorable> moooost of the interface for the one i wrote for one project is probably almost doable with only info known at compile time
<FromGitter> <dscottboggs_gitlab> Yeah Crystal metaprogramming is VERY different from metaprogramming in dynamic languages
<FromGitter> <dscottboggs_gitlab> Although I've yet to see a better macro system in a compiled language
<FromGitter> <meltheadorable> i try to limit my metaprogramming in ruby to `define_method` and avoid `send` which. maps pretty well to what macros are capable of
<FromGitter> <watzon> @dscottboggs_gitlab imo Nim has the best macro system
<FromGitter> <watzon> It gives you full unadulterated access to the AST
<FromGitter> <watzon> Which makes it extremely powerful
<FromGitter> <dscottboggs_gitlab> Oh wow,
<FromGitter> <meltheadorable> i would love to port one of my activerecord gems to crystal but it relies on `send` and im not sure i can do it without it
<FromGitter> <watzon> You can actually write a complete scripting language inside of Nim if you wanted to
<FromGitter> <watzon> It's kinda crazy
<FromGitter> <watzon> Like as a DSL
<FromGitter> <dscottboggs_gitlab> I was actually thinking as I typed that *I know Nim has a macro system, maybe it's better than Crystal's*
<FromGitter> <dscottboggs_gitlab> you could do the same in crystal
<FromGitter> <watzon> Haha, it's the best I've seen
<FromGitter> <meltheadorable> in principle or now?
<FromGitter> <dscottboggs_gitlab> I was just talking about doing that the otehr day as hooks to Python
<FromGitter> <dscottboggs_gitlab> I haven't *tried* it, but it should work in theory
<FromGitter> <watzon> By that I mean you can parse the AST at compile time and change invalid Nim syntax into a valid syntax
<FromGitter> <watzon> That's a little out of my comfort zone though
<FromGitter> <dscottboggs_gitlab> You can do that in crystal
<FromGitter> <watzon> You can?
<FromGitter> <dscottboggs_gitlab> For example, we've discussed implementations of ruby's `send` in Crystal
<FromGitter> <watzon> Ahh yeah, but that doesn't go against the language syntax does it?
<FromGitter> <watzon> you just have to do some dynamic method creation or something
<FromGitter> <meltheadorable> I would like to hear more about this
<FromGitter> <meltheadorable> @watzon does lucky’s ORM have something equivalent to scopes in activerecord
<FromGitter> <dscottboggs_gitlab> So, for send, one would have to iterate over each method in the class/struct to create a case..when block to match the method name to a StringLiteral
<FromGitter> <watzon> @meltheadorable refresh my memory. It's been a while since I've worked with AR
<FromGitter> <meltheadorable> basically procs that return an ActiveRecord::Relation as shortcuts to longerish chains for queries
<FromGitter> <meltheadorable> named procs
<FromGitter> <watzon> @dscottboggs_gitlab right, but in the end you still have to parse valid Crystal syntax and generate valid nodes from that right?
<FromGitter> <watzon> @meltheadorable I don't think they do yet, but I'm not 100%
<FromGitter> <meltheadorable> `scope :most_recent, -> { order(created_at: :desc) }` which you can then use by doing `Model.all.most_recent`
<FromGitter> <meltheadorable> the only real difference between them and instance methods is the defined interface (it’s expected they will always be chainable and always return an active record relation) and i think they might define one or two aditional helper methods
<FromGitter> <dscottboggs_gitlab> @watzon yes but the point is that you can enumerate all values that it's possible to respond to, and compare input at runtime to that. You MUST handle the error case of receiving unrecognized input from a user in the macro but that's really the only limitation aside from the performance hit
<FromGitter> <dscottboggs_gitlab> Gimme a few minutes and I'll bang out a `send` implementation
<FromGitter> <watzon> Looks like they do have something like that
<FromGitter> <meltheadorable> They’re just normal instance methods, they seem to have abandoned the idea of having special syntax for them ^_^
<FromGitter> <meltheadorable> but that’s fine
<FromGitter> <watzon> Yup, and they're defined on a Query instead of a Model
<FromGitter> <meltheadorable> yeah, im not sure yet how well my gem maps to that style
<FromGitter> <meltheadorable> my original gem is pretty minor but it helps with dealing with user-provided sorting options safely, so if you have like a dropdown for sort orders in your frontend for products, you don’t need to write big whole chains of ifs or a big case to choose which one to apply ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ which you’d then use by just calling `Item.safe_sort(params[:sort_option])` and as
<FromGitter> ... long as it matches one of the defined `sort_options` it’ll work, otherwise it’ll fall back to the default [https://gitter.im/crystal-lang/crystal?at=5d438818bea6966fb04d213c]
<FromGitter> <watzon> That's cool
<FromGitter> <meltheadorable> that should be doable in crystal by using macros to generate that case, since you can register and iterate over the valid options and throw the default in the else
<FromGitter> <meltheadorable> but im not sure if that API would be natural in a lucky query
<FromGitter> <paulcsmith> Instance methods with no special syntax was done on purpose in Lucky. It’s super flexible, easy to test. Also easy to understand and errors are nice because it’s not buried in macro code. I think in general classes and regular methods are an awesome choice if possible
<FromGitter> <watzon> There's the Lucky authority right there ^
<FromGitter> <watzon> Lol
<FromGitter> <paulcsmith> What does the gem do? Maybe there would be a way to use it with regular instance methods in Lucky still
<FromGitter> <dscottboggs_gitlab> @watzon @meltheadorable Ruby's send implemented in Crystal https://carc.in/#/r/7c70
<FromGitter> <watzon> That's pretty simple too
<FromGitter> <dscottboggs_gitlab> yup
<FromGitter> <dscottboggs_gitlab> and a really good demonstration of just how powerful the macro system is
<FromGitter> <dscottboggs_gitlab> Although I agree that its incomplete and can see more features being added in the future
DTZUZU has quit [Quit: WeeChat 2.2]
DTZUZU has joined #crystal-lang
<FromGitter> <paulcsmith> @meltheadorable Here is how I believe I'd do that with just a regular instance method: https://gist.github.com/paulcsmith/5727ac9a2db44e3c738948d506b99f90
<FromGitter> <paulcsmith> A bit more wordy. I bet you could make a macro that generates that code for you though. I'll try to make an example
<FromGitter> <meltheadorable> @paulcsmith In the ruby version, it’s implemented by registering the name of each sort option in a whitelist and then calls to the safe sort method check the whitelist before passing it on through to send, it is basically just letting you define a whitelist of methods that are safe to call if they match user input, with a defined fallback, it’s always been possible to do through normal instance
<FromGitter> ... methods, but there’s some additional clarity that comes from the compact API and from packaging it as a kind of standard interface
<FromGitter> <meltheadorable> i do think it would be possible to generate the case via macro
<FromGitter> <meltheadorable> because it doesn’t involve anything that isn’t already in the code
<FromGitter> <meltheadorable> i was more asking the question of whether that sort of API would even be welcome
<FromGitter> <meltheadorable> (and because it also uses scopes under the hood, you also get the implementation inline with its declaration as a sort option, which for something like sorts is really nice, as opposed to having to decouple them)
<FromGitter> <meltheadorable> but I suspect you could use annotations over the method names on the query to construct the whitelist and do something with that
<FromGitter> <paulcsmith> @meltheadorable I think this would be cool. I'd love to use this in Lucky :)
<FromGitter> <meltheadorable> in crystal
<FromGitter> <paulcsmith> Here is a super rough implementation https://gist.github.com/paulcsmith/5727ac9a2db44e3c738948d506b99f90
<FromGitter> <paulcsmith> Of course you could also do what you said and generate other methods like `recently_updated` so that you can call `UserQuery.new.recently_updated` directly. This would all by type-safe and the case handles the whitelist. Would be super cool!
<FromGitter> <paulcsmith> If you ever wanna chat about it some more ping me or hop in https://gitter.im/luckyframework/Lobby
<FromGitter> <paulcsmith> I tend to stay in Lucky because I don't have much time to do that + the Crystal room :P
<FromGitter> <meltheadorable> I will probably want to build this the first time I actually do a crystal web project, but I don’t have one in mind atm
<FromGitter> <watzon> See what I mean? The maintainers of Lucky are super active and helpful 😄
<FromGitter> <dscottboggs_gitlab> NIce implementation @paulcsmith
<FromGitter> <paulcsmith> Thanks :D
<FromGitter> <meltheadorable> i’ll pop into the lucky room if i ever use lucky ^_^;;;
<FromGitter> <meltheadorable> still trying to find a project that’s a good fit for crystal atm
<FromGitter> <paulcsmith> Yeah for sure. Having the right project makes *all* the difference
<FromGitter> <meltheadorable> a lot of the stuff i wanna do will *never* get done if i need to build 80% of the ecosystem myself, rails is still unbeatable for that 😂
<FromGitter> <paulcsmith> Totally
<FromGitter> <meltheadorable> but i increasingly do try to see if i can make crystal fit my smaller projects before i reach for rails
<FromGitter> <meltheadorable> eventually i’ll find one
<FromGitter> <meltheadorable> lol
<FromGitter> <watzon> > if i need to build 80% of the ecosystem myself ⏎ ⏎ I feel like I'm trying this
<FromGitter> <watzon> Lol
<FromGitter> <paulcsmith> We're working hard to get a lot of the stuff built-in to Lucky. Not there yet, but we're getting pretty far. Front end assets, ORM, built-in auth. But lots of third part stuff missing
<FromGitter> <paulcsmith> You gotta roll your own API clients for just about everything. But I kind of enjoy making all those little libs, even though it does take time :P
<FromGitter> <meltheadorable> and i applaud you but my side project list is, and i am not kidding, 35 projects long and ever-growing, and half of them also require building the world even in mature ecosystems
<FromGitter> <paulcsmith> Once the Crystal ecosystem has these libs it'll be unstoppable
<FromGitter> <paulcsmith> @meltheadorable Sounds like you've got a lot of ambitious ideas!
<FromGitter> <meltheadorable> i can’t stop coming up with ambitious ideas
<FromGitter> <meltheadorable> i would love for somebody to come take some from me
<FromGitter> <meltheadorable> lol
<FromGitter> <meltheadorable> people stealing my ideas would be a very very very welcome reprieve
<FromGitter> <paulcsmith> I might steal your safe_sort idea haha
<FromGitter> <meltheadorable> oh please not that one i am actually proud of that itty bitty tiny niche i carved for myself 😂
<FromGitter> <paulcsmith> Haha ok I won't 🤣
<FromGitter> <watzon> @meltheadorable same though
<FromGitter> <meltheadorable> i meant i want people to steal my ambitious ideas not the little achievable ones
<FromGitter> <meltheadorable> those are so few and far between
<FromGitter> <watzon> I can't tell you how difficult it has been getting where I am with Marionette
<FromGitter> <meltheadorable> 😂
<FromGitter> <dscottboggs_gitlab> > i can’t stop coming up with ambitious ideas ⏎ ⏎ ooof yeah
<FromGitter> <watzon> That project was almost too ambitious for one person
<FromGitter> <kniknoo> Ambitious ideas come from lots of little ideas.
<FromGitter> <dscottboggs_gitlab> me too I mean
<FromGitter> <watzon> @kniknoo when two little ideas love each other very much...
<FromGitter> <meltheadorable> haha
<FromGitter> <kniknoo> They invoke a stork of genius?
<FromGitter> <watzon> 😂
<FromGitter> <watzon> That was good
<FromGitter> <kniknoo> Thankee.
<FromGitter> <meltheadorable> in my case it goes the opposite direction — i get big ideas that require implementing 300,000 itty bitty ideas that are also novel
<FromGitter> <meltheadorable> my big ambitous ideas spawn lots of smaller slightly less ambitious ideas
<FromGitter> <watzon> Yeah I feel that
<FromGitter> <kniknoo> Is multiple assignment on local play not working a known issue?
<FromGitter> <watzon> Even right now I'm having to roll my own proxy server implementation to make Marionette work right
<FromGitter> <meltheadorable> @watzon https is probably gonna continue to be an issue there, might be time to break it out into its own shard to make space for the code it’s likely to require
<FromGitter> <kniknoo> Let me rephrase that, not working in an init with @s, seems to work in global.
<FromGitter> <watzon> Yeah I've already run into the HTTP issue :(
<FromGitter> <meltheadorable> 🌻
<FromGitter> <watzon> I'm in the newest edition of Crystal Lib Hunt twice 😁 https://crystal.libhunt.com/newsletter/125
<FromGitter> <watzon> Man this sucks
<FromGitter> <watzon> Firefox makes connections like this ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ But Crystal doesn't handle that well [https://gitter.im/crystal-lang/crystal?at=5d439ec77c87746165f71a73]
<FromGitter> <watzon> I wish URI.parse worked on URLs like that correctly
<FromGitter> <meltheadorable> ooof
<FromGitter> <watzon> This is making writing a proxy server pretty difficult
<FromGitter> <meltheadorable> which part does it not handle correctly?
<FromGitter> <watzon> Both the CONNECT and the URI format
<FromGitter> <watzon> When I change the URI to a correct format with a scheme and no port and change CONNECT to GET it works
<FromGitter> <meltheadorable> hmmm
<FromGitter> <watzon> Idk why CONNECT isn't working, it's HTTP/1.1
<FromGitter> <meltheadorable> it should be relatively straightforward to write a simple transformer that will take a method & URI and return a tuple with the new schemed version & new verb at least?
<FromGitter> <watzon> Yeah, relatively
<FromGitter> <watzon> URIs are a pain in the ass though
<FromGitter> <meltheadorable> is the problem with URI.parse that it doesn’t work with appended ports at all or just that it doesn’t detect 443 as SSL?
<FromGitter> <meltheadorable> like going from `{“CONNECT”, “www.google.com:443”}` to `{ “GET”, “https://www.google.com”}` shouldn’t be too hard if you can still use URI.parse to identify & strip the port, and a case statement could handle the scheme setup for the average case, 80 http, 443 https, anything else just leave it alone
<FromGitter> <watzon> URI.parse doesn't correctly differentiate the host from scheme in this case. It ends up putting `www.google.com` as the scheme
<FromGitter> <meltheadorable> that’s a bug in the library that should definitely just be patched & fixed
<FromGitter> <meltheadorable> at least
<FromGitter> <watzon> And it ends up identifying the port as a path
<FromGitter> <watzon> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d43a15775c7976e0310c634]
<FromGitter> <meltheadorable> i mean it doesn’t help you *now* but that’s straightforwardly incorrect behavior as opposed to just being like, something you’ll have to live with forever
<FromGitter> <meltheadorable> that can be fixed upstream
<FromGitter> <meltheadorable> nobody could reasonably be relying on the incorrect behavior
laaron has joined #crystal-lang
<FromGitter> <watzon> It looks like Ruby behaves the same way
<FromGitter> <meltheadorable> yeah i just found that out too — i wonder if this is some weird side effect of strict adherence to the spec
<FromGitter> <watzon> I think it is. I know there's a Ruby library that does a better job of figuring out URIs like that, but I can't remember what it's called
<FromGitter> <watzon> I tried to port it before, but it's a monster
<FromGitter> <meltheadorable> go also does this — https://play.golang.org/p/qbW1wWkcKY apparently
<FromGitter> <kniknoo> O.o
<FromGitter> <meltheadorable> https://github.com/golang/go/issues/19779
<FromGitter> <meltheadorable> what a mess
<FromGitter> <watzon> Yeah. I think it's the specs fault.
<FromGitter> <meltheadorable> somebody needs to revise the spec against reality
<FromGitter> <watzon> I agree
<FromGitter> <meltheadorable> making dots illegal characters in schemes would basically fix this problem i think
<FromGitter> <meltheadorable> and i don’t think any real world uri scheme is using dots
<FromGitter> <watzon> We need this in Crystal https://github.com/sporkmonger/addressable
<FromGitter> <watzon> It does a much better job
dingenskirchen has quit [Ping timeout: 245 seconds]
<FromGitter> <watzon> And it handles URI templates
<FromGitter> <watzon> Maybe I'll take a crack at it again
<FromGitter> <meltheadorable> apparently technically “CONNECT” is a host/port tuple not a URI, so a way around this might be to fix the other side of this and handle `CONNECT` directly
<FromGitter> <meltheadorable> which should be doable without violating any specs
<FromGitter> <watzon> Ahh interesting
<FromGitter> <meltheadorable> i mean go nuts if you wanna implement addressable but a path of less resistance might be to implement connect
<FromGitter> <watzon> Well I've got it working now with some hacky regex magic
<FromGitter> <watzon> But now I'm getting another error elsewhere lol
<FromGitter> <meltheadorable> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d43a698eb4c657f4394ef92]
<FromGitter> <meltheadorable> from the spec
<FromGitter> <watzon> Oh well it's already doing that
<FromGitter> <watzon> "www.google.com:443"
<FromGitter> <meltheadorable> right what i’m saying is that it’s not a URI, so you can fix it
<FromGitter> <meltheadorable> it’s a host name and port number
<FromGitter> <watzon> Ahh I gotcha
<FromGitter> <meltheadorable> and a simple regex or even `split` is sufficient
<FromGitter> <meltheadorable> its much more limited than URIs
<FromGitter> <watzon> The problem is I have to be able to handle multiple cases, like when there isn't a port present
laaron has quit [Remote host closed the connection]
<FromGitter> <watzon> Or when it is actually in the correct format
laaron has joined #crystal-lang
<FromGitter> <watzon> Crap, it looks like even addressable fucks up there
<FromGitter> <watzon> Ahhh, but Addressable has a `URI#heuristic_parse` method that gets it almost right
<FromGitter> <watzon> It sets the scheme to http
_whitelogger has joined #crystal-lang
<FromGitter> <bararchy> If anyone on Arch Linux wanna play with 0.30.0 ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d43bc9fb336537fd410529a]
<FromGitter> <bararchy> fixed the PKBUILG for 0.30.0
rohitpaulk has joined #crystal-lang
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
laaron has joined #crystal-lang
rohitpaulk has quit [Remote host closed the connection]
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
<FromGitter> <alex-lairan> Hi, I've tried to upgrade my shards to 0.30.0 ⏎ ⏎ It use a lot of generics and I have this error : ⏎ ⏎ ```code paste, see link``` ... [https://gitter.im/crystal-lang/crystal?at=5d43d53941d5cd61b59c38b1]
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
laaron has joined #crystal-lang
sorcus has joined #crystal-lang
dingenskirchen has joined #crystal-lang
<FromGitter> <naqvis> @alex-lairan might be due to breaking changes in (0.30.0)[https://github.com/crystal-lang/crystal/releases/tag/0.30.0] ⏎ `(breaking-change) Enforce abstract methods return types. (#7956, #7999, #8010, thanks @asterite)`
<FromGitter> <watzon> Oh I forgot about that. I'm going to need to do some refactoring for some of my libs.
<FromGitter> <naqvis> yeah, this breaking change would definitely require whole lot of shards to break. Indeed a *breaking change*
<FromGitter> <watzon> Damn abstract methods
<FromGitter> <watzon> Don't they know they're useless?
<FromGitter> <naqvis> 😆
<FromGitter> <naqvis> just hope in future version of language, compiler *cryptic* messages can be improved
<FromGitter> <watzon> Yeah there are some error messages that could use improving
<FromGitter> <watzon> If I remember right this version actually introduced some improvements there
<FromGitter> <watzon> It might have been 0.29.0 though
flaviodesousa has joined #crystal-lang
<FromGitter> <naqvis> yes, release changes does state that. But above cited compiler message in Lairan message still shows the cryptic output from compiler. That’s from 0.30.0 compiler output
flaviodesousa has quit [Ping timeout: 258 seconds]
<FromGitter> <alex-lairan> @naqvis I've changed my classes to conform to the return type :)
<FromGitter> <alex-lairan> Oops the link is dead : https://github.com/alex-lairan/monads/pull/54
_whitelogger has joined #crystal-lang
<FromGitter> <alex-lairan> Ah 😀
ht_ has joined #crystal-lang
flaviodesousa has joined #crystal-lang
alex`` has joined #crystal-lang
<FromGitter> <kingsleyh> anyone know why this error occurs? `crystal/0.29.0/src/gc/boehm.cr:76:5 in 'Sushi::Core::Transaction#valid_as_embedded?`
<FromGitter> <kingsleyh> is it a GC problem?
<FromGitter> <kingsleyh> or it's a red herring? and it's not a problem
<FromGitter> <watzon> What's the full trace?
<FromGitter> <kingsleyh> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d43f858d7fc954750e58950]
<FromGitter> <kingsleyh> also not sure why it affects the web sockets
<FromGitter> <watzon> That's weird
<FromGitter> <watzon> I've never seen anything like that before
<FromGitter> <naqvis> @kingsleyh any symptoms of `memory leak`? cited source and line is referring to `LibGC.malloc(size)`
<FromGitter> <kingsleyh> hmm I'll investigate - maybe something to do with a spawn somewhere
<FromGitter> <naqvis> might be, better perform mem profiling to see if you can find the culprit
<FromGitter> <kingsleyh> @naqvis what's a good tool for mem profiling in Crystal?
<FromGitter> <j8r> Valgrind in general
<FromGitter> <kingsleyh> maybe this instruments tool on OSX? https://www.mikeperham.com/2016/06/24/profiling-crystal-on-osx/
dingenskirchen has quit [Ping timeout: 246 seconds]
<FromGitter> <kingsleyh> unfortunately Valgrind doesn't work on osx mojave - the only os I have
dingenskirchen has joined #crystal-lang
<FromGitter> <j8r> LLDB maybe?
<FromGitter> <mavu> Morning, I am getting this: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d4405f441d5cd61b59da8ed]
<Stephie> valgrind isn't e mem profiler
<FromGitter> <mavu> Has anyone seen something similar?
Flipez has quit [Quit: The Lounge - https://thelounge.github.io]
<Stephie> perf on linux, and callgrind
<Stephie> @kingsleyh instruments is the only one i know of on osx
Flipez has joined #crystal-lang
Flipez has quit [Client Quit]
Flipez has joined #crystal-lang
<FromGitter> <kingsleyh> @stephie I’m not sure I understand how to read the output of instruments - I used the Allocations template on my binary and now see a list of heap allocations but no idea what it means
<FromGitter> <watzon> @mavu it looks like you're using `to_i` on a string that doesn't contain just an int
<FromGitter> <watzon> Sorry other way around
<FromGitter> <watzon> You're trying to cast a json int to a string
<FromGitter> <watzon> Or yaml rather
<FromGitter> <watzon> I'm on my phone rn lol
<FromGitter> <mavu> @watzon I get the error since i changed a phone number field in my config file to string (because surprisingly a phone number can be longer than int32) ⏎ The only conversion I'm doing is this line: ⏎ ⏎ ```code paste, see link``` ⏎ ... [https://gitter.im/crystal-lang/crystal?at=5d440ab7ff59f961b4fede86]
<FromGitter> <mavu> I'll try to make a short file that replicates the error
<FromGitter> <mavu> https://play.crystal-lang.org/#/r/7c7o ⏎ this makes : ⏎ ⏎ ```code paste, see link``` ⏎ ... [https://gitter.im/crystal-lang/crystal?at=5d440d967c87746165fa38c7]
<FromGitter> <absolutejam_gitlab> Seems like it
<FromGitter> <absolutejam_gitlab> Wait
<FromGitter> <absolutejam_gitlab> > This means that invoking #as_s when the underlying value is not a String will raise: the value won't automatically be converted (parsed) to a String.
<FromGitter> <watzon> @mavu the phone number should be stored as a string to begin with since not all phone numbers are valid ints
<FromGitter> <absolutejam_gitlab> You need to use `.to_s`
<FromGitter> <watzon> Some start with 0
<FromGitter> <absolutejam_gitlab> but yeah, a phone number is a string, not a numeric value imo
<FromGitter> <absolutejam_gitlab> what if you get `+44` at the start, etc.
<FromGitter> <mavu> @watzon As far as I understand YAML, strings don't need quotes unless you want to force them to be strings.
<FromGitter> <watzon> Generally true
<FromGitter> <absolutejam_gitlab> but it could be parsed as an int?
<FromGitter> <watzon> Which for numbers you may need to do
<FromGitter> <watzon> Unless the number starts with a 0 or a +
<FromGitter> <absolutejam_gitlab> I always quote my strings
<FromGitter> <watzon> Even if it starts with a + it may get parsed as an int though
<FromGitter> <absolutejam_gitlab> Makes it look more visible in editors too imo
<FromGitter> <mavu> @absolutejam_gitlab where did you find the quote about #as_s above? Did I skip reading the docs again? >.>
<FromGitter> <absolutejam_gitlab> https://crystal-lang.org/api/0.23.1/YAML/Any.html
<FromGitter> <watzon> You could make it a `String | Int64` and then just do `to_s`
<FromGitter> <absolutejam_gitlab> I'm not sure on the semantics of `cast` - Does that normally mean no conversion?
<FromGitter> <watzon> That way they don't have to quote it
<FromGitter> <mavu> I will play around with some different things and see which I like best, thanks for the pointers :)
<FromGitter> <watzon> No problem. Strings should definitely be the default though. Phone numbers should never be actual numbers
<FromGitter> <absolutejam_gitlab> If it isn't data you're going to manipulate with numeric operations (you wouldn't add phone numbers) just save them as strings
<FromGitter> <absolutejam_gitlab> then you get regex matching etc.
<FromGitter> <watzon> I'd convert it to a string and then strip all chars that aren't integers
<FromGitter> <watzon> That way the phone number can be in any format
<FromGitter> <absolutejam_gitlab> it's like having a car license plate that's all numbers - it's not really an int
<FromGitter> <watzon> Phone numbers and monitary values are often confusing for people. Phone numbers should always be strings and money should always be a normal int and not a float
<FromGitter> <watzon> Or a bigint for those high rollers 😉
<FromGitter> <absolutejam_gitlab> I'm so happy I got the static compilation working
<FromGitter> <absolutejam_gitlab> And by that, I mean 'I'm so happy I stopped being an idiot'
<FromGitter> <absolutejam_gitlab> I was literally about to rewrite in another language I was so annoyed haha
<FromGitter> <watzon> Lol glad you got things working
go|dfish has quit [Quit: SIGQUIT]
<Stephie> @kingsleyh the allocations don't work because of libgc
<Stephie> Only runtime
<Stephie> Not any of the memory functions
devil_tux has joined #crystal-lang
teardown has quit [Ping timeout: 248 seconds]
<FromGitter> <kniknoo> How can I do this more accurately? 3-4% is a lot of drift. https://play.crystal-lang.org/#/r/7c7v
<FromGitter> <kingsleyh> @Stephie how does one use it to check for memory leaks?
<Stephie> You can't
<Stephie> There's no tool for that
<Stephie> I think maybe someone made a specific leak checker shard for crystal
<Stephie> But I don't remember the name sorry
devil_tux has quit [Ping timeout: 245 seconds]
devil_tux has joined #crystal-lang
<FromGitter> <absolutejam_gitlab> omg
<FromGitter> <absolutejam_gitlab> TIL of compact_map
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
laaron has quit [Remote host closed the connection]
devil_tux has quit [Ping timeout: 268 seconds]
devil_tux has joined #crystal-lang
<FromGitter> <greenbigfrog> Trying to launch some crystal code through docker-compose, and somehow it fails when launching the container via docker-compose, but otherwise it works. Not sure where OptionParser is even used... ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ Anyone got any ideas? [https://gitter.im/crystal-lang/crystal?at=5d44376075c7976e0314f60c]
<FromGitter> <tenebrousedge> what command did you use?
<FromGitter> <greenbigfrog> `ENTRYPOINT ["/website-launcher"]`
laaron has joined #crystal-lang
<FromGitter> <greenbigfrog> It's probably kemal
<FromGitter> <greenbigfrog> but not sure where it's getting the `-c` from
sagax has quit [Remote host closed the connection]
<FromGitter> <tenebrousedge> `/website-launcher` ? it's in the root directory?
<FromGitter> <greenbigfrog> I static build and then copy it over to a clean container.
<FromGitter> <greenbigfrog> I just thought of setting the `command` inthe docker-compose.yml, and it works
<FromGitter> <greenbigfrog> but why is docker-compose sending a `-c`...
<FromGitter> <tenebrousedge> what command did you use to start docker?
devil_tux has quit [Ping timeout: 272 seconds]
<FromGitter> <kingsleyh> hello I need some maths help - anyone good at maths please message me
<FromGitter> <greenbigfrog> `sudo systemctl start docker`?
<FromGitter> <tenebrousedge> no
<FromGitter> <tenebrousedge> the `docker-compose` command
<FromGitter> <greenbigfrog> `docker-compose up`
<FromGitter> <absolutejam_gitlab> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d4440104635976e041939fc]
<FromGitter> <absolutejam_gitlab> am I a bad person?
<FromGitter> <absolutejam_gitlab> for abusing ternary
<FromGitter> <tenebrousedge> yes
<FromGitter> <absolutejam_gitlab> @greenbigfrog share the compose file
<FromGitter> <kingsleyh> how can I generate a gradient with a decreasing value for each item in Crystal - like this:
<FromGitter> <kingsleyh> ``````
<FromGitter> <kingsleyh> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d44406cd7fc954750e7cb11]
<FromGitter> <tenebrousedge> I think docker-compose has some weird behavior with `entrypoint` in dockerfiles. Probably best to specify in the docker-compose
<FromGitter> <absolutejam_gitlab> Overwrite the entrypoint to `["sh", "-c"]` for good measure
<FromGitter> <absolutejam_gitlab> or use `dumb-init` if you need signals (once you have it working)
<FromGitter> <tenebrousedge> @kingsleyh use `zip`? potentially followed by `to_h` if you need a `Hash`
<FromGitter> <kingsleyh> I don't want to hold a big hash in memory - I want to just calculate the amount using maths
<FromGitter> <kingsleyh> just because the number_of_items will probably be 50 million
<FromGitter> <tenebrousedge> so `[curr, 50_000_000 - curr]`
<FromGitter> <kingsleyh> I want a gradient though - which gradually tapers down
<FromGitter> <kingsleyh> I'm sure there is a math algorithm that can do it
<FromGitter> <tenebrousedge> give us some input/expected output pairs
lucasb has joined #crystal-lang
<FromGitter> <meltheadorable> id fight you on the name `generate gradient` for something that is not actually generating anything, but ⏎ ⏎ `total_amount - (curent_item * (total_amount / number_of_items))` ⏎ ⏎ should do it [https://gitter.im/crystal-lang/crystal?at=5d44422bdfbfc20f5a8537aa]
<FromGitter> <kingsleyh> yeah the name sounds wrong :)
<FromGitter> <meltheadorable> if i’m understanding this right
duane has quit [Ping timeout: 246 seconds]
<FromGitter> <meltheadorable> you want to take the total amount, then subtract the amount per item * current item from it, so that if the current item is 0 it’s just the total and if the current item is the max then it’s 0
<FromGitter> <kingsleyh> actually I think I didn't explain it very well
<FromGitter> <kingsleyh> your solution doesn't do what I wanted exactly
<FromGitter> <meltheadorable> that’s a linear formula, if you need it to follow some other curve then i can’t really help you
<FromGitter> <kingsleyh> I want the 20000 to be distributed across the total items in a decreasing way
<FromGitter> <meltheadorable> you need to pick things like decreasing by how much
<FromGitter> <meltheadorable> once you move into nonlinear curves there’s decisions you would have to make
<FromGitter> <meltheadorable> nobody’s gonna be able to fill this in for you
<FromGitter> <meltheadorable> there’s constants involved that aren’t part of your problem parameters
<FromGitter> <kingsleyh> decreasing by enough so that it distributes
<FromGitter> <kingsleyh> can't it automatically calculate the decrease in order to create a curve
<FromGitter> <kingsleyh> since we know the number of items and the start and end amounts
<FromGitter> <tenebrousedge> what kind of curve? why?
<FromGitter> <meltheadorable> for any non-linear curve, there’s an additional parameter that could be totally arbitrary but isn’t one of your fixed numbers that is going to choose some other stuff about the shape of the curve, you will need to pick that
<FromGitter> <meltheadorable> you are gonna need to look into different types of curves and the equations that produce them
sagax has joined #crystal-lang
<FromGitter> <meltheadorable> and choose a shape, but there will be an additional unknown constant that you’re probably going to need to tweak
<FromGitter> <meltheadorable> there’s only one linear path between two points on a graph but there’s an infinite number of curves
<FromGitter> <meltheadorable> so if you want a nonlinear curve you need to pick the other parameter
<FromGitter> <kingsleyh> I don't really mind at this point - I just want a base thing to play with
<FromGitter> <tenebrousedge> what are you trying to do?
<FromGitter> <kingsleyh> I'm trying calculate a block reward system for my blockchain project: https://sushichain.io
<FromGitter> <kingsleyh> so for each block there will be an amount of reward up to a total cap
<FromGitter> <kingsleyh> my current solution uses square roots to create the curve
<FromGitter> <kingsleyh> but it's not cutting it
<FromGitter> <tenebrousedge> reward curves have been studied in gaming
<FromGitter> <tenebrousedge> square root would be exponent = .5
<FromGitter> <kingsleyh> yes it does sound like an exponential curve would do it
<FromGitter> <tenebrousedge> do you want the reward curve to flatten out over time?
<FromGitter> <kingsleyh> I want the rewards to start at their highest and then gradually drop until the cap is reached at which point any blocks past the cap will provide no reward
<FromGitter> <kingsleyh> I can't see anyway to not hold a huge hash in memory though
<FromGitter> <kingsleyh> also a block is produced every 2 minutes - so that 720 blocks per day - so the block cap needs to be set at 3.9 million which would be 15 years of blocks until the cap
<FromGitter> <kingsleyh> and the total amount should be capped at 23 million reward amount
<FromGitter> <kingsleyh> so I need a curve that can exponentially distribute the 23 million coins over the 3.9 million blocks - so that the most reward is at the start and the least reward is near the end until finally the cap is reached and all blocks after that produce 0 reward
<FromGitter> <tenebrousedge> so like y = 3.9M - x^(d)
<FromGitter> <tenebrousedge> whatever exponent results in the area under the curve being 23M
<FromGitter> <kingsleyh> what is x and what is d in that equation?
<FromGitter> <tenebrousedge> x is the input, current block
<FromGitter> <tenebrousedge> d is an exponent
<FromGitter> <kingsleyh> is that like a parabola?
<FromGitter> <kingsleyh> hmm interesting
<FromGitter> <kingsleyh> 1) 5 is a float32 which doesn't support ^
<FromGitter> <tenebrousedge> `^` is a bitwise operator, not exponentiation
<FromGitter> <kingsleyh> so in Crystal it should be `exp`
<FromGitter> <kingsleyh> I don't know how to convert that equation to Crystal
<FromGitter> <tenebrousedge> `->(x : Int32) { 3_900_000 - x ** EXPONENT }`
<FromGitter> <tenebrousedge> and my calculus isn't good enough to provide the exponent
<FromGitter> <kingsleyh> I think I may just hardcode a big rewards table
<FromGitter> <meltheadorable> i am gonna duck out on account of i am ethically prevented from helping to bring more blockhain tech into the world
<FromGitter> <tenebrousedge> hardcoding a table with millions of elements because math is hard does not sound like a good solution
laaron has quit [Remote host closed the connection]
<FromGitter> <absolutejam_gitlab> can I dump a hash to json?
<FromGitter> <absolutejam_gitlab> like a json string
<FromGitter> <absolutejam_gitlab> wait
laaron has joined #crystal-lang
<FromGitter> <tenebrousedge> yes (https://crystal-lang.org/api/0.30.0/Hash.html#to_json(json:JSON::Builder)-instance-method)
<FromGitter> <tenebrousedge> https://crystal-lang.org/api/0.30.0/Hash.html#to_json(json:JSON::Builder)-instance-method
<FromGitter> <absolutejam_gitlab> I need to go hash -> HTTP::Client `body` param
<FromGitter> <tenebrousedge> so form encoded ?
<FromGitter> <absolutejam_gitlab> yeah mb
<FromGitter> <meltheadorable> very strange question that i could probably test if i wasn’t in the middle of something else but does `method_missing` work for class methods or just instance methods
<FromGitter> <tenebrousedge> both I think
<FromGitter> <kingsleyh> @meltheadorable no problems :)
<FromGitter> <tenebrousedge> @absolutejam_gitlab https://crystal-lang.org/api/0.30.0/HTTP/Params.html#encode(hash:Hash(String,String%7CArray(String)))-class-method
<FromGitter> <meltheadorable> the reason i’m asking is mostly dumb, i’ll share later if what i want to do works 😂
<FromGitter> <absolutejam_gitlab> Doesn't `to_s` make the hash form encoded?
<FromGitter> <tenebrousedge> pretty sure no
<FromGitter> <tenebrousedge> definitely no
<FromGitter> <absolutejam_gitlab> home time now
<FromGitter> <absolutejam_gitlab> i'll look later thanks
return0e has quit [Ping timeout: 268 seconds]
devil_tux has joined #crystal-lang
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
<Stephie> @meltheadorable unfortunately do it doesn't
<Stephie> there's no method_missing for class methods
<FromGitter> <meltheadorable> sadness
<Stephie> yeah...
<Stephie> there might be eventually
return0e has joined #crystal-lang
<FromGitter> <meltheadorable> well drat
<Stephie> there should be
<Stephie> but i'm not sure ary really likes it
<Stephie> that is, method_missing at all
<Stephie> what's your usecase?
<Stephie> there might be another way to achieve it
<FromGitter> <meltheadorable> honestly, my use case is “chaining on `.new` is ugly" and i just want to forward the class method versions of the instance methods to a newly initialized instance, for cases where the instances take no parameters and are basically totally indistinguishable from one another, it’s completely dumb and not really a problem worth solving
<FromGitter> <meltheadorable> but if there was an easy way to solve it i was gonna do it anyway
<FromGitter> <tenebrousedge> what class do you have that doesn't take any parameters?
<FromGitter> <tenebrousedge> I would think that a class would encapsulate some state
<FromGitter> <meltheadorable> it’s common for certain patterns where the class needs to hold state but the state is all a result of other processes & method calls
<FromGitter> <meltheadorable> like when the state is in the database and it needs to remember some of it but not be parameterized with anything to go get it
<FromGitter> <meltheadorable> so you need to chain query methods on new even though new never has any params
<FromGitter> <tenebrousedge> why not have those as class methods, then?
<FromGitter> <kinxer> That sounds hard to reason about for other developers.
<FromGitter> <meltheadorable> i didn’t write the code i’m just looking at it and going “ew” and wanting to hide the messy details from myself
<FromGitter> <kinxer> Ah...
<FromGitter> <tenebrousedge> fair enough
<FromGitter> <meltheadorable> though semantically i also hate using `new` for processes in general, where you are really using the class to encapsulate something that might otherwise be a function, except that it’s wrapping a bunch of other behavior and may need to hold some intermediary state, but then returns something else, so for things like service objects I also tend to not really like doing the whole
<FromGitter> ... `UserCreateService.new.process(params)` thing, but all the private methods need to share sufficient state that just using a module or something doesn’t work
<FromGitter> <meltheadorable> though that’s an easier thing to solve
laaron has quit [Remote host closed the connection]
<FromGitter> <meltheadorable> point being i see this sort of situation a lot and i get twitchy every time i see `.new.something` and i am always looking for ways to eliminate it 😂
<FromGitter> <watzon> I was trying to do that just yesterday
<FromGitter> <watzon> Couldn't come upm with anything better
laaron has joined #crystal-lang
<FromGitter> <Blacksmoke16> just because it has no args doesnt mean its not doing anything in the initalizer
<FromGitter> <meltheadorable> @watzon im not sure how id port my ruby solution for service objects specifically into crystal, needing to know types in method signatures kinda wrecks everything i think, will have to think on it
<Stephie> @meltheadorable then isn't that usually just one or two methods which you need to proxy to a new instance?
<Stephie> could probably do that manually
<FromGitter> <meltheadorable> in the service object case yes, in the case i wanted method missing for no
<Stephie> mmm
<Stephie> but it's still a predefined set
<FromGitter> <meltheadorable> yeah, the set is the set of instance methods
<Stephie> hmm
<Stephie> might be possible
<FromGitter> <meltheadorable> might be possible to write a macro that you passed those names into and then did a thing like the send implementation from yesterday
<Stephie> but i still don't really like the idea haha
<Stephie> it seems like "magic" to me
<FromGitter> <meltheadorable> i like magic
<Stephie> yeah, writing a macro to define the `def self.foo(*args); self.new.foo(*args); end`
<Stephie> i don't really like this kind of magic, and it's interesting that you have this
<Stephie> Class.new.foo() pattern so much
<Stephie> it's a reasonable pattern but i've never really had it appear often when writing stuff...
<Stephie> wonder why
devil_tux has quit [Ping timeout: 258 seconds]
<Stephie> probably cause i prefer to manually inject dependencies into such classes
<Stephie> instead of global state
<Stephie> so, i'd have args to the ctor at least
<FromGitter> <meltheadorable> i usually will go out of my way to avoid code that uses that pattern, once in a while i will find a case where i do actually need classes and not modules, but the initializer does not need to take arguments, and i’ve found ways around it there too in ruby, trying to think about how i’ll avoid it in crystal
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
<FromGitter> <rmarronnier> Hi all !
<FromGitter> <tenebrousedge> o/
<FromGitter> <Blacksmoke16> o/
<FromGitter> <rmarronnier> It seems I can't use `sort_by` with `Hash`. Am I mistaken ?
<FromGitter> <rmarronnier> if `rated_sentences` is a hash, `rated_sentences.sort_by! { |_, score| -score }` gives me `in src/cadmium/summarizer/sum_basic_summarizer.cr:24: undefined method 'sort_by!' for Hash(String, Float64) ⏎ ⏎ ``` rated_sentences.sort_by! { |_, score| -score }```` [https://gitter.im/crystal-lang/crystal?at=5d4470c945da450fec93e705]
<FromGitter> <Blacksmoke16> there isnt a sort by method for hash
<FromGitter> <tenebrousedge> you could do something like `map(&.itself).sort_by {|(k,v)| k }`
<FromGitter> <tenebrousedge> which would get you a sorted array of tuples
<FromGitter> <tenebrousedge> or `to_a` I guess
<FromGitter> <rmarronnier> Ah... :-/ Any plan / discussion about it ? (it exists in Ruby : https://stackoverflow.com/questions/2540435/how-to-sort-a-ruby-hash-by-number-value)
<FromGitter> <tenebrousedge> probably `to_a` makes more sense
<FromGitter> <rmarronnier> hmm ok, thanks. That will do the job
<FromGitter> <tenebrousedge> the Ruby version also produces an array
<FromGitter> <tenebrousedge> because `Hash` isn't ordered
<FromGitter> <tenebrousedge> I mean, theoretically anyway
<FromGitter> <naqvis> from the code it looks, he is sorting the values, so why not invoke `values` on `rated_sentences` and then call `sort_by` on values array
<FromGitter> <rmarronnier> because I need the key value (string)
<FromGitter> <tenebrousedge> in Ruby and Crystal `Hash` is ordered by insertion, but it's not wise to rely on it
<FromGitter> <naqvis> then go with tuple as Kai Leahy suggested
<FromGitter> <Blacksmoke16> can use https://crystal-lang.org/api/master/Hash.html#key_for(value)-instance-method
Raimondi has quit [Quit: WeeChat 2.5: ¡Chau!]
<FromGitter> <rmarronnier> Yes, I'll use this, it's more elegant
<FromGitter> <asterite> > in Ruby and Crystal `Hash` is ordered by insertion, but it's not wise to rely on it ⏎ Yes it is
Raimondi has joined #crystal-lang
<FromGitter> <asterite> I mean, Hash is sorted in Crystal and that's a guarantee I'll keep
<Stephie> After all, if we let Hash be unordered, the new Hash implementation would be a lot simpler :P
<Stephie> a lot of languages don't want people to rely on ordered hashes, but in Ruby and Crystal we make that guarantee
<FromGitter> <tenebrousedge> @asterite good to know. Is that in the docs?
<Stephie> https://crystal-lang.org/api/master/Hash.html: "Enumeration follows the order that the corresponding keys were inserted."
<FromGitter> <naqvis> @alex-lairan re your problem, I did some investigation and random testing, notice *0.30.0* have added check for handling *Generic Modules*. *0.29.0* wasn’t taking this into account (as per my investigation). So if you remove `Leftable` module and merge that into `Left` and `LeftException` struct, compiler will happily accept that.
fyber has quit [Read error: Connection reset by peer]
<FromGitter> <greenbigfrog> @absolutejam_gitlab was AFK. ⏎ Here the Dockerfile (stripped irrelevant parts): https://gist.github.com/greenbigfrog/c429d70183f24a136fda37bf5fb55f34 ⏎ If I remove the `command` section, kemal will complain about an unknown param `-c`
<FromGitter> <Blacksmoke16> what the problem @greenbigfrog
<FromGitter> <greenbigfrog> Just realized I didn't remember correctly how I had set up docker compose a while back
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
<FromGitter> <greenbigfrog> If I have `command: bash -c 'while !</dev/tcp/db/5432; do echo "waiting for database"; sleep 1; done; /website_launcher'` for my website, kemal (OptionParser) will complain about `Invalid option: -c` ⏎ Otherwise it'll work fine
<FromGitter> <greenbigfrog> (I've noticed I had 2 `command:` settings, doesn't fix the issue though)
laaron has joined #crystal-lang
<FromGitter> <Blacksmoke16> whats the dockerfile look like?
<FromGitter> <tenebrousedge> I have a suspicion that `command` is being passed to `entrypoint`
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d447ebc4b8ca519c9d2e73d]
<FromGitter> <Blacksmoke16> if you define both `CMD` sets the args passed to the entrypoint
<FromGitter> <greenbigfrog> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d447f07ee80d76164d846db]
<FromGitter> <Blacksmoke16> yea, remove the entrypoint
<FromGitter> <Blacksmoke16> since you're doing that in your dockerfile
<FromGitter> <greenbigfrog> wdym?
<FromGitter> <Blacksmoke16> since you're specifying an entrypoint, the command `command: bash -c 'while !</dev/tcp/db/5432; do echo "waiting for database"; sleep 1; done; /website_launcher'`
<FromGitter> <Blacksmoke16> is passing that to `/website-launcher`
<FromGitter> <Blacksmoke16> as args
<FromGitter> <greenbigfrog> oh. lol
<FromGitter> <Blacksmoke16> so just remove the `ENTRYPOINT ["/website-launcher"]` and it should be fine
<FromGitter> <greenbigfrog> so the `bash -c 'while !</dev/tcp/db/5432; do echo "waiting for database"; sleep 1; done; /website_launcher'` actually wasn't being run on any of the other services, except that they didn't complain because there's no OptionParser
<FromGitter> <greenbigfrog> lol
<FromGitter> <Blacksmoke16> prob yea
<FromGitter> <Blacksmoke16> was being executed like `/website-launcher bash -c 'while !</dev/tcp/db/5432; do echo "waiting for database"; sleep 1; done; /website_launcher'`
<FromGitter> <greenbigfrog> thanks
<FromGitter> <greenbigfrog> just checked, the wait part was never being run
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <greenbigfrog> now to figure out why it suddenty is unable to find the file...
<FromGitter> <greenbigfrog> this is weird. ⏎ As soon as I get rid of the `ENTRYPOINT` part, I get `website_1 | bash: /website_launcher: No such file or directory` ⏎ As soon as I add it back, I get the OptionParser error (as expected) ⏎ wtf [https://gitter.im/crystal-lang/crystal?at=5d4481a5757b7b19c84323ab]
<FromGitter> <Blacksmoke16> `COPY --from=0 /src/website-launcher /website-launcher`
<FromGitter> <Blacksmoke16> does that do anything?
<FromGitter> <Blacksmoke16> otherwise id suggest jumping into the container and poke around
<FromGitter> <greenbigfrog> oh. ok. I see... I have `_` in the docker-compose, and `-` in the Dockerfiles... oops
<FromGitter> <Blacksmoke16> :S
<FromGitter> <Blacksmoke16> that would do it
<FromGitter> <Blacksmoke16> you could just put all this in the dockerfile
<FromGitter> <Blacksmoke16> you only need to specify the command in the compose file when you want to override the command in the dockerfile
<FromGitter> <Blacksmoke16> or if you're using the same img for multiple services (i.e. diff commands)
<FromGitter> <greenbigfrog> yep. thanks
<FromGitter> <Blacksmoke16> np
<FromGitter> <greenbigfrog> (or in my case wait for the db port to be available)
<FromGitter> <Blacksmoke16> why do you have to do that in the first place?
<FromGitter> <Blacksmoke16> is the db not also part of the compose file?
<FromGitter> <Blacksmoke16> ``` depends_on: ⏎ - database``` [https://gitter.im/crystal-lang/crystal?at=5d4482ba475c0a0febea4ddb]
<FromGitter> <Blacksmoke16> is that not enough?
<FromGitter> <greenbigfrog> yes. But I need to init the db first (load data) ⏎ `depends_on` only waits for the container to start, not to be ready.
<FromGitter> <greenbigfrog> (*no)
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <tenebrousedge> the reasoning is that docker has no idea when a service will be ready
<FromGitter> <tenebrousedge> \#allsoftwaresucks
<FromGitter> <greenbigfrog> yep
<FromGitter> <greenbigfrog> I can't blame docker :)
teardown has joined #crystal-lang
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
laaron has joined #crystal-lang
<FromGitter> <absolutejam_gitlab> You can add healthchecks
<FromGitter> <absolutejam_gitlab> but nobody really adopted healthchecks
<FromGitter> <absolutejam_gitlab> I normally just add a startup script that polls for so long against a target
<FromGitter> <absolutejam_gitlab> oh yeah, that's what you said above ^
<FromGitter> <Blacksmoke16> or in reality just restart it after you seeded db
<FromGitter> <absolutejam_gitlab> @tenebrousedge `{|(k,v)| k }`?
<FromGitter> <tenebrousedge> just an example
<FromGitter> <absolutejam_gitlab> vs `{|k,v| k}`
<FromGitter> <absolutejam_gitlab> what's yours do?
<FromGitter> <tenebrousedge> `()` is a deconstruction operator
<FromGitter> <absolutejam_gitlab> does it unpack in a method that doesn't provide it?
<FromGitter> <tenebrousedge> it may or may not be optional
<FromGitter> <tenebrousedge> but probably if you were doing `reduce` you'd need it
<FromGitter> <tenebrousedge> `hash.reduce([]) {|memo, (k, v)| memo << k }`
<FromGitter> <absolutejam_gitlab> TIL
<FromGitter> <tenebrousedge> `map` will do deconstruction automatically (I assume the parentheses are inferred), but `reduce` will error unless you use parentheses there
<FromGitter> <tenebrousedge> I prefer to be explicit
<FromGitter> <Blacksmoke16> @kinxer https://www.youtube.com/watch?v=kmWTZ3KfnXE something a bit..different
<FromGitter> <kinxer> This is a lot.
<FromGitter> <kinxer> Also, they have 6 commercial breaks in a 12-minute YouTube video, which is a move.
<FromGitter> <Blacksmoke16> oh really?
<FromGitter> <Blacksmoke16> rip
<FromGitter> <tenebrousedge> if you need a method to take reversed negabinary numbers (as an array) and output reversed negated binary numbers (as an array): ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ I hate exercises like this >_< [https://gitter.im/crystal-lang/crystal?at=5d4499d7ff59f961b4032cfa]
<FromGitter> <kniknoo> Heilung!
mstanich has joined #crystal-lang
lucasb has quit [Quit: Connection closed for inactivity]
<FromGitter> <dscottboggs_gitlab> What gives? ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ https://carc.in/#/r/7cdv [https://gitter.im/crystal-lang/crystal?at=5d44ad00e939ab2447e655cb]
ht_ has quit [Remote host closed the connection]
<FromGitter> <tenebrousedge> definitely weird
<FromGitter> <tenebrousedge> maybe overload it?
<FromGitter> <dscottboggs_gitlab> oh, of course
<FromGitter> <tenebrousedge> `def method(arg); ... def method(arg, *splat)`
<FromGitter> <tenebrousedge> my take on this is that splat args are treated somewhat like a macro
<FromGitter> <tenebrousedge> but that may not be correct
mstanich has left #crystal-lang [#crystal-lang]
sorcus has quit [Ping timeout: 250 seconds]
flaviodesousa has quit [Quit: KVIrc 5.0.0 Aria http://www.kvirc.net/]
alex`` has quit [Ping timeout: 272 seconds]
<FromGitter> <kniknoo> The parameter setup is unusual, but I really like it. Make sure your read up in detail as it's a bit different from Ruby.
<FromGitter> <kniknoo> I'm watching the Q&A with core team on Reddit from April. So nice to to see your faces!