<FromGitter>
<naqvis> @wontruefree 👍 only 1 episode?
twistedpixels has quit [Ping timeout: 252 seconds]
twistedpixels has joined #crystal-lang
<raz>
hmm. this has been mentioned here before, sometimes it'd be useful if constants could be abstract (require a constant to be defined in inheriting class).
<raz>
like when you want to force the implementor to configure something for which there is no meaningful default
<raz>
atm the way to go seems to be (if i'm not missing something) to use an abstract method. not sure if it's rational but somehow that feels wrong to me.
<raz>
(i think mainly cause in such cases you'd clearly use a const in the parent class if inheritance wasn't needed)
<raz>
</micro-rant-of-the-day> :)
alexherbo2 has quit [Ping timeout: 265 seconds]
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
deavmi has quit [Client Quit]
deavmi has joined #crystal-lang
<jhass>
raz: I think you can do {{@type}}:FOO
<jhass>
eh ::FOO
<raz>
hmmm, with a type restriction even?
* raz
should experiment some more
<raz>
even w/o a type restriction it'd come in handy for me
<jhass>
I got that. I didn't get why the heck you would need that
<jhass>
seems Javaish again
<jhass>
it's not like you can compile a program when a constant is missing where you expect it
<raz>
maybe it is. it's just often my default thought when i make an abstract class and want to force the implementor to configure something
<jhass>
well I never got abstract classes
<raz>
yes, it's mostly about providing a helpful error message
<jhass>
I only use them in java and only because I don't have modules
<raz>
hm, well, yea, valid point
<raz>
perhaps i should just use modules more
<jhass>
and if my target platform would allow me even there I'd probably use interfaces with default implementations, so emulating modules
<raz>
well, and if my aunt was my uncle... :P
<jhass>
honestly I regret not having fought against abstract classes at this point
<raz>
it's no big deal anyway, just a detail that comes up here and there and that i haven't yet found a fully satisfying solution for yet
<raz>
i'm kinda torn on abstract classes. some of you seem to hate them, but i don't (yet) fully understand why
<raz>
i guess most (or even all) of the things i use them for could also be done with modules
<raz>
but abstract usually feels more natural to me, so that's what i reach for first
<raz>
perhaps i was ruined by my java childhood :/
<FromGitter>
<naqvis> raz i won't blame Java for that lol
<FromGitter>
<naqvis> its just a matter of preference
<FromGitter>
<naqvis> i am not big fan of inheritance so always prefer to go with composition
<raz>
i have to admit i actually like java to a degree. ;) it's a bit clumsy but the JVM is great, docs are great. people mostly ruined it with XML hell, dumb patterns and Iot nonsense
<FromGitter>
<naqvis> but that might be my preference
<raz>
IoC*
<FromGitter>
<naqvis> 😆
<jhass>
I hate them because a) they're redundant to modules (ignoring some compiler bugs maybe), you can even define abstract methods in them! (but don't, see b) and b) they stand for something that's the opposite of what made Crystal appealing to me in the first place, trying to be a language that brings the implicitness and convention oriented programming from dynamic languages to the static
<jhass>
world. They are relict errected by the everything needs to declared mindset. they're just on step away from hungarian notation
<FromGitter>
<naqvis> never been a fan of SpringBoot
alexherbo2 has joined #crystal-lang
<FromGitter>
<naqvis> though I spent whole lot of time on Struts lol
<raz>
oh god struts... (PTSD moment)
<FromGitter>
<naqvis> lol
<jhass>
and yeah, they also make you too quickly think in inheritance rather than composition
<raz>
jhass: yea, i can understand that in principle. i guess i just struggle to imagine crystal w/o abstract.
<jhass>
go write ruby for half a year
<jhass>
you'll get it
<raz>
oh i've done that for about 30 half-years now ;P
<jhass>
then I don't get you :P
<raz>
well, maybe it's a bounce-back reaction. in ruby everything is liquid, so i love the rigidity that crystal provides (with types, abstract as kinda-interfaces etc.)
<raz>
but you are of course right that modules pretty much do the same thing, so it might just be a "eh, this is almost like ruby again" kinda reluctance
<jhass>
did you seriously ever miss a abstract def each(&block) in Ruby's Enumerable?
<raz>
not on a daily basis, i don't think :p
<raz>
but being able to define interfaces in general is def sth i misse
<jhass>
it's kinda funny how that's the only Ruby core/stdlib example I can come up with
<raz>
method_missing etc. are fun. but we all know where that goes when the app grows
<jhass>
it's almost like you can design things without that
<jhass>
everything else is just overridable hooks with reasonable default implementations
<raz>
well. ruby is clay, crystal is lego. go-lang is lego with only 1x1 pieces. javascript is a pile of sand...
<jhass>
"bring your own water?" :D
<raz>
can all be used to arrange certain formations, but with different levels of rigidity
<raz>
yea, pour water and hope it stays in place for a minute :p
<jhass>
I want clay. Clay that tells me whether it cracks before I put it into the oven
<jhass>
this is what I initially saw in Crystal
<jhass>
I don't want to go out and buy a new lego brick because my idea is not realizable with the standard bricks
<raz>
heh... ok, maybe we're stretching that analogy a bit now. but yea, crystal could also be seen as ruby with an oven :p
<raz>
anyway, i could prob live w/o abstract if it was to be removed at some point
<raz>
but i imagine that would break too many existing code to be realistic
<jhass>
unfortunately
<jhass>
I mean I guess I'm using this as a proxy discussion for the more general trend anyways
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
<raz>
nom nom, new commits on gripen
<raz>
can't wait for this thing to land
<jhass>
I'm really unhappy with the whole Digest/DigestIO API. Maybe we should mark it as experimental for 1.0
<jhass>
which I think should be more IO yielding builder method style
<jhass>
this whole #final thing and that changing what you can and should do with the object is terrible
<FromGitter>
<naqvis> i guess it just try to mimic how golang has defined Hash (https://pkg.go.dev/hash?tab=doc) interface. Where one need to call `Sum` to get the current hash. In Crystal its called 'final`
<FromGitter>
<Blacksmoke16> there are two built in ones, `Groups` and `Version`. But custom ones would need to be added like that
<FromGitter>
<naqvis> wouldn't it be good to have kind of registration mechanism where one can restier the strategy implementation, thus each code can use that without instantiating separately?
<FromGitter>
<naqvis> just thinking ....
<FromGitter>
<naqvis> i assume built-in one would behave like i said above
<FromGitter>
<naqvis> where dev don't need to instantiate them
<FromGitter>
<naqvis> or my understanding is wrong?
<FromGitter>
<Blacksmoke16> my thinking was the user could define their own serializer object in order to abstract this stuff. or even a method to get the context
<FromGitter>
<Blacksmoke16> built in ones are like
<FromGitter>
<Blacksmoke16> `context.groups = ["one", "two", "three"]` and that would add the group strategy
<FromGitter>
<Blacksmoke16> user could also reopen the context to add some method to make adding it easier
<FromGitter>
<naqvis> aha
<FromGitter>
<naqvis> excellent design choice 👍
<FromGitter>
<Blacksmoke16> or in a DI example, define a customer serializer, inject the default serializer, do extra logic and just pass that onto the original
<FromGitter>
<naqvis> yeah, make sense
<FromGitter>
<Blacksmoke16> i dont really see fancy strategies being used for now, i would rather it be a compile time construct, at least for annotation based approaches
<FromGitter>
<Blacksmoke16> but that would depend on some features that dont exist yet
<FromGitter>
<Blacksmoke16> we have one at work, `IgnoreOnUpdate` and `IgnoreOnCreate` that allows ignoring properties on PUT and POST requests. is kinda neat
<FromGitter>
<naqvis> true , but it does offer these extension points and i'm sure there will be quite few use-cases for people developing framework(s) or similar libraries on top of it
<FromGitter>
<Blacksmoke16> ideally it would have both runtime and compile time strategies
<FromGitter>
<naqvis> agree and believe what you were asking for is a kind of RTTI or reflection, to retrieve things at run-time. indeed an excellent point, but don't think atm Crystal will plan to support this idea
<FromGitter>
<naqvis> your hack is already clean-enough, its just too complicated to manage and add new strategies
<FromGitter>
<HankAnderson> it's pretty ugly
<FromGitter>
<Blacksmoke16> hack falls down with more than one type that has annotation
<FromGitter>
<Blacksmoke16> as you get unions and such. Generics would work, but kinda even more of a hack to have to add a strat for each type ha
<FromGitter>
<naqvis> true
<FromGitter>
<Blacksmoke16> yea, there was an issue for reflection iirc. But i dont see it coming anytime soon/if at all
<FromGitter>
<naqvis> yeah, might be in 2.0 or above
<FromGitter>
<Blacksmoke16> user could define their own base class with common utilities
<FromGitter>
<j8r> The object is forced to be one thing, and can include optional features
<FromGitter>
<j8r> Yes
zorp_ has joined #crystal-lang
<FromGitter>
<wontruefree> @naqvis We have 2 more recorded that are being edited and 1 more in the pipeline
<FromGitter>
<wontruefree> we should have some more out soon
<FromGitter>
<wontruefree> Also people have been asking so we have a website podcast.chicagocrystal.org
<FromGitter>
<wontruefree> it has more services and feeds for podcast players
<FromGitter>
<didactic-drunk> @jhass How would I incrementally hash streamed data received in a loop with a builder interface?
<jhass>
wrap the builder around your receive loop
<jhass>
or sender loop
<jhass>
you already have a point where you start computing the digest and a point where you finish that. A builder API just enforces the presence of these points with no incompatible calls before or after the end point. Whatever your code between those points, just wrap it into the builder
<jhass>
I'd argue running a digest over a *partial* stream is not the common usecase
<FromGitter>
<Blacksmoke16> its prob just putting everything into the unmapped hash
<FromGitter>
<brunto> roles is a jsonb from a postgresql query
<jhass>
and even for that it's not too terrible
<FromGitter>
<Blacksmoke16> right but what's its structure?
<FromGitter>
<Blacksmoke16> you would need to create types that map to the structure in order to use `.from_json`
<FromGitter>
<Blacksmoke16> like you dont have any properties within your `A` type, so everything is going into a `JSON::Any` hash due to the `Unampped` module
<FromGitter>
<brunto> I want to put everything inside an unmappad hash because I don’t know the structure and the structure can change.
<FromGitter>
<Blacksmoke16> ah
<jhass>
wrap it into a method from which you can return unless msg and you can save the outer loop state variable
<FromGitter>
<Blacksmoke16> so whats the problem then?
<FromGitter>
<Blacksmoke16> ORM is prob converting to a hash for you
<FromGitter>
<Blacksmoke16> versus just providing the JSON string
<FromGitter>
<brunto> This is returned by postgresql jsonb
<FromGitter>
<brunto> :)
<jhass>
who writes it?
<jhass>
how do you read it?
<FromGitter>
<brunto> I get it with a simple query with psql
<FromGitter>
<didactic-drunk> @jhass You say it's not a common use case but libsodium secret stream kind of requires this as do other cryptographic streaming protocols.
<jhass>
brunto: mind sharing a screenshot of the terminal session or so?
<jhass>
or a literal copy paste from it
<FromGitter>
<didactic-drunk> `EOM`isn't available until after decryption as the protocol is intentionally opaque.
<jhass>
didactic-drunk: I don't say I didn't an extensive case study, just that the API seems brittle and it feels like it should be possible to do a better oen
<jhass>
* I did I mean
<FromGitter>
<wontruefree> @raz: It should be hosted on itunes spotify and google. I have opened accounts with some other providers but dont know which one pocket cast uses. You can always check out podcast.chicagocrystal.org and grab the RSS feed. I will look into pocketcasts
<raz>
wontruefree: yep, it seems to be on literally every other platform except the one i use ;( (it's also a 404 when you click on it on your page)
<FromGitter>
<didactic-drunk> I'm not against an `IO` interface even as the default. As long the current interface remains even if it's only recommended for advanced use.
<FromGitter>
<rishavs> gui & gpu support coming for wsl apps
<FromGitter>
<kinxer> @raz Btw, re RSS on PocketCasts, you should be able to just paste the feed link into the search bar.
<raz>
kinxer: ah, gtk thx!
<raz>
already added this one now, but might come in handy another time
<FromGitter>
<cbortz> Hey y'all, I'm having an issue trying to get the amber framework specs working locally. I'm using crystal v0.34.0 on macOS installed with asdf. When I run the specs, I get the following error: ⏎ ⏎ ```crystal spec ./spec/amber --debug --verbose``` ⏎ ⏎ Notably I can run the specs just fine when I use Cystal v0.34.0 installed via Homebrew. ... [https://gitter.im/cr
<FromGitter>
<Blacksmoke16> @naqvis ah, yea `IOBackend` is for writing *TO* an `IO`, duh
<FromGitter>
<kinxer> Why do you think it was deleted? Did he email the security email or something?
<FromGitter>
<Blacksmoke16> didnt have any good answers? :P
<FromGitter>
<naqvis> lol
<straight-shoota>
ditched all my questions about specific issues with the official docker image, just mentioned vague rationales
<straight-shoota>
So it feels very shady
<FromGitter>
<kinxer> I mean, the removeddit link showed me a reply with container vulnerability comparisons. That seems like a decent reason (if it's true).
<FromGitter>
<Blacksmoke16> so running the image would plop you into `/crystal-app` as `crystal` user
<FromGitter>
<Blacksmoke16> but given its a container does it really matter if you're not root
<FromGitter>
<kinxer> Huh. Yeah, after reading the whole thing, I agree that it's pretty sketchy.
<FromGitter>
<kinxer> Though, clearly, just deleting the post in the first place after barely any conversation is sketchy.
<FromGitter>
<naqvis> agree, but I think one point raised is indeed valid, that we should be running some kind of container scanner to check against vulnerabilities
<FromGitter>
<naqvis> i don't know if Crystal current CI system does have any similar check
<FromGitter>
<j8r> I don't think it is needed
<FromGitter>
<naqvis> why not?
<FromGitter>
<j8r> Because we are up-to-date.
<FromGitter>
<naqvis> provided you are building against latest distro
<straight-shoota>
The crystal images are usually based on the latest LTS release
<FromGitter>
<j8r> Using the latest stable distribution, it is near guaranteed to have the latest security patches
<FromGitter>
<j8r> But the issue is: what about those built?
<straight-shoota>
If Ubuntu can't update their libraries to remove vulnerabilities, how should we be able to do that?
<FromGitter>
<j8r> Yeah, OS/package maintainers surely already have means to be informed of news about updates/patches
<FromGitter>
<j8r> One issue though:
<FromGitter>
<j8r> What's happen if the container built for, e.g., Crystal 0.34.0, now several months old, has security breach discovered now?
<FromGitter>
<j8r> It is not really an issue now, because version releases are quite fast paced
<FromGitter>
<j8r> But still, more the time between releases is long, bigger the issue of out-of-date "dangerous" packages is
<straight-shoota>
We can rebuild the image and push it to dockerhub
<jhass>
anybody noticed the formatter always forcing ternaries on a single line?
<FromGitter>
<j8r> @naqvis I'd be curious about alpine:latest
<FromGitter>
<j8r> should not have much
<FromGitter>
<sam0x17> anyone familiar with https://github.com/axvm/cake know if it is possible to do nested tasks / tasks with spaces in them e.g. `cake db migrate` rather than `cake db_migrate`
<FromGitter>
<sam0x17> eh I'll just do the rails `db:migrate` syntax that seems to work in a string
<FromGitter>
<Blacksmoke16> would need a converter
<FromGitter>
<Blacksmoke16> er not even sure if that would help
<FromGitter>
<watzon> Meh
<FromGitter>
<watzon> I'll just use JSON
<FromGitter>
<Blacksmoke16> 👍
<FromGitter>
<Blacksmoke16> cant use `Enum` is union so yea
<FromGitter>
<Blacksmoke16> in a*
<FromGitter>
<watzon> Hmm with `JSON::Field` I always thought that `key` was the elements key, and that `base` would be the root key. But it seems like it's the opposite? So: ⏎ ⏎ ```{ ⏎ "key": { ⏎ "base": "value" ⏎ } ⏎ }``` [https://gitter.im/crystal-lang/crystal?at=5ec46330940fa238d6027529]
<FromGitter>
<watzon> And this model ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ but it doesn't work because there are multiples of the same key. If I comment out all but one of the fields with a `key: "base"` it works though, so I know it's getting the value from the right place. [https://gitter.im/crystal-lang/crystal?at=5ec463cde8153a398061072a]
<FromGitter>
<Blacksmoke16> you have it backwards i think
<FromGitter>
<Blacksmoke16> root would be `base`, and `key` would be like `HP` and such iirc
<FromGitter>
<watzon> I had it the other way around at first, but it doesn't work
<FromGitter>
<Blacksmoke16> oh?
<FromGitter>
<watzon> This way works, but it complains about multiples of the same key
<FromGitter>
<Blacksmoke16> rip
<FromGitter>
<watzon> Has to be a bug. There's no way that's intended behavior.
<FromGitter>
<j8r> I need your opinion on this API: https://play.crystal-lang.org/#/r/93rt ⏎ Note: I have not implemented annotation yet, I would like to be on par with `JSON::Serializable` (and `YAML`)
<FromGitter>
<Blacksmoke16> serializable stuff is implemented with case