ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.34.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
travis-ci has joined #crystal-lang
<travis-ci> crystal-lang/crystal#5d65a7a (master - Support DragonFly(BSD) (#9178)): The build passed. https://travis-ci.org/crystal-lang/crystal/builds/681751869
travis-ci has left #crystal-lang [#crystal-lang]
<DeBot> https://github.com/crystal-lang/crystal/pull/9178 (Support DragonFly(BSD))
<FromGitter> <ImAHopelessDev_gitlab> wtf does `uninitialized ` mean anyway
<FromGitter> <ImAHopelessDev_gitlab> why would i want a variable to be `uninitialized`???
<FromGitter> <ImAHopelessDev_gitlab> isn't the entire point of writing a variable, is to create it?
travis-ci has joined #crystal-lang
travis-ci has left #crystal-lang [#crystal-lang]
<travis-ci> crystal-lang/crystal#55f89a1 (master - Parser: fix parsing of ambiguous '+' and '-' (#9194)): The build passed. https://travis-ci.org/crystal-lang/crystal/builds/681752454
<DeBot> https://github.com/crystal-lang/crystal/pull/9194 (Parser: fix parsing of ambiguous '+' and '-')
<FromGitter> <watzon> It basically creates a null pointer to the value @ImAHopelessDev_gitlab
<FromGitter> <watzon> It's really only useful for C interops and IO::ByteFormat
<FromGitter> <ImAHopelessDev_gitlab> so moreso of fiddlinga round with c linking and whatnot?
<FromGitter> <watzon> Basically. Not something you're gonna use much unless you do a lot of wrapping C libraries
<FromGitter> <watzon> And even then you can always just use `Pointer.malloc` which a lot of people do
<FromGitter> <ImAHopelessDev_gitlab> makes sense
<FromGitter> <ImAHopelessDev_gitlab> well, good to know. cause i was like wtf
<FromGitter> <ImAHopelessDev_gitlab> "some random value, garbage, unreliable" ROFL
<FromGitter> <ImAHopelessDev_gitlab> G A R B A GE
<FromGitter> <watzon> Yeah it's more or less a placeholder
juanfra_ has left #crystal-lang ["User left"]
<FromGitter> <ImAHopelessDev_gitlab> > asterite always says don't use uninitialized EVER, FULL STOP ⏎ ⏎ @oprypin NamedTuples: hold my beer!
straight-shoota has quit [Ping timeout: 240 seconds]
<FromGitter> <Blacksmoke16> how would you go about getting the sha256 hash of a file?
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eab7bef347bd6163049f8d2]
<FromGitter> <Blacksmoke16> doesnt seem to be correct
<FromGitter> <watzon> Idk about `DigestIO`, but you should be able to just use `OpenSSL::Digest`
<FromGitter> <watzon> I think just ⏎ ⏎ ```digest = OpenSSL::Digest.new("SHA256") ⏎ digest.update(file_slice) ⏎ digest.hexdigest``` [https://gitter.im/crystal-lang/crystal?at=5eab7d6197338850a2dd807f]
<FromGitter> <Blacksmoke16> seems reading the file directly works, but trying to do it via IO or response.body does not
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eab7dc4a9de3d01b1ded2fe]
<FromGitter> <Blacksmoke16> fwiw
<FromGitter> <watzon> Hmm, last time I tried to get `DigestIO` to work I wasn't able to
<FromGitter> <watzon> We need better docs for that stuff haha
<FromGitter> <Blacksmoke16> also API could prob be updated to use https://crystal-lang.org/api/master/OpenSSL/Algorithm.html
<FromGitter> <watzon> Yeah true
<FromGitter> <Blacksmoke16> yea fwiw, `DigestIO` just doesnt seem to produce correct result
sorcus has quit [Ping timeout: 265 seconds]
alexherbo2 has quit [Ping timeout: 256 seconds]
Vexatos has quit [Quit: ZNC Quit]
Vexatos has joined #crystal-lang
sorcus has joined #crystal-lang
_ht has joined #crystal-lang
alexherbo2 has joined #crystal-lang
sz0 has joined #crystal-lang
<raz> i've used digestio and i think it worked as advertsed
<jhass> mode = is passing a positional argument and assigning a local variable btw :)
<raz> yeh i should put some ameba in there, but i think it ran away screaming when it realized there's code in a string
<raz> ..in a macro
alexherbo29 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 246 seconds]
alexherbo29 is now known as alexherbo2
<oprypin> 🙃
alexherbo22 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 246 seconds]
alexherbo22 is now known as alexherbo2
return0e has quit []
sagax has quit [Read error: Connection reset by peer]
sagax has joined #crystal-lang
straight-shoota has joined #crystal-lang
v2px__ has joined #crystal-lang
Flipez5 has joined #crystal-lang
Flipez has quit [Read error: Connection reset by peer]
Flipez5 is now known as Flipez
zorp_ has quit [Ping timeout: 258 seconds]
v2px__ has quit [Ping timeout: 256 seconds]
_ht has quit [Remote host closed the connection]
_ht has joined #crystal-lang
return0e has joined #crystal-lang
<FromGitter> <Blacksmoke16> hm, wonder why its not for me then raz
<raz> i'm the same with github actions. i wonder what they are smoking
<raz> i think i'll give up on it and go back to circle. they can't even generate a proper badge icon, that's just silly
<FromGitter> <Blacksmoke16> hm?
<raz> they have a button to give you a badge. it spits out markdown.
<FromGitter> <Blacksmoke16> ah
<FromGitter> <Blacksmoke16> https://github.com/blacksmoke16/oq/workflows/CI/badge.svg is the one i been using
<raz> except... the badge doesn't link to the build. when you click on it... you get to see a bigger version of the "build passed" icon
<FromGitter> <Blacksmoke16> yea...
<raz> it's one of these tiny things that are so needless and idiotic that they can make me abandon an entire platform
<raz> or well, a half-baked CI system...
<FromGitter> <Blacksmoke16> i dunno, i been happy with it
<FromGitter> <Blacksmoke16> what are you trying to do?
<raz> i click on these badges and many others probably also do. to get a quick peek on how many dots that projects test suite has. and perhaps glimpse at the yml. gives a good first idea/impression.
<FromGitter> <tenebrousedge> I like CCI
<FromGitter> <Blacksmoke16> so just fix the link?
<raz> yea well, if i knew how to link to the latest build
<raz> their urls don't give it away
<FromGitter> <sam0x17> is there a way I can assert that a macro argument must be a literal
<FromGitter> <sam0x17> and not something dynamic
<FromGitter> <Blacksmoke16> afaik you can just link to a specific workflow
<raz> black: yea that doesn't link to the build
<raz> it links to a random list of builds on whatever branches
<FromGitter> <tenebrousedge> @sam0x17 why?
<FromGitter> <Blacksmoke16> is a `branch=master` query param
<FromGitter> <Blacksmoke16> `?query=branch%3Amaster`
<FromGitter> <sam0x17> because I have a macro that breaks if you give it something dynamic and it just wasted some time for me that would have been saved if it gave a better compiler error than some variable is undefined
<raz> i don't want to link to a list, but to the build
<raz> y'know, like every other CI system in the universe does it
<FromGitter> <Blacksmoke16> :shrug:
<raz> yea, it's a little thing. just annoys me cause the whole idea of a CI system is to get these little things right and automate them. :shrug:
<FromGitter> <Blacksmoke16> it is still in beta, suggest the feature or see if it was already suggested
<raz> no, i complain on the internet, that has to be enough
<FromGitter> <tenebrousedge> I mean, I don't know offhand how you could do that, but I'm also confused by how your macro doesn't work with "something dynamic". Maybe that part is fixable? Do you have an example?
<FromGitter> <Blacksmoke16> oh yea you can do that @sam0x17
<FromGitter> <Blacksmoke16> `{% raise "#{arg} should be BoolLiteral not #{arg.class_name}" unless arg.is_a? BoolLiteral %}`
<FromGitter> <Blacksmoke16> something like that
<FromGitter> <sam0x17> for a string, `StringLiteral`?
<FromGitter> <Blacksmoke16> yea
<FromGitter> <sam0x17> thx!
<FromGitter> <naqvis> > yea fwiw, `DigestIO` just doesnt seem to produce correct result ⏎ That's because you are just wrapping the IO, but not performing any read on the data. You should read the data from `DegiestIO` instance for it to perform update internally. Then perform `hexdigest` action
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eac2a183d58de7a38ead588]
<FromGitter> <Blacksmoke16> :thinking: then whats the benefit of doing that versus just doing `file.gets_to_end` on the non IO digest?
<FromGitter> <naqvis> best use case I think of is `piping` the IO
<FromGitter> <naqvis> where yo do read and at end, perform the hash check
<raz> yap
<jhass> also to avoid reading everything into memory I guess
<FromGitter> <naqvis> true thing
<FromGitter> <Blacksmoke16> gotcha
<jhass> but tbf we probably should have IO consuming overloads on Digest for that
<FromGitter> <naqvis> but wouldn't that change the meaning of this function?
<FromGitter> <naqvis> in that case, one would only be able to perform checksum at the end of IO
<FromGitter> <naqvis> what if you need to perform at bulks?
<FromGitter> <naqvis> currently it just provides the digest of what's been read so far
<jhass> then you'll wrap it into an IO::Sized or so or use DigestIO
<FromGitter> <naqvis> yeah, true
<FromGitter> <naqvis> my understanding of IO is kind of stream
<jhass> not saying to replace anything
<FromGitter> <naqvis> so it should perform in that manner
<FromGitter> <naqvis> if one need to exhaust the stream, then they should do it explicitly
<FromGitter> <naqvis> agree, just sharing my thoughts
<jhass> I can imagine "give me the digest of that file" to be a common usecase, so why not make it as easy as File.open() {|io| Digest.hexdigest(io) }
<FromGitter> <Blacksmoke16> ^
<FromGitter> <Blacksmoke16> based on other `IO` based things i just figured it would read from it and bash the hash on it
<FromGitter> <Blacksmoke16> base*
<FromGitter> <naqvis> hmm, others IO also don't read implicitly otherwise told to do so
<FromGitter> <naqvis> then why the expectation for this IO to read automagically?
<jhass> things consuming an IO as a paramter very well do so
<jhass> IO.copy being the most obvious example
<FromGitter> <naqvis> yeah, that's where dev is explicit and asking for cosumption
<jhass> How aren't they in Digest.hexdigest(io)?
<jhass> I'm confused
return0e has quit []
<FromGitter> <didactic-drunk> @jhass is hashing a file without any other processing that common of a use case to justify `Digest.hexdigest(io)`?
<jhass> I don't know, but I can imagine it to be the number two usecase of digest after hashing a short in memory string
<FromGitter> <didactic-drunk> I think that would be #3. #2 Is using some info in the data stream along with hashing it. Such as encryption/decryption/compression/serialization/searching/etc.
<jhass> well I'm imaginging verification of downloaded files
<jhass> seems more common than rolling your own compression or encryption, no?
<FromGitter> <didactic-drunk> Maybe it depends. 90% of the time I have an encrypted stream or am verifying with the intent to process it, not hashing it to discard the data.
<FromGitter> <didactic-drunk> Actually? When would you discard the data?
<jhass> verification before operating on the data makes sense, no?
<FromGitter> <tenebrousedge> if your app only cares whether x content is present
<jhass> so if it's a bit to big to reasonably hold in memory, you'd read it twice anyways
<FromGitter> <didactic-drunk> If `Digest.hexdigest(io)`performs the reads where does the data go?
<jhass> or if you just verify and then pass to external tools
<jhass> nowhere
<jhass> of course you wouldn't use it on a network stream
<FromGitter> <tenebrousedge> probably, unless you were checking whether something existed elsewhere
<jhass> unless you really don't care about the actual data
<FromGitter> <didactic-drunk> Then I think you use case is rather uncommon. Almost every verification hash I've done is verifying while processing, not hashing an actual file to get a single result.
<FromGitter> <didactic-drunk> Even downloads use the data: ```
<FromGitter> <didactic-drunk> The normal pattern I'd use to avoid saving corrupt files: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ Swap `DigestIO` for `digest.update` if you prefer. [https://gitter.im/crystal-lang/crystal?at=5eac3afa7975db7ebfda8803]
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
<FromGitter> <didactic-drunk> Maybe a new IO method would shorten both our use cases? ⏎ ⏎ ```IO.each_slice { |s| digest.update s } ⏎ digest.hexdigest``` [https://gitter.im/crystal-lang/crystal?at=5eac3df80b23797ec05714cc]
<FromGitter> <ondreian> Is there some way to capture the rest of an Array's members, like in ruby, when destructuring. I've perused the documentation, but didn't see anything: ⏎ ⏎ ```first, second, *rest = %w(one two three four)``` [https://gitter.im/crystal-lang/crystal?at=5eac3f2b97338850a2df6837]
<FromGitter> <Blacksmoke16> not that im aware of
<FromGitter> <tenebrousedge> can I pass a C function an `Array` or does it have to be a `StaticArray` ?
<jhass> anything that provides #to_unsafe should be possible
<jhass> and in fact Crystal will even automatically invoke #to_unsafe for you in C fun calls
<FromGitter> <tenebrousedge> yes I noticed that
<jhass> the difference basically is that StaticArray is stack allocated, while Array is heap allocated
<jhass> so if you pass a StaticArray and the C side keeps that pointer around after returning to you and then you exit the stackframe where you allocated that... fun
<FromGitter> <tenebrousedge> and apparently you can't do `n = 5; StaticArray(LibC::Char, n)`
<jhass> otoh it's usually less performance overhead to allocate
<jhass> yeah, because Crystal needs to generate code to make the right room in the stackframe
<jhass> (well, it just tells LLVM to do so, but)
<FromGitter> <tenebrousedge> one would think that could be possible in a macro though
<FromGitter> <tenebrousedge> I mean, without interpolation
<jhass> what I'm trying to say is that the type declared in LLVM for StaticArray is the same as clang would use for a char[5] in C
<FromGitter> <ondreian> yeah, since you're basically saying `Enumerable#skip(N)`
<jhass> you lost me there
return0e has joined #crystal-lang
<FromGitter> <Blacksmoke16> ☝️ April 29, 2020 5:26 PM (https://gitter.im/crystal-lang/crystal?at=5ea9f0eb7a24ff01b0f01520) ⏎ ⏎ Regards to this, I thought of the problem with it. That example works in this case, and probably for most simple things.
<FromGitter> <Blacksmoke16> \cc jhass
<FromGitter> <Blacksmoke16> however, in the case where the writer would have dependencies of its own, and/or those dependencies have dependencies, it get a bit tricker
<FromGitter> <Blacksmoke16> or in the case where you want to inject the same instance into another object
rcvalle has quit [Remote host closed the connection]
rcvalle has joined #crystal-lang
_ht has quit [Remote host closed the connection]
_ht has joined #crystal-lang
<FromGitter> <didactic-drunk> Is there a way to stack allocate a dynamic array of bytes?
<jhass> No
<jhass> If you know the upper bound you can allocate a static array of that size, get a pointer to it and stuff that into a slice with the actual size
ht_ has joined #crystal-lang
_ht has quit [Ping timeout: 258 seconds]
ht_ is now known as _ht
<FromGitter> <didactic-drunk> The upper bound is rare. I'm trying to avoid increasing the stack size unnecessarily.
flips has joined #crystal-lang
<jhass> where's the data coming from?
<jhass> IO?
<jhass> the usual pattern is to just have a statically sized buffer and a loop
<jhass> if your buffer is bigger or even close to the L1 cache, you'll likely have basically no performance benefit anymore anyways
<jhass> stack allocated is essentially faster because it's known ahead of time
<jhass> so it needs less bookeeping, is better prefetched etc
<jhass> if it can't be prefetched because it doesn't even fit into the cache anymore...
<FromGitter> <didactic-drunk> Not IO. Custom digest output sizes.
<jhass> custom as in user supplied?
<FromGitter> <didactic-drunk> Yes.
<FromGitter> <didactic-drunk> There are limits on likely and useful output sizes but no strict limit.
<jhass> huh, I kinda thought hash functions have a fixed width
<FromGitter> <didactic-drunk> > BLAKE2x variants, which can produce digests of arbitrary length.
DTZUZU has joined #crystal-lang
<jhass> seems to have an upper bound of 64 bytes though
<jhass> that's not a lot, I'd just allocate a buffer that big
DTZUZU2 has quit [Ping timeout: 260 seconds]
<FromGitter> <didactic-drunk> SHAKE-128 and SHAKE-256 allow an arbitrary output length, which is useful in applications such as optimal asymmetric encryption padding.
<jhass> whether the trail is actually used or not shouldn't matter so much
<FromGitter> <didactic-drunk> I think SHA3 also allows any size. New algorithms are... I'd say experimentally using them.
<FromGitter> <didactic-drunk> The longer digest outputs.
<FromGitter> <didactic-drunk> @jhass The size is unlimited, not 64. You'd need to look for Blake2X in the paper above. Or use this one (https://blake2.net/blake2x.pdf).
<jhass> well, my bad trusting the very third paragraph of the very homepage
<jhass> how do the reference implementations deal with this?
DTZUZU2 has joined #crystal-lang
DTZUZU has quit [Ping timeout: 258 seconds]
_ht has quit [Remote host closed the connection]
_ht has joined #crystal-lang
<FromGitter> <jwaldrip> Did anything ever come of this? https://new.crystalshards.org/shards/github/crystal-lang/crystal-env
<jhass> how do you mean?
olbat has joined #crystal-lang
<FromGitter> <didactic-drunk> Depends. Some implementations use an `IO` stream for arbitrary output. I'll probably provide similar. But there's are 2 common uses of 128 <> 1-2kb output that can be optimized. 1) `hexdigest`. The intermediary `Bytes` could be stack allocated, but an exact ceiling is per application and uncomon. 2) Signatures. Same problem and solution. Typical uses are 1-2kish digest output. Some people will
<FromGitter> ... go crazy and up the signature size to who knows. Consider those messages rare but shouldn't crash.
<FromGitter> <jwaldrip> Well i guess my main question is there community conensus on how to set the active environment
<FromGitter> <Blacksmoke16> prob an env var specific to your app
<FromGitter> <jwaldrip> I have seen suggestions to check the compilers release flag. Is that sufficent or have frameworks used other methods
<FromGitter> <j8r> Don't see the usefulness of https://github.com/crystal-lang/crystal-env @jwaldrip
<FromGitter> <Blacksmoke16> main benefit is it would allow having a common flag to determine env
<FromGitter> <Blacksmoke16> env var*
<FromGitter> <j8r> Setting an environment variable with the name of the language inside is out place
<FromGitter> <j8r> that's like setting `CXX_ENV` or `C_ENV` for other languages
<FromGitter> <jwaldrip> right now you have `AMBER_ENV` and `LUCKY_ENV` but I think it would be great if we just had a way to do it accross the community.
<FromGitter> <jwaldrip> Convention over Configuration
<FromGitter> <Blacksmoke16> maybe, just saying that i could see the benefit of a single common flag for determining env
<FromGitter> <Blacksmoke16> yea, then if you include shards etc they would just pick up that env as well
<FromGitter> <Blacksmoke16> but not really a big deal :shrug:
<FromGitter> <jwaldrip> exactly
<FromGitter> <j8r> just `ENV` then?
<FromGitter> <jwaldrip> even thats fine
<FromGitter> <jwaldrip> But nothing wrong with wrapping it in a module either
<FromGitter> <j8r> the user does not have to know (not always) in which technos a tools is made
<FromGitter> <jwaldrip> hence the reason for that lib
<FromGitter> <Blacksmoke16> @j8r is mainly talking about the env var name of that lib
<FromGitter> <j8r> yep, and looking at the logic https://github.com/crystal-lang/crystal-env/blob/master/src/env/core.cr
<FromGitter> <j8r> not a big deal to implement it without depending from an external library
JuanMiguel has joined #crystal-lang
<FromGitter> <j8r> ho ok, thanks jhass
JuanMiguel has quit [Client Quit]
<FromGitter> <jwaldrip> Last line of that discussion was the intro of the library I posted earlier
<FromGitter> <j8r> I see
<FromGitter> <jwaldrip> I mean, why don't library maintainers just all start using that lib
<FromGitter> <jwaldrip> @paulcsmith @drujensen
<FromGitter> <j8r> this lib does not bring much
<FromGitter> <Blacksmoke16> idea is good, impact is quite small
<FromGitter> <Blacksmoke16> i could see use cases of wanting to run your webapp in prod mode, but maybe drop some other lib down to debug something (for extra logs for example)
<FromGitter> <j8r> that's up to framework devs to name their env vars at the end
<FromGitter> <jwaldrip> At the very least defaulting back to the crystal one would be great
<FromGitter> <jwaldrip> the new crystal shards uses Orion, Clear, and Mosquito. It would be awesome if those had debug like settings that would just fall back to the crystal setting in a given environment
<raz> this is a lost battle
<FromGitter> <jwaldrip> even if its just `ENV["AMBER_ENV"] ||= ENV["CRYSTAL_ENV"]`
<FromGitter> <jwaldrip> @raz, where is the decision that it's lost?
<raz> there never was a decision. if there had been one we'd all be using ENV.
<FromGitter> <j8r> for me `CRYSTAL_` are compiler env vars
<raz> but there's RAILS_ENV, NODE_ENV, AMBER_ENV, CRYSTAL_ENV, ...
<raz> every real world app has to set a bunch of those. doesn't make a difference if it's 5 or 6
<raz> there's just a widespread misconception about what the unix env even is. like, they put stuff in .env and then read that file from the app instead of from the actual env, etc.
<FromGitter> <j8r> The issue is not only the environment name, but the values it can take
<raz> yea, in reality there's only one env. and if the app wants to know _which_ env it is, the name for that would be ENV (or even more mundane sth like "NAME")
<jhass> I think the main issue is that people think it's framework configuration while it should be an application setting
<raz> but none of that is standardized
<jhass> most apps would pass it through to their framework initializer, but still
<FromGitter> <j8r> yep right
<FromGitter> <j8r> For example, if I made a GitLab/Gitea in Crystal using Lucky
<FromGitter> <j8r> I don't see users setting `LUCKY_ENV` to have their app in prod/dev setup
<FromGitter> <j8r> I agree agree jhas
<FromGitter> <j8r> However Gitea has `MACARON_ENV`
<raz> in my apps i enforce ENV and patch anything that disrespects it
<raz> but that's just my personal windmill fight
<FromGitter> <j8r> Sounds good, `ENV` is usually enough
<raz> this prefixed *_ENV stuff just doesn't make sense and can even be dangerous. (DATABASE_URL = prod, RAILS_ENV = test ...)
<FromGitter> <j8r> raz, you do like if I set `ENV`, other env vars can be set in the app?
<raz> hmm, not sure how you mean?
<FromGitter> <j8r> If I set `ENV=prod`, the application will set configuration according to it (like databases, logging, etc)
<raz> oh yea, it should. e.g. ENV=development means more logging by default, which could still be overridden with an explicit LOG_LEVEL, etc.
<raz> however in practice it's easy to clash with other things, so i guess it should rather be APPNAME_LOG_LEVEL or such
<FromGitter> <j8r> right
<raz> (i.e. `ENV` describes what type of environment it is, the other vars configure the individual apps that live in the environment)
<FromGitter> <j8r> The good old `.env-prod` do the job. Systemd support it, any shell too
<raz> yup
<raz> https://direnv.net/ is helpful for auto-loading/switching between envs when cd'ing around
<raz> but people have different opinions on all that
<FromGitter> <j8r> noice
<FromGitter> <j8r> even if I prefer to do it manually
<FromGitter> <j8r> with `set -a; . ./.env-test; set +a`
<FromGitter> <j8r> need to do like this because of comments inside
<raz> yea, it's a slippery slope. when working on many things in parallel stuff can get leaky. (e.g. that DATABASE_URL you set an hour ago for a quick test now has a bad effect in a completely different codebase that you cd'ed to)
<raz> direnv not only sets but also unsets the vars when leaving the directory. personally i prefer that over hoping that each thing i work on loads its .env itself
<jhass> somehow I prefer config files over env still
<raz> but... well... just my preference. i've also met people who think direnv is the devil
<jhass> at least if there's more than, say, three settings
<jhass> and something like three settings might even very well still be CLI args, depending on the app
<raz> depends on what env (:P) you're in. for cloudy stuff, docker etc., you don't want config files
<jhass> yeah but only because they're opinionated against
<raz> nah, it's just the only thing that makes sense there. you don't want to patch your image for config changes
<FromGitter> <j8r> env vars in a .dotenv file results to a config file
<jhass> but to me env has so many downsides. it leaks into other apps quickly while switching between projects in the same shell session. It leaks to subprocesses. It leaks to /proc
<raz> well, that's getting into unix neckbeard philosophical territory
<jhass> especially the subprocess one not all
<jhass> I don't want to know how many CVEs due to leaking secrets there
<raz> well, you say it "leaks". but that's exactly what it's meant to do. because the subprocess might also want to know what env he's in ;)
<jhass> well, tbh I just don't trust enough people to realize the implications
<raz> yup. the number of people who know how to do it right is small. but treating env like a config file has its own pitfalls as well
<raz> (now shared config that the subproc reads has to be passed on somehow, etc.0
<raz> needs*
<raz> what happens is practice that people tend to re-invent their own env (read from file, pass it on somehow)
<raz> grr can't type today
<FromGitter> <paulcsmith> @jwaldrip I have nothing against CRYSTAL_ENV at all. Would like to use that package, but it is super low on the priority list
<raz> i guess one thing that crystal could do for env safety would be to not pass the full env to spawned procs by default. but make that an explicit flag in the api
<FromGitter> <paulcsmith> That's the only reason we have not done it. We'd need to change docs, heroku buildpack, etc. and not a huge return. Most people don't care that much. So yeah, def want to do it/will do it, but just lots to do that has higher impact
<jhass> raz: well, not passing anything at all just breaks too much (PATH, LANG, LC_*, LD_LIBRARY_PATH and what not). So you'd want a whitelist, but what whitelist? any will break somebody's setup
<raz> jhass: true. would be tricky to get that right. (def not something that should just be changed willy nilly)
<jhass> and say we'll try you'll get endless discussions about borderline cases like PS1, SSH_AGENT_SOCk and whatnot
<raz> yup yup
<raz> jhass: although i can't help but noticed even your small list there already contains a gaping security risk (SSH_AGENT_SOCK) ;)
<jhass> exactly. But we'll have people coming and "WHY MY SSH AIN'T WORK"
<raz> ultimately people just need to be aware that sub-procs live largely in the same security realm as their parents
<raz> process groups etc.
<jhass> so I'd rather educate people to not put their secrets into envs of things they don't 100% trust, but...
<jhass> I know it's a dream world
<raz> jhass: i think the proper lesson would be to unset sensitive env vars after reading
<raz> but good luck making that common knowledge ;)
<jhass> I guess we could add a SECURE_ENV interface 😂
<FromGitter> <srowe_gitlab> Hi, I've just written my first project in Crystal and it was working great when it was all in one file, but when I separated the code into multiple files and used require "./myfile.cr" I'm getting an error about undefined constant as if the require didn't work. Any tips?
<raz> then again, i also don't think there's so many apps that spawn untrusted sub procs
<FromGitter> <Blacksmoke16> @srowe_gitlab make sure you require them in the correct order
<FromGitter> <srowe_gitlab> Good call, I believe I have.
<FromGitter> <Blacksmoke16> i.e. does `myfile.cr` use any types/constants defined in the file you're including it in?
<jhass> or just use a glob require which makes crystal care less
<FromGitter> <Blacksmoke16> pretty sure that still runs into issues
<FromGitter> <srowe_gitlab> heh ok I'll try the glob
<FromGitter> <srowe_gitlab> that's just `require "./*"` ?
<FromGitter> <Blacksmoke16> esp if you're doing like ` < SomeType` and there isa file called `a_type.cr`
<jhass> every tried loading the compiler in another way?
<raz> jhass: nah, what you pointed out above was right. there's no way to come up with a sane whitelist (cross platform and all). i think ssh itself has one, but it's probably a mess of special cases
<jhass> you'll learn what an undefined constant is
<FromGitter> <Blacksmoke16> :S
<FromGitter> <srowe_gitlab> hmm `require "./**"` and still no luck
<jhass> (I really wish it wasn't the case and kinda wish glob require wasn't a thing)
<FromGitter> <Blacksmoke16> whats the error exactly?
<FromGitter> <Blacksmoke16> and dont suppose you have it pushed up somewhere?
<FromGitter> <srowe_gitlab> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eac7dd43d58de7a38ebf0e3]
<FromGitter> <Blacksmoke16> is it a shard?
<FromGitter> <Blacksmoke16> nvm
<FromGitter> <srowe_gitlab> no it's in `./moka.cr`
<FromGitter> <Blacksmoke16> and you're requiring that before you're using it?
<FromGitter> <srowe_gitlab> which is the file I was requiring first... I'm currently doing `require "./**"`
<FromGitter> <Blacksmoke16> and im assuming you're running the main file with the requires?
<FromGitter> <srowe_gitlab> right
<FromGitter> <srowe_gitlab> `crystal build mokaweb.cr` which is the file that has the Kemal routes and starts with that glob require now (and previously with the moka.cr require)
<FromGitter> <srowe_gitlab> Crystal 0.34 with LLVM 8.0.0
<FromGitter> <Blacksmoke16> got the code pushed to a branch or something?
<FromGitter> <srowe_gitlab> I'm not sure what you're asking. Are you asking if you can see the source?
<FromGitter> <srowe_gitlab> If so, sadly no.
<FromGitter> <Blacksmoke16> then not much more we can help :/
<FromGitter> <Blacksmoke16> just make sure require order is correct, spelling, and such
<FromGitter> <Blacksmoke16> if you defined stuff in namespaces could also be an issue
<FromGitter> <Blacksmoke16> as would need to use full path to the type
<FromGitter> <srowe_gitlab> I do have some classes in a module, but not the one it's complaining about
<FromGitter> <srowe_gitlab> and I use the Module::Class to get to them in the code
<FromGitter> <Blacksmoke16> hard to say, im sure its some require issue tho
<FromGitter> <srowe_gitlab> lemme put the code somewhere
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <srowe_gitlab> lines 1 and 28 are shell https://pastebin.com/JtLHME63
<FromGitter> <tenebrousedge> mission accomplished: https://play.crystal-lang.org/#/r/8zv3
<FromGitter> <Blacksmoke16> yea, you're using `Moka.new` in the kemal route before its defined
<FromGitter> <Blacksmoke16> on 16, when its not defined until 32
<FromGitter> <srowe_gitlab> yea 28 is shell...
<FromGitter> <srowe_gitlab> so it should be defined on line 1
<FromGitter> <Blacksmoke16> oh sorry
<FromGitter> <Blacksmoke16> moment
<FromGitter> <srowe_gitlab> oh wait
<FromGitter> <Blacksmoke16> yea where do you require `moka` or `mokaweb`?
<FromGitter> <srowe_gitlab> I'm very sorry. I've wasted your time.
<FromGitter> <Blacksmoke16> 😆 all good
<FromGitter> <tenebrousedge> no worries
* FromGitter * Blacksmoke16 called it
<FromGitter> <srowe_gitlab> I was converting this project from ruby to crystal and I've been using mokaweb.cr with crystal code in it
<FromGitter> <srowe_gitlab> this is a .rb vs .cr problem
* FromGitter * srowe_gitlab feels stupid
<FromGitter> <tenebrousedge> every developer makes stupid mistakes
<FromGitter> <tenebrousedge> all the time
<FromGitter> <srowe_gitlab> thanks for your help everyone
<FromGitter> <Blacksmoke16> np
<FromGitter> <tenebrousedge> good luck with the project
* FromGitter * tenebrousedge is still doing a happy dance because the code works the way it should
<FromGitter> <srowe_gitlab> any chance any of you an answer my Kemal question in their chat from yesterday?
<FromGitter> <Blacksmoke16> prob should look into `ECR` versus doing `File.read`
<FromGitter> <Blacksmoke16> what was that?
<FromGitter> <Blacksmoke16> pretty sure kemal even has like `render`
<FromGitter> <srowe_gitlab> I found a bug that talked about the way to do streaming responses (not websockets) and was wondering if that's still the preferred way
<FromGitter> <Blacksmoke16> idt `stream` is still a thing
<FromGitter> <Blacksmoke16> should just be able to do like `obj.to_json ctx.response` since the response obj itself is an `IO`
<FromGitter> <Blacksmoke16> i.e. so this example would write the json directly to the response as a chunked response
<FromGitter> <Blacksmoke16> versus building the string and copying it
<FromGitter> <srowe_gitlab> this project searches through the contents of tarfiles and spits out text... the ruby version streams as it finds results
<FromGitter> <srowe_gitlab> (no JSON if you're saying that to me)
<FromGitter> <Blacksmoke16> was an example but the ideas the same
<FromGitter> <Blacksmoke16> pass ctx.response and you can write to it
<FromGitter> <Blacksmoke16> and the data will be written directly to the response io
<FromGitter> <srowe_gitlab> yea that's what I'm doing... env.response.print mything and then env.response.flush
<FromGitter> <Blacksmoke16> or in other words, to stream something just write to the `ctx.response` `IO`
<FromGitter> <srowe_gitlab> like this https://github.com/kemalcr/kemal/issues/151
<FromGitter> <Blacksmoke16> thats not the same thing
<FromGitter> <Blacksmoke16> does `mything` return a string?
<FromGitter> <srowe_gitlab> yes
<FromGitter> <Blacksmoke16> what im saying is you could do `mything env.response`
<FromGitter> <srowe_gitlab> what syntax is that?
<FromGitter> <Blacksmoke16> ```def mything(io : IO) ⏎ io << "some string" ⏎ ... ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5eac82d814b48f0698a3bd78]
<FromGitter> <srowe_gitlab> right I do that
<FromGitter> <srowe_gitlab> oh well I'm assuming print and << are similar
<FromGitter> <srowe_gitlab> I'll try <<
<FromGitter> <srowe_gitlab> and see if it works better
<FromGitter> <Blacksmoke16> no, let me clarify
<FromGitter> <Blacksmoke16> `env.response.print mything`
<FromGitter> <Blacksmoke16> this would get the full string result and write it to the response IO
<FromGitter> <srowe_gitlab> ah!
<FromGitter> <Blacksmoke16> doing my thing would write each individual string and write that, i.e. streamed
<FromGitter> <Blacksmoke16> i.e. soon as you `<<` or `print` the first string, the client would get that
<FromGitter> <srowe_gitlab> hmm
<FromGitter> <Blacksmoke16> maybe that'll help
<FromGitter> <srowe_gitlab> kk I'll read
<FromGitter> <srowe_gitlab> ty
<FromGitter> <tenebrousedge> so `sscanf` gives me a `StaticArray(LibC::Char)` representing string data, which will have at least one `0` at the end. What's the best way to convert that to a string, without trailing zeroes?
<FromGitter> <tenebrousedge> right now I'm doing `String.new(a.to_slice).rstrip('\0')` and it could be better
<jhass> huh, String.new should already skip a trailing 0 byte
<FromGitter> <srowe_gitlab> hmm that's interesting. So one of the many reasons I wanted to try this in Crystal was to use concurrency. So I'm looping over my targets with a `Channel(String).new` and then `spawn{ channel.send mything.to_s }` (simplified) and I then count those so I know how many times to `endpoint << channel.receive` (where endpoint is `env.response`)
<jhass> ah, maybe only String.new(Pointer) does
<jhass> so just String.new(a.to_unsafe)
<FromGitter> <srowe_gitlab> Should I instead pass the endpoint all the way down to `mything` so I can directly write to it there in the Fibers?
<FromGitter> <tenebrousedge> hmm, kay
<FromGitter> <tenebrousedge> thanks jhass
<jhass> or maybe just make the slice one shorter
<jhass> if you already know the length that should be slightly faster
<FromGitter> <tenebrousedge> I'd have to re-compute it
<FromGitter> <tenebrousedge> at compile time though
<jhass> String.new(Slice.new(a.to_unsafe, a.size - 1)) ?
<jhass> maybe i'm missing something
<FromGitter> <tenebrousedge> oh right
<FromGitter> <tenebrousedge> that's really faster than letting `String.new` figure it out?
<FromGitter> <Blacksmoke16> @srowe_gitlab uhh, guess it depends on exactly what you're doing?
<jhass> yeah String.new(pointer) has to strlen, so iterate through it
<FromGitter> <tenebrousedge> actually I have no idea how many zeroes will be at the end of the array
<jhass> oh, ah
<FromGitter> <Blacksmoke16> unrelated, wouldnt using files in that way make the response be in a random order? is that not breaking anything?
<jhass> then stick to String.new(pointer)
<FromGitter> <tenebrousedge> kk
<FromGitter> <srowe_gitlab> search order doesn't really matter
<jhass> to answer the question anyway, if you know the size of the string it's just a memcpy
<FromGitter> <Blacksmoke16> no but whats the serialization format?
<FromGitter> <srowe_gitlab> text
<FromGitter> <Blacksmoke16> ah
<FromGitter> <tenebrousedge> I can't know the size of the string, only the maximum size of the string
<FromGitter> <srowe_gitlab> well this works and it's twice as fast as the ruby, so I'm pretty pleased even w/o the streaming
<FromGitter> <srowe_gitlab> thank you very much for being so kind to a newbie
<jhass> yeah, so you have to count :)
<FromGitter> <Blacksmoke16> i mean if thats what you're doing you're already streaming
<FromGitter> <Blacksmoke16> as first write to the response would send the data
<FromGitter> <Blacksmoke16> check the response and see if the transfer encoding is chunked
<jhass> vs https://github.com/crystal-lang/crystal/blob/master/src/string.cr#L158, both end up at the same method really, one just figures out the size prior
<FromGitter> <tenebrousedge> good to know
<FromGitter> <srowe_gitlab> chunked it is
<FromGitter> <Blacksmoke16> yea so you're god
<FromGitter> <Blacksmoke16> be aware that you cant add/change headers once data is first written
<FromGitter> <srowe_gitlab> indeed. thanks
* FromGitter * tenebrousedge debates whether it is even a good idea to make `scanf` work with IO objects
<FromGitter> <tenebrousedge> this (http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html) seems to argue that it's more often a bad idea than not
<jhass> oh, your port is serious? I thought you're just having fun :P
<jhass> scanf is terrible, yeah
<jhass> anything you're missing from Crystal's IO interface?
<FromGitter> <tenebrousedge> I mean, I don't really expect that it will get used
<jhass> I mean can do anything stdlib can't already?
<FromGitter> <tenebrousedge> no idea
return0e has quit []
_ht has quit [Quit: _ht]
<FromGitter> <tenebrousedge> what can you do with stdlib?
<jhass> https://carc.in/#/r/8zvc things like this
<FromGitter> <tenebrousedge> well okay, but that gets you one type, right?
<jhass> sure, just put it into loops etc
lvmbdv has quit [Quit: bye]
<FromGitter> <tenebrousedge> okay, but if you have `"abc 123 -- 456"` and you don't want `--`, then you have to do a lot more than just `scanf("%s %d -- %d")`
<FromGitter> <tenebrousedge> or I guess `scanf("%3s %d -- %d")`
lvmbdv has joined #crystal-lang
<FromGitter> <tenebrousedge> `scanf` was recently removed from Ruby stdlib, presumably because no-one used it. I maybe needed it twice in the last ten years, and at least one of those times I rewrote that code a different way so that it was no longer useful
<FromGitter> <tenebrousedge> it's dangerous and arcane, but every once in a great while it's a simple solution to some problem
<jhass> well you may need to build some abstractions on it
<jhass> look now it can read and write tuples: https://carc.in/#/r/8zvi
<FromGitter> <tenebrousedge> okay?
<jhass> wait, scanf just does string conversion, eh?
<FromGitter> <tenebrousedge> yes
<jhass> I rememebered it wrong kinda :D
<jhass> for something like the above I'd use regex I think
<FromGitter> <tenebrousedge> which would give you strings
<jhass> just to_i them?
<FromGitter> <tenebrousedge> you can. `scanf` would skip allocating the intermediate strings
<FromGitter> <tenebrousedge> it may or may not also be faster than regex
<FromGitter> <tenebrousedge> I'd hate to have to pick which one was less readable
<FromGitter> <tenebrousedge> theoretically `scanf` also handles octal and hex digits smoothly
<jhass> seems like regex just gives a view into the string: https://carc.in/#/r/8zvr
return0e has joined #crystal-lang
<jhass> paulcsmith: so here's why it's better to private message such requests. you're just feeding the troll and helping them derailing the topic
<FromGitter> <paulcsmith> I’m not sure who to private message or I would
<FromGitter> <paulcsmith> Also literally anything anyone says is feeding the troll at the moment 😂
<FromGitter> <tenebrousedge> who is trolling?
<FromGitter> <paulcsmith> Which is why IMO he needs to be banned. This person is toxic to the community
<FromGitter> <paulcsmith> IEatReturnValues4 on the crystal forums
<jhass> well, I guess discourse lacks a tool for that, yeah
<jhass> like being able to DM a predefined group of people or so
<jhass> or at least being able to add a custom message to a flag
<FromGitter> <paulcsmith> Yeah. Or if there is a I don’t know. So I put it in multiple places so hopefully someone sees it. This person is totally disruptive and when asked to change just mocks people
<FromGitter> <paulcsmith> Yeah that’d be cool too. Custom message. I’ve personally muted him but his replies still show up in my email so the mute doesn’t really work lol
<FromGitter> <paulcsmith> I admit I did rip into him at one point and my comment got removed but I was hoping it’d bring attn to the issue and he would be banned or be given an ultimatum or something. But he just kept on going with no repercussions so far
<FromGitter> <paulcsmith> A code or conduct is not very valuable if not enforced :(
<jhass> mmh, it seems to you can restrict categories to certain trust levels
<jhass> and by default there's one restricted to TL3 called "The lounge" inteded foor such discussions
<jhass> but looks like we got rid of it?
<FromGitter> <paulcsmith> That’s a good idea. I don’t know much about discourse though so can’t really offer much
<FromGitter> <paulcsmith> for those following along this is the kind of helpful and kind stuff you can expect to see from this user lol 😂 https://forum.crystal-lang.org/t/how-rust-views-tradeoffs/2029/6?u=paulcsmith
<FromGitter> <paulcsmith> So my recommendation in the meantime is mute. It helps because replies are hidden by default (but still show up in emails unfortunately)
<FromGitter> <paulcsmith> Ah I figured it out. I can choose “something else” when reporting and leave a comment. Not sure it actually makes it to moderators though
<FromGitter> <straight-shoota> FYI I just hid a bunch of comments because they're off topic
<FromGitter> <paulcsmith> Can you please hide IEatReturnValues4?
<FromGitter> <paulcsmith> His topics may be on topic, but are completely inappropriate in delivery
<FromGitter> <paulcsmith> It is baffling to me that my posts are hidden for calling someone out, but the guy actually *causing* the issues has been allowed to derail conversations constantly over the last week
<FromGitter> <paulcsmith> I'm sorry if I'm being annoying here, it is just so strange. WE have a code of conduct that he is not following. How is he still allowed to post?
<FromGitter> <asterite> Yes, please hide him 🙏
<FromGitter> <paulcsmith> Thank you! I was starting to feel like I was on crazy pills here lol
<FromGitter> <paulcsmith> Honestly if he isn’t then the code or conduct may as well be an empty file. I don’t like to be dramatic, but it’s better not to have one than to have one that is not enforced
<jhass> straight-shoota: paulcsmith: How about we split those into an offtopic category post?
<jhass> for now
<straight-shoota> @paulcsmith Can you point out a clear violation of the CoC? I think it's difficult. In total, the behaviour seems destructive. But the individual comments are IMO on the edge
<jhass> and that's why I'd go for isolating them into topics we can use to escalate without derailing the originals. That'll eventually drive them into behavior that's clearly bannable
<FromGitter> <paulcsmith> I think if the total behavior is destructive it is fine to ban or mute
<FromGitter> <paulcsmith> Even if there isn’t one single post. I personally think he’s said some stuff that’s made me feel like a total dumbass so 🤷‍♂️
<FromGitter> <paulcsmith> jhase I’d be down for moving it to off topic
<straight-shoota> jhass, what exactly to you mean?
<FromGitter> <paulcsmith> I’m gonna be out for dinner so won’t have time to respond
<jhass> straight-shoota: discourse let's you freely move posts around, into a new topic, an existing one etc
<FromGitter> <paulcsmith> Also if his behavior hasn’t breached the code of conduct then I imo it should be modified so that that kind of behavior isn’t allowed
<FromGitter> <paulcsmith> Because if this continues people won’t want to post or go to the forums at all. Which would suck :(
_whitelogger has joined #crystal-lang
bazaar has joined #crystal-lang
chachasmooth has joined #crystal-lang
<straight-shoota> I think it's fine to simply hide off-topic posts
<straight-shoota> Why would we want a separate topic for them?
deavmi has joined #crystal-lang
dom96 has quit [Ping timeout: 246 seconds]
dannyAAM has joined #crystal-lang
<jhass> I think it worked out well for https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006, it kept the original topic in tact while isolating the toxic behavior into its own topic that people could just choose to ignore. If you just hide within each topic that'll entice them to post more more to that same topic you have to hide
dom96 has joined #crystal-lang
<jhass> and discourse allocates rather a lot of screen estate to those still
MasterdonX has joined #crystal-lang
lanodan has quit [Ping timeout: 240 seconds]
<jhass> and tbh if it escalates a bit to give us a clear cut ban reason, also fine by me
<jhass> you seem to be hesitant to ban them outright and I have to agree, at least for my position in this community, in one where I would feel more authoritative I'd be less reluctant already. But just hiding fits their strategy tbh where they can present themselves as oppressed
<jhass> and it'll also requrie hiding the the annoyance caused in other community members, which is not exactly beneficial to the community as a while too IMO
lanodan has joined #crystal-lang
v2px__ has joined #crystal-lang
gangstacat has quit [Ping timeout: 265 seconds]
gangstacat has joined #crystal-lang
straight-shoota has quit [Ping timeout: 256 seconds]