ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Crystal 0.23.1 | Fund Crystal's development: | GH: | Docs: | API: | Gitter:
<FromGitter> <simaoneves> eheh that means you are doing a good job :) kudos
DTZUZO has quit [Ping timeout: 240 seconds]
RickHull has quit [Ping timeout: 260 seconds]
<FromGitter> <jwoertink> I saw this whole Alternative hash function PR, but I'm a little confused on what it does, or what it's for. Can anyone break that down?
<FromGitter> <jwoertink> When they say "Hash", they're not talking about `{"a" => 1}` right? They're talking more like MD5 type hash with lots of numbers and letters and stuff?
<Papierkorb> jwoertink, not Hash, but the #hash algorithm
<Papierkorb> (well, the algorithm #hash functions are supposed to use now)
<FromGitter> <jwoertink> Like what OpenSSL provides?
<FromGitter> <jwoertink> sha256, etc... those kind of hash functions?
<Papierkorb> jwoertink, there are many kinds of hashing algorithms. Cryptographic ones like SHA256, or those used to generate a (possibly unique) identifier.
<Papierkorb> The latter ones are generally not cryptographically secure, they don't have to be. They're optimized for speed.
<FromGitter> <jwoertink> Oh, like generating a random UUID?
<Papierkorb> In our case, it's e.g. what `Hash` will use to figure out "where to put" a value you give it
<Papierkorb> Maybe a bit, but the use-case is not the same
<FromGitter> <jwoertink> When you make a `Hash` and you add a value, this #hash function helps to determine where in memory to put the value?
<Papierkorb> Basically, yes
<FromGitter> <jwoertink> ah
<FromGitter> <jwoertink> nice
<FromGitter> <jwoertink> Thanks for the explanation!
<Papierkorb> jwoertink, and there's a reason why we do this handstand at all: it's to prevent DoS attacks. If an attacker knows exactly how the hashing algorithm works, they could craft requests (e.g. to a web service) which would make the hash put tons of values into the same bucket(s). This is super bad, as the Hash will now become really slow to get stuff out of
<Papierkorb> So this new algorithm, among other things, generates a random seed at program start, which is then used with the hash generation. An attacker can't know this seed, and hence, makes it not practically possible for an attacker to exploit this
<Papierkorb> jwoertink, you can check this in Ruby, just open irb/pry, check `"".hash`, and then again in another session. The hash values will be different.
<Papierkorb> It's one of the things ruby web devs "tripped over" as people used tons of Hash'es to store stuff lul.
<FromGitter> <exts> hey quick question, what was the reason for crystal to not have interfaces again?
<Papierkorb> a module with only (abstract) methods is an interface (in the java sense)
DTZUZO has joined #crystal-lang
<FromGitter> <exts> yeah, true
csk157 has joined #crystal-lang
<FromGitter> <faustinoaq> > @asterite No progress yet. A formatter is something that will come after 1.0 ⏎ ⏎ I didn't know we thought a formatter after 1.0 ⏎ ⏎ Well, is there is one now 😄 ✨ ... []
<FromGitter> <exts> how close is 1.0?
csk157 has quit [Ping timeout: 240 seconds]
<FromGitter> <faustinoaq> ⏎ ⏎ Seems some Ruby developers don't like types at all
<FromGitter> <aarongodin> I would even go as far to say that the absence of types is something that drew people to ruby
alex`` has joined #crystal-lang
ephemera_ has quit [Quit: No Ping reply in 180 seconds.]
ephemera_ has joined #crystal-lang
csk157 has joined #crystal-lang
csk157 has quit [Ping timeout: 252 seconds]
ephemera_ has quit [Quit: No Ping reply in 180 seconds.]
ephemera_ has joined #crystal-lang
<FromGitter> <marksiemers> > the absence of types is something that drew people to ruby ⏎ I think that's absolutely correct, and I am in favor of what Nate B. said. There are plenty of typed languages and having something like ruby that is very accessible to beginners I think needs to remain in the language eco-system. ⏎ Once you understand the value of typing, then you can graduate to Crystal
<FromGitter> <HCLarsen> I never liked the lack of types with Ruby. Maybe it's because it's the first language I ever used that wasn't strongly typed, but it always bugged me.
<FromGitter> <HCLarsen> I was drawn to Ruby because of the syntax and the community. But throughout the years that I've worked with Ruby, the lack of types and lack of compiling always bugged me.
<watzon> Does this same concept work in Crystal?
<watzon> Basically I am trying to figure out if there is a way to define a module with both class methods and instance methods that get passed on to whichever class includes it
<FromGitter> <HCLarsen> Basically, using a module as a mixin?
<watzon> HCLarsen I guess that would be accurate. I'm just wondering how close to the ruby functionality Crystal is
<watzon> I am fairly certain you can't just use a `ClassMethods` or `InstanceMethodsAfterActivation` module, but if there is a way it would be good to know
<FromGitter> <HCLarsen> ```code paste, see link``` []
<FromGitter> <HCLarsen> Just need to include the module in your class, and it works.
<watzon> I thought so. But doesn't Ruby do the same thing? I thought the `ClassMethods` module added some additional functionality, like making it so that the models contained therein could only be used inside of the class itself, whereas the `InstanceMethodsAfterActivation` module is methods that can only be used once a class has been instantiated
<watzon> I could be misunderstanding what they're for though
<FromGitter> <HCLarsen> Ooh. I don't remember what ClassMethods did.
<FromGitter> <HCLarsen> Maybe you have to use that to define actual class methods from within the module.
<FromGitter> <HCLarsen> Question for the more experienced Crystal folks. I don't see anything in the documentation about accepting arguments from the command line. I'm assuming that you can create command line tools in Crystal though.
<FromGitter> <HCLarsen> Does it work the same as Ruby?
<watzon> @HCLarsen I believe it works similarly, if not the same. I remember some discussion about removing the $0 variable though
<watzon> Yeah, just use `ARGV`
<FromGitter> <HCLarsen> I can't find anything in the language reference about it.
<watzon> Yeah the documentation is lacking a bit
<watzon> This is a little old, but should still hold up
<FromGitter> <HCLarsen> I might have to write a new page for the language reference for this. It should be in there.
<watzon> I agree though, that's one thing that should be there
<watzon> I'm sure they'd be happy to get a PR
<FromGitter> <HCLarsen> No doubt. It's just that all my PR's so far have been improving existing pages. This'll take a whole new page, which means figuring out where in the structure it should go.
<watzon> Yeah, asterite would be a good one to talk to about that
notdaniel has joined #crystal-lang
<FromGitter> <HCLarsen> Very true.
csk157 has joined #crystal-lang
alex`` has quit [Quit: WeeChat 1.9.1]
csk157 has quit [Ping timeout: 248 seconds]
DTZUZO has quit [Ping timeout: 240 seconds]
<FromGitter> <sdogruyol> morning everyone
claudiuinberlin has joined #crystal-lang
<FromGitter> <Rinkana> Morning
<Groogy> Morning!
tdc has joined #crystal-lang
<watzon> Morning guys
<watzon> So, Crystal still doesn't have a built in Singleton module correct?
DTZUZO has joined #crystal-lang
DTZUZO has quit [Ping timeout: 240 seconds]
<Groogy> do you mean Ruby singleton or do you mean like the pattern?
notdaniel has quit [Quit: Leaving]
<FromGitter> <monouser7dig> > **<watzon>** Basically I am trying to figure out if there is a way to define a module with both class methods and instance methods that get passed on to whichever class includes it ⏎ ⏎ you mean like this?
<FromGitter> <Rinkana> Crystal indeed does not have a singleton module
<FromGitter> <Rinkana> There was a PR but it was declined:
<FromGitter> <Rinkana> However the basic module is very simple: ``` ⏎ module Singleton ⏎ ⏎ `````` []
<watzon> So that's the difference between extend and include then?
<watzon> monouser7dig
<watzon> Rinkana thank you for that :)
<FromGitter> <monouser7dig> yes extend makes the module available on a class level and include in an instance level
<FromGitter> <monouser7dig> there is even some documentation about that
<watzon> That makes sense
<watzon> Thanks
<FromGitter> <monouser7dig> liked it so far as well
alex`` has joined #crystal-lang
csk157 has joined #crystal-lang
<FromGitter> <bew> Weird error on Travis:
<FromGitter> <bew> `An error occurred while generating the build script.`
csk157 has quit [Ping timeout: 246 seconds]
p0p0pr37_ has joined #crystal-lang
p0p0pr37_ has joined #crystal-lang
p0p0pr37 has quit [Ping timeout: 248 seconds]
p0p0pr37_ is now known as p0p0pr37
baweaver has quit [Ping timeout: 248 seconds]
Cyrus has quit [Ping timeout: 248 seconds]
thews has quit [Ping timeout: 248 seconds]
Cyrus has joined #crystal-lang
baweaver has joined #crystal-lang
Cyrus is now known as Guest74140
baweaver is now known as Guest74876
thews has joined #crystal-lang
thews has quit [Changing host]
thews has joined #crystal-lang
cyberarm has quit [Ping timeout: 240 seconds]
cyberarm has joined #crystal-lang
justinmcp has quit [Read error: Connection reset by peer]
justinmcp has joined #crystal-lang
<FromGitter> <faustinoaq> Interesting project, I think could be possible to create something similar on Crystal/Ruby
<FromGitter> <monouser7dig> but transpiring is mostly just hack to get it to compile
<FromGitter> <monouser7dig> but you miss specific language optimisations and optimisation is one of the main reasons to switch to crystal so...
<FromGitter> <monouser7dig> like pythonic vs non pythonic :D you can have perfectly valid code that still is bad code
<FromGitter> <DRVTiny> Hello again, dear All! :) ⏎ How can i read 6 bytes from socket to some struct with fields desribing readed data? ⏎ ⏎ ```code paste, see link``` ⏎ ... []
<FromGitter> <DRVTiny> Can it be simpler?
<FromGitter> <faustinoaq> `unless nb=6` 👉 `unless nb == 6` ?
csk157 has joined #crystal-lang
<FromGitter> <DRVTiny> Yes, of course. But problem is not here at all :)
<FromGitter> <faustinoaq> > but transpiring is mostly just hack to get it to compile ⏎ ⏎ @monouser7dig Yeah, is just a hack, I made a program that compiles using Ruby || Crystal, using hackish code 😅
<FromGitter> <DRVTiny> How to read N bytes from socket to memory chunk addressed by pointer ptr?
csk157 has quit [Ping timeout: 240 seconds]
<FromGitter> <faustinoaq> @DRVTiny, Why pointers? they are considered unsafe in crystal try: ⏎ ⏎ ```bytes = Slice(UInt8).new(n) ⏎ socket.read_fully(bytes) ⏎ pp bytes``` ⏎ ⏎ Also see: []
<FromGitter> <DRVTiny> @faustinoaq Its ok, but i need to read into some structure, not to pointer known as Bytes, aka Slice(UInt8)
<FromGitter> <bew> you can't `read` a struct in Crystal like you could do it in C, mostly because the memory layout of your struct in Crystal can't be guarantied iirc
<FromGitter> <bew> but you can read each fields of the struct from an io, and build the struct using the fields you read
<FromGitter> <DRVTiny> @bew OK. How can i read fields of readed binary data? ⏎ I need to read into NamedTuple, Tuple, StaticArray... How can i do it in Crystal? Crystal is simpler than C, right?
<FromGitter> <bew> wut from your example you have a `Array(Char)[4]` what is this supposed to be?
<FromGitter> <DRVTiny> I need to read header of some binary protocol: ⏎ First 4 bytes is a signature (must be "ZBXD") ⏎ 5-th byte is a delimiter between signature and some meaningfull data: 0x01 ⏎ 6-th byte is a length of data payload (encoded as JSON) ⏎ From 7-th to 7-th+payload_length-1 - is it JSON-encoded data returned from server ... []
<FromGitter> <bew> ah perfect
<FromGitter> <codenoid> hi, i want to use crystal 0.24.0 for production
<FromGitter> <bew> you shouldn't
<FromGitter> <codenoid> i still got ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <codenoid> cc @samueleaton
<FromGitter> <DRVTiny> @bew Array(Char)[4] is some try to tell Crystal that my string must be limited by 4-bytes in length
<FromGitter> <bew> The first line of is: *WARNING:* this is a pre-release version of Crystal. *Do not use* this in production.
<FromGitter> <codenoid> yes, i know @bew
<FromGitter> <codenoid> ok, how to fix that Lexical Scope bug
<FromGitter> <codenoid> ok, wait
<FromGitter> <faustinoaq> > Array(Char)[4] is some try to tell Crystal that my string must be limited by 4-bytes in length ⏎ ⏎ @DRVTiny Maybe you should use `StaticArray(Char, 4)` then, see:
<FromGitter> <DRVTiny> @faustinoaq Already :) But i dont know how to initialize StaticArray(Char, 4) with the chars 'Z', 'B', 'X' and 'D' ⏎ StaticArray(Char, 4).new('Z', 'B', 'X', 'D') - doesn't work, for example ⏎ ⏎ arr[0]='Z' ⏎ arr[1]='B' ... []
<FromGitter> <DRVTiny> "Design? What is design? ⏎ Is it something about ⏎ ⏎ ```b : UInt8 ⏎ b=255_u8``` ⏎ ... []
<FromGitter> <bew> @DRVTiny there a shortcut: `StaticArray['A', 'B', 'C']` will create a `StaticArray(Char, 3)` filled with 'A', 'B' & 'C'
mark_66 has joined #crystal-lang
stephenwithav has joined #crystal-lang
<FromGitter> <yxhuvud> @DRVTiny : i would suggest using a struct, but have the initializer for it take an arbitrary Slice, and in the initializer read from the slice one field at a time. You defintely don't want a String for that as strings assume the data is utf8.
<FromGitter> <codenoid> hi, is crystal have function to verify the password from `Crypto::Bcrypt::Password.create` ? (I'm forget about that)
<FromGitter> <yxhuvud> I would not try to use the type system to encode the size - I'd just have the constructor consume the appropriate amount of the slice, and then pass along whatever is left of the slice to whatever it is that consumes the body.
mark_66 has quit [Remote host closed the connection]
<FromGitter> <DRVTiny> @bew Oh, that looks good, thank you!
<FromGitter> <yxhuvud> is an example of reading the header and then operating on the resulting slice.
<FromGitter> <Rinkana> @DRVTiny For reading bytes check this:
<FromGitter> <Rinkana> This is how i parse the header of a BMP file
<FromGitter> <codenoid> got it ``
bjz has joined #crystal-lang
bjz has quit [Client Quit]
bjz has joined #crystal-lang
bjz has quit [Client Quit]
<stephenwithav> Once Crystal reaches 1.0, will there be a regular release cycle like Golang has?
csk157 has joined #crystal-lang
<FromGitter> <sdogruyol> probably
csk157 has quit [Ping timeout: 248 seconds]
<stephenwithav> Awesome. I may settle on Crystal for v2 of my startup if that's true.
<FromGitter> <DRVTiny> @Rinkana Thanks! But how to read exactly 4 bytes from io object (socket) and compare it with "ZBXD", not with UInt32 representation?
<FromGitter> <bew> sth like `io.gets(4) == "ZBXD"` ?
<Papierkorb> DRVTiny, `a = StaticArray(UInt8, 4).new; socket.read_fully(a.to_slice); if a == StaticArray[ 'Z', 'B', 'X', 'D' ] ...`
<FromGitter> <bew> way better ^
<Papierkorb> Assuming that the other end may send you string data at all is a false assumption, don't use strings for such checks
<Papierkorb> E.g., say you use a String, and thus, a string-reading function. You tell it that you want 4 chars at max.
<Papierkorb> Remember encoding: UTF-8 is multibyte. You could receive more than you wanted. Maybe with a bit of trickery, this could be exploited
<FromGitter> <DRVTiny> Papierkorb, so i need to read UInt32... Well, this is reasonable
<Papierkorb> DRVTiny, And now you'd have to check endianess too
<Papierkorb> And on top of that, turn that readable ABCD sequence into a 0x12345678u32 thing that no one will ever understand
<jsn-> hmm, how come there's Set#-(Enumerable), but there's no Set#+?
<FromGitter> <bew> Papierkorb not working, comparing a StaticArray(UInt8, 4) and a StaticArray(Char, 4) will always return false
<Papierkorb> ah well, adding #ord left as excercise to the reader
<Papierkorb> and #to_u8
<Papierkorb> Or simply writing a helper method
<FromGitter> <bew> or wait until we have a literal for Slice(UInt8) :D
<Papierkorb> No, Slice is run-time allocated, wasting resources for a tiny check
<FromGitter> <yxhuvud> well you can put it in a constant.
<FromGitter> <yxhuvud> or ah, you are talking about the other side :)
<Papierkorb> I'd probably write a helper method/macro
<FromGitter> <bew> ah yes that's true
<FromGitter> <yxhuvud> I still like the way I did it in the github link I gave earlier :)
csk157 has joined #crystal-lang
DTZUZO has joined #crystal-lang
csk157 has quit [Ping timeout: 248 seconds]
<FromGitter> <DRVTiny> Oh no... ⏎ I've got a length in UInt8 and now i decide to read JSON-string from socket with that length in mind ⏎ read_string not working properly, because it doesn't uses offset which previously was seted by read_byte(s) sequence. ⏎ So... I need to read payload_length bytes... somewhere and convert that rom JSON to hash structure. HOW?? :( [
<FromGitter> ... l-lang/crystal?at=59f87ed8614889d47521ef15]
<FromGitter> <bew> What do you mean "read_string not working properly" ?
<FromGitter> <bew> about the JSON, is it in a known-in-advance structure?
<FromGitter> <faustinoaq> TypeScript/JavaScript is so similar to Crystal/Ruby 😄
<FromGitter> <exts> any plans on having lazy urls to the api docs? For example if I type: it would redirect me to ?
<RX14> well /api/JSON.html works
<RX14> the best thing to do it to bookmark /api/latest/
<RX14> and then hope that the PR with fuzzy search gets merged
<FromGitter> <exts> case sensitive though
<Papierkorb> exts, I have a bookmark on with a `cr` prefix
<RX14> i use github's fuzzy search so much
<RX14> i cant wait for the crystal docs to get it
<FromGitter> <bew> GH has fuzzy search??
<RX14> press t
<RX14> press t on to do sa fuzzy file search
<RX14> its the only way to get around
<FromGitter> <exts> hmm would also be cool if I could type in my browser bar, press tab and i can submit straight to the search form from my browser bar similar to how youtube does it
<FromGitter> <bew> ah yes the finder
<FromGitter> <exts> :P
<FromGitter> <bew> RX14 I have a nice fzf config (on Alt-F) to find files, so I always search in local version, not online, so much faster imo
<FromGitter> <DRVTiny> Finally, i did it ⏎ ⏎ ```code paste, see link``` []
<RX14> @bew i typicvally find it slower to navigate to the repo and then fuzzy search compared to just going on github
<RX14> im usually just trying to find a method impl
<RX14> or two
<FromGitter> <straight-shoota> @exts You can do it similar to Papierkorb, just manually add a search engine shortcut
<FromGitter> <bew> hmm it depends, I have very fast directory navigation in my shell, so it's always faster for me
<FromGitter> <bew> but I can understand that when you don't have that it's way slower
<RX14> well even if i did
<RX14> actually i guess i need a fuzzy finder for my repo checkouts lol
<RX14> then it'd just be double fuzzy find crystal repo -> file
<RX14> hmm
<RX14> i need to work on my emacs config more lol
<FromGitter> <exts> will give it a try @straight-shoota
<FromGitter> <bew> ahah that would be a good idea! I like it
<RX14> i have a weird directory layout for my repos though lol
<RX14> i check out every branch in a different folder using github worktrees
<RX14> s/github/git
<RX14> so i have /data/programming/crystal-lang/crystal/master/
<RX14> or /data/programming/crystal-lang/crystal/feature/foo
<FromGitter> <bew> why? to work on many things at the same time?
<RX14> yeah
<RX14> i hate having to commit when i change branch
<RX14> so i just dont
<FromGitter> <bew> ^^ or stash?
<RX14> or that
<RX14> but stash is messy
<RX14> it's a stack really
<FromGitter> <bew> true, but you can comment them iirc, never tried that
<RX14> which isnt what you want when you're working on 10 prs
<RX14> yeah but it's somewhat difficult to pick out the middle
<RX14> magit makes it a lot easier but still
<FromGitter> <exts> @straight-shoota the search is javascript based so it won't work as it doesn't submit a form it seems
<RX14> and i never remember the correct stash commands
<FromGitter> <bew> hmm sure never did more than 1-2 pr, I'm sure the workflow is different when you have more like you
<RX14> yeah i just like wasting disk space lol
<crystal-gh> [crystal] Papierkorb opened pull request #5216: ENV#[]=: Disallow null bytes in key and value (master...disallow-nul-in-setenv)
<RX14> nice pr
<Papierkorb> arg left over of using the string function
<FromGitter> <straight-shoota> @exts Yes, it works only for types.
<FromGitter> <yxhuvud> stash is messy, since it is easy to forget about and then you have a mess. forgotten branches is just not a problem.
<RX14> it's just great having a seperate workspace that you can *just leave* and open up a new clean one on a new branch anytime
<RX14> it's just effortless leave it and come back later
<FromGitter> <sdogruyol> @RX14 that way of working kills my productivity :/
<RX14> i've lost uncomitted changes/random unstashed files
<RX14> @sdogruyol which? how?
<FromGitter> <sdogruyol> doing many things at the same time
<RX14> what, you want me to wait the month it takes to bikeshed my PR to start working on the left ;)
<RX14> s/left/next
<Papierkorb> I'm more confused that stash apply doesn't seem to remove the changeset from the stack
<RX14> yeah that too
<Papierkorb> So I've them piling up in all my projects
<RX14> stash i just
<RX14> stay away from now
<RX14> no more pls
<Papierkorb> And I have no idea which are actually useful
<Papierkorb> Or if I have already applied the stash
<FromGitter> <straight-shoota> @exts Javascript-based search could accept a search query in the fragment like
<Papierkorb> So if they'd fix that, that'd be great
<FromGitter> <straight-shoota> would be a nice addition to #4746
<FromGitter> <Shalmezad> @PapierKnob I believe you can do "git stash pop" instead of "git stash apply" to apply the stash and remove it from the stack.
<Papierkorb> I'm a bit wary that the download size would be simply too much for a big project
<Papierkorb> Oh you're right!
<RX14> i just wish #4746 didn't depend on #4772
<FromGitter> <Shalmezad> Bleh, can't type today, sorry 'bout fumbling the username
<RX14> then i'd actually be able to merge it
<Papierkorb> I always thought pop would just get rid of it..
<FromGitter> <Shalmezad> "Remove a single stashed state from the stash list and apply it on top of the current working tree state"
<RX14> Papierkorb, i dont think you can pop further up the stack tho
<RX14> which is annoying
<Papierkorb> Ah that's good enough for me
<FromGitter> <straight-shoota> @RX14 got a better idea?
<FromGitter> <Shalmezad> RX14: As in mid stack? Add stash@{<revision>} to that.
<Papierkorb> I mainly have it as scratch space, for branch changes, or pulls. I mostly immediately reapply them
<RX14> you can use autostash
<RX14> for pulls
<RX14> or just use magit
<RX14> but i guess thats a bit heavy handed
<RX14> @straight-shoota not really :(
<Papierkorb> stash@{idx} is also possible
<FromGitter> <bew> zsh's completion FTW ;)
<FromGitter> <bew> there's sth I really miss in zsh completion is fuzzy search in completion candidates found by zsh...
<Papierkorb> sometimes is scary. you install some random program, and then hit tab and zsh already knows what's up
<RX14> yeah lol
<Papierkorb> I mean, zsh even parses shell scripts for auto-completion .. automatically Oo
<RX14> wait what really?
<Papierkorb> case
<FromGitter> <straight-shoota> RX14, it's either that PR, or adding additional export types with JSON.mapping for each exportable type, or writing directly to a JSON::Builder which duplicates much boilerplate code
<RX14> i struggled a long time working out what the point was of #4772
<RX14> and i think that still remains
<RX14> i get it now
<RX14> but it wasnt well explained in the PR description
<RX14> so i was like wtf and skimmed over it
<FromGitter> <straight-shoota> sry... :D
<RX14> i really wish we could define private methods etc inside spec ifs
<RX14> the def_to_json specs are horiffic
<RX14> with all those class definitions nowhere near where they're used
<FromGitter> <straight-shoota> jep
<FromGitter> <straight-shoota> well, I could probably split the `describe` block for each `it`...
<FromGitter> <straight-shoota> and put the classes in between
<RX14> ew
<RX14> but
<RX14> yes that could work
swav has quit [Ping timeout: 252 seconds]
swav has joined #crystal-lang
<FromGitter> <DRVTiny> Why? ⏎ ⏎ ```clock=e[:clock] ⏎ ^``` []
<FromGitter> <DRVTiny> I've checked that ":clock" is in Tuple (or no) before trying to use it!
<FromGitter> <bew> don't use a NamedTuple here, use a Hash instead
<FromGitter> <exts> i don't think that's the solution
<FromGitter> <exts> like for instance this works fine as long as I call the test tuple, but the moment i pass a named tuple missing that key to the same array it errors out
<FromGitter> <exts> I mean it's one solution, but this seems like a bug or something
<FromGitter> <bew> @straight-shoota your msg formatting went wrong here
<FromGitter> <bew> (we should run crystal tool format for crystal code blocks in github comments x) )
<FromGitter> <exts> @DRVTiny create a new issue
<FromGitter> <straight-shoota> @bew thanks, I noticed right after publishing ;)
DTZUZO has quit [Ping timeout: 240 seconds]
DTZUZO has joined #crystal-lang
<robacarp> perhaps this is a search failure, but is the delegate construct documented anywhere?
<Papierkorb> probably in Object
<FromGitter> <bew> yep*methods,toobject)-macro
<robacarp> great, thanks.
duper has quit [Ping timeout: 255 seconds]
csk157 has joined #crystal-lang
csk157 has quit [Ping timeout: 258 seconds]
saadq has quit [Ping timeout: 264 seconds]
saadq has joined #crystal-lang
<crystal-gh> [crystal] straight-shoota opened pull request #5217: Fix docs path in .gitignore and Makefile (
vivus has joined #crystal-lang
<vivus> Does crystal have a shard like: ? Specifically one for handling users (register, login, logout, etc.) I am using amberframework
<FromGitter> <bew> probably not yet
<FromGitter> <DRVTiny> ⏎ How to force it work? ⏎ ⏎ I am in doubt, over 2 hours trying to get a simple function :( []
<FromGitter> <bew> what are you trying to do? it looks over complicated
<Papierkorb> DRVTiny, please explain in text what you're trying to do, not only code
Ven has joined #crystal-lang
Ven is now known as Guest12701
<FromGitter> <DRVTiny> I am trying to accept list (Array?) of arguments, each may be NamedTuple, Hash or Array ⏎ {key: "key", value: "value", clock: clock} ⏎ or ⏎ {key: "key", value: "value", clock: "clock"} ⏎ or ... []
<Papierkorb> and then do what with it?
Guest74876 is now known as baweaver
baweaver has quit [Changing host]
baweaver has joined #crystal-lang
<FromGitter> <DRVTiny> Convert all elements of what to Hash, add this Hash to output array a
<FromGitter> <DRVTiny> ```code paste, see link``` []
<FromGitter> <DRVTiny> if - elsif maybe rewritten using "case", i know
hightower3 has joined #crystal-lang
hightower4 has quit [Ping timeout: 258 seconds]
<FromGitter> <DRVTiny> ⏎ ⏎ Hmm... That works perfect. Magic. Some unpredictable, capricious magic of Crystal type system
csk157 has joined #crystal-lang
<vivus> is anybody using amber in production?
<FromGitter> <unreadable>
<FromGitter> <unreadable> Amber org is using it xD
<vivus> interesting. I assume it is the rails equivalent of Crystal
<Papierkorb> Kemal is around much longer than Amber
<Papierkorb> And has been maintained the whole time
<FromGitter> <aarongodin> It’s similar for sure, and it does take inspiration from other web frameworks
csk157 has quit [Ping timeout: 240 seconds]
<vivus> so which should 1 use ? kemal or amber?
<FromGitter> <bew> @DRVTiny why do you have thoses NamedTuple or Hash or Array as input? Are you writing them yourself? Or do you get them from different sources that you don't control?
<FromGitter> <r3bo0t> @vivus, if your work is more API centric kemal is better choice
<FromGitter> <r3bo0t> ===amber is definitely more feature enabled by default as compared to #kemal===
<FromGitter> <r3bo0t> and #kemal is more matured in comparison
DTZUZO has quit [Ping timeout: 240 seconds]
Guest12701 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<FromGitter> <kazzkiq> Wanted to thanks @crisward for his awesome email plugin ( Worked like a charm, right on the first try.
<FromGitter> <kazzkiq> Crystal is so simple it often seems wrong. "How that's even working?"
<FromGitter> <asterite> I have the same feeling :-)
<FromGitter> <asterite> Although... this line reminds me of Ruby is Rails, so let's make every gem know about it:
<FromGitter> <asterite> I think we should add a rule to the compiler: if "kemal" appears in the source code but the shard itself is not kemal, give a compile error
linuksz has joined #crystal-lang
<FromGitter> <sdogruyol> @asterite lol, what's that :D
<Papierkorb> there should be a simple, really simple, environment shard which kemal uses to set a good precedenc
<FromGitter> <marksiemers> @vivus - If you are familiar with Sinatra and Rails and know how to decide between those two - that is a good starting point for deciding between Kemal and Amber.
<Papierkorb> then we can tell everyone to rely on that, and if not, that their code is simply bad.
<FromGitter> <marksiemers> If you want an ORM to be integrated more-or-less out of the box, then Amber may be a better choice.
linuksz has left #crystal-lang [#crystal-lang]
<FromGitter> <marksiemers> If you want easy to get up and running, and easy to customize, Kemal may be a better choice.
<FromGitter> <marksiemers> I vote you try out Amber though - and report feature requests and other issues
<FromGitter> <r3bo0t> @asterite thats quick 👏
<FromGitter> <hugoabonizio> @vivus this project uses Amber
Ven has joined #crystal-lang
Ven is now known as Guest53736
<vivus> I plan on building an experimental twitter clone
<FromGitter> <marksiemers> If its a learning experiment - what things are you prioritizing to learn?
linuksz has joined #crystal-lang
<linuksz> Is it possible to write shared libraries in Crystal that are usable in C programs? If yes, how much is it complicated?
<FromGitter> <bew> yes it's possible
<Papierkorb> linuksz: That's "You can totally do that for fun five minutes!" territory
<FromGitter> <bew> oooh nice gist ;)
<linuksz> how much are these usable in real life?
<linuksz> does it worth to write a C compatible library?
<Papierkorb> linuksz: At least if done bare-bones as in the gist. If you're serious about it, you could (should) write a bridge library thing first which does the annoying parts for you. Then, maybe it's reasonable for certain use-cases
<Papierkorb> Now the good part is that we're using boehmgc, which should just work™ for the most part, even if used only by a "guest".
<linuksz> and is the same thing true with python or rust?
<linuksz> (I mean using Crystal lib)
<Papierkorb> The bad part is that the GC won't be able to track pointers that you handed over to the host application if that host doesn't use boehmgc itself. in which case you run into the GC free-ing stuff that's still in use.
<FromGitter> <bew> to me it's pretty useful to write plugins for some C programs that allows plugins via shared libs (like mpv, rofi)
<Papierkorb> linuksz: If you put enough effort into it, you could integrate the hosts GC into Crystal (probably best: Replace boehm with the host GC).
<linuksz> I'm new in the world of compilers, so I didn't understood too much from these.
<linuksz> @bew, do you use Crystal plugins for C programs?
<Papierkorb> bew, consider what I wrote above. You're quickly having the issue of dangling pointers
<FromGitter> <bew> I've experimented with a few, it works well ;) (But I don't use them ATM)
<FromGitter> <bew> Papierkorb yes when the "host" uses a GC.. otherwise you can't..
<FromGitter> <bew> I don't exactly see what you mean Papierkorb about dangling pointers
<FromGitter> <crisward> @kazzkiq thanks!
<Papierkorb> bew: 1) you pass a ptr back to the host. this ptr isn't stored anywhere in the guest 2) the host stores that pointer for later use (takes ownership) 3) Boehm decides to clean up 4) The pointer stored in the host is now a dangling pointer ("use-after-free")
<FromGitter> <crisward> what does everyone think of having a common env var for crystal projects, the determine if your in production, dev, or test environment. A bit like NODE_ENV. Kemal has KEMAL_ENV but it'd be nice to have something more generic everyone could agree on? eg `CRYSTAL_ENV`. @sdogruyol
<FromGitter> <bew> ah yes I know that, one needs to store all things you pass to the host in Crystal-land to prevent that
<Papierkorb> crisward, would be fine by me. A small "lib" in the stdlib would be nice. Even a simple `ENV.production?` would do the trick
<FromGitter> <straight-shoota> @crisward I like the idea, but Im not sure about `CRYSTAL_ENV`... might be confusing as I'd suspect it to be somehow related to `crystal env` or a (not-yet-existing) crystal version manager.
<Papierkorb> I think that'd be a good choice for a name. It's unlikely to conflict with anything, now or in the future
<FromGitter> <straight-shoota> what about something totally generic like `APP_ENV`?
<Papierkorb> That'd be too generic for me
<FromGitter> <faultyserver> Those ENVs are generally done by frameworks, not languages
<FromGitter> <faultyserver> it'd be cool if `APP_ENV` or something similar was adopted by a bunch of frameworks for consistency
<FromGitter> <faultyserver> but I'm with straight-shoota in regards to the potential confusion
<FromGitter> <bew> or more simply, have a `Spec.in_spec?` as the original issue was that it wrongly sent mails from specs
<FromGitter> <crisward> I think the production / dev stages also have a good use case for this.
<FromGitter> <crisward> `CRYSTAL_MODE`?
<FromGitter> <bew> not explicit for me
<Papierkorb> an environment is not a mode of operation
csk157 has joined #crystal-lang
<FromGitter> <crisward> I'd personally go with `CRYSTAL_ENV`, just trying to offer alternatives.
csk157 has quit [Ping timeout: 248 seconds]
alex`` has quit [Ping timeout: 240 seconds]
Guest53736 is now known as Ven``
<FromGitter> <crisward> let the discussion begin
<Papierkorb> Mh, I think I should add to my comment what OTOH would be bad about my proposal
<Papierkorb> there we go
<FromGitter> <crisward> You don't need to encourage disagreement, it just happens naturally. 😉
linuksz has quit [Quit: WeeChat 1.9.1]
<Papierkorb> Yeah I just think this can totally be a "good intention, but still shot into your own foot" kind of thing
<Papierkorb> I'd rather have people come in here if they don't know how to build their lib nicely, than cluttering it with ENV.test? checks. Especially (but not only) newbies will see it, and because it's so easy to use, think it's perfectly fine to do it
<watzon> Is there any way to check if String.sub was successful? In Ruby there is the `sub!` method which returns nil if the sub wasn't successful
<Papierkorb> watzon: good catch, I don't think that's possible. except for doing a == check afterwards
<watzon> Yeah I thought not
<watzon> I feel like it would be nice to have some methods that do that
<watzon> Like `sub!`, `gsub!`, etc
<Papierkorb> String#sub? : { String, Bool } would be possible
<Papierkorb> Or add Regex::MatchData#sub
<Papierkorb> Then you could do a Regex#match(str), and if that's non-nil, do match.sub(str)
<watzon> True. I like the idea of having destructive methods as well though. I'm sure not everyone feels the same
<watzon> So instead of `sub!` just returning the string it would actually modify the original string
<Papierkorb> we won't do that
<Papierkorb> Even Ruby3 is getting rid of mutable strings
<watzon> Oh really?
<Papierkorb> Mh or only literals - which would make sense as far ruby is concerned, that's a huge breaking change
greenbigfrog has quit [Remote host closed the connection]
Ven`` has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<crystal-gh> [crystal] RX14 pushed 1 new commit to master:
<crystal-gh> crystal/master e095e93 Johannes Müller: Fix docs path in .gitignore and Makefile (#5217)...
alex`` has joined #crystal-lang
greenbigfrog has joined #crystal-lang
<FromGitter> <watzon> Ok I need help fixing this line ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ where `string` could be something like "active_record", "activerecord", or even "active_record/name" []
<FromGitter> <watzon> Right now it throws an error if capture group 1 doesn't match
<FromGitter> <watzon> Also `inflections.acronyms` is just a `Hash(String, String)`
<Papierkorb> Don't use the $1... magic variables. gsub yields two arguments: the matched string part, then the match
<FromGitter> <watzon> Ahh ok
<FromGitter> <watzon> Good to know
<Papierkorb> capture the match (`Regex::MatchData`), then use `match[1]?` to maybe-grab the captured group
<FromGitter> <watzon> I'm trying to convert some Ruby code
linuksz has joined #crystal-lang
<linuksz> How much is it harder to create a shared library in Crystal for use with Crystal programs than creating a static library?
<vivus> @marksiemers I want to see how quickly I can develop a barebones project
Ven has joined #crystal-lang
Ven is now known as Guest77569
<FromGitter> <marksiemers> Amber should enable you to develop a twitter clone a little quicker than Kemal.
<FromGitter> <watzon> Thanks Papierkorb, this works but it's not very pretty ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ tips on how to improve it? []
<FromGitter> <marksiemers> Question for `Spec` is there a way to conditionally skip a test or mark it as pending? Likely this will be based on an environment variable, or and option flag, if one exists.
<FromGitter> <watzon> I'm sure there's plenty I can do haha
<FromGitter> <bew> @marksiemers did you tried `pending` ?
<FromGitter> <bew> (instead of `it`)
<FromGitter> <bew> what? what do you mean by "conditionally" ? what's the usecase?
<Papierkorb> watzon, not shorter, but maybe easier to read
<travis-ci> crystal-lang/crystal#e095e93 (master - Fix docs path in .gitignore and Makefile (#5217)): The build was broken.
<DeBot_> (Fix docs path in .gitignore and Makefile)
<Papierkorb> watzon, don't test-and-get, just use #[]? for that
<Papierkorb> If 'acronyms' is of a custom type which is lacking #[]?, then add it
<watzon> Ahh gotcha. No that's perfect
<Yxhuvud> papierkorb: I'd probably end that one with (m[1]? || "") + res
<watzon> Thanks for your help
<Papierkorb> Yxhuvud: I mean you can do that, but I don't like building a new string if there's no prefix
<robacarp> is there a way to type a hash so that the values can be references to classes (either subclassed or inheriting functionality)? I expected `{} of String => Superclass` to work
<Papierkorb> robacarp: referencing a Class, or an instance?
<robacarp> the class
<Papierkorb> Try `Superclass.class`
<Papierkorb> Never tried that, but...
<FromGitter> <marksiemers> @bew - Conditionally "pending" or "skipped" at run time - or a macro would probably do the trick. ⏎ The use case is that a test suite runs in milliseconds without a certain test, and minutes with that test.
<FromGitter> <marksiemers> So during the development workflow, we want it to default to skipping the test
<robacarp> Papierkorb: compiler likes that for a superclass... I can't believe I didn't think of that. thanks!
<FromGitter> <marksiemers> But have the ability to set and environment variable so Travis will run it, and you can also run it locally when you want
<FromGitter> <marksiemers> `RUN_BUILD_TEST=true crystal spec` - something like that
<Papierkorb> marksiemers, I'd have a `spec/slow/` (or similar) directory for the slow tests (just so they're obvious). You can then put something like `{% if flag?(:slow_test) %} require "./slow/*" {% end %}` into your spec/
<Papierkorb> Or "integration" instead of "slow" or whatever you like ;)
<Papierkorb> You can define flags using the -D switch
<FromGitter> <marksiemers> Nice, that sounds like a good solution
<Papierkorb> Also know that you can run the test suite only over a specific file, or directory tree, by specifying the path to `crystal spec HERE`
<Papierkorb> So "only slow stuff" would be simply `crystal spec spec/slow/`
<robacarp> man, that thrashed me for 90min... /o\
<Papierkorb> robacarp: Good to know that actually works lul
<FromGitter> <bew> @Papierkorb @marksiemers `crystal spec/slow` works too, no need for the extra `spec` arg
<linuksz> How much is it harder to create a shared library in Crystal for use with Crystal programs than creating a static library?
<robacarp> it doesn't seem to work when its an included module, which is what I'd prefer, but I'm just happy to be unstuck. thanks again
<FromGitter> <marksiemers> @Papierkorb - Yes, even line numbers, right. That has been very helpful. ⏎ For our build tests, I think we just want to make it a default so newer contributors don't think everything is broken when they run the tests.
<FromGitter> <bew> ah no sorry not working with folders, only with files
<Papierkorb> linuksz: Neither. Crystal programs want to know the source of what they're using. Everything else will be painful, and if you don't have extremely good reasons, "don't"
<Papierkorb> linuksz: Crystal libraries ("shards") are generally source distributions
<Papierkorb> Much like ruby if you want
<linuksz> Papierkorb: so Crystal isn't the best language for e.g. a full featured GUI toolkit?
<Papierkorb> linuksz: I'm the developer of It works great.
<Papierkorb> Qt with Crystal, that is
<linuksz> I mean a GUI toolkit written in Crystal
<Papierkorb> Sure it would be possible, but why wouldn't you want to do a source distribution?
<linuksz> Doesn't statically linked binaries are much larger?
<Papierkorb> The compiler will cache large chunks of the build, after the initial long compilation the time will reduce drastically
<Papierkorb> No?
<Papierkorb> Static and dynamic libraries need to store the same data
<Papierkorb> in fact, if anything, static libs have the chance to be (much) smaller when linked into the target application compared to shared libs
<FromGitter> <faustinoaq> is statically linked and works very well
<Papierkorb> linuksz: And if you "link" to crystal code, it gets as small as it can be. If it ends up being large, the reason is that that code is actually needed by something
<linuksz> But isn't the binary several times larger if the library is compiled into the binary?
<Papierkorb> So?
<Papierkorb> You still have to distribute the dynamic library if you link dynamically
<Yxhuvud> depends on the library. If you only need a little part, it may even be smaller than the linking code.
<Yxhuvud> but maybe not with Qt though :)
<linuksz> I mean e.g. the gtk3 package is 70MiB on my machine. If GTK+ would be compiled into each GTK3 program, and there are 30 gtk3 apps installed on my system, then it would create 30*70Mib overhead
<Yxhuvud> no it wouldn't, as not every program would use every single function gtk3 exposes to the world.
<linuksz> Yxhuvud: how? If I install the libreoffice-fresh package, and the firefox package, and the GTK lib would be compiled into both firefox and libreoffice binary, wouldn't it be much larger than both package depends on the gtk3 package?
<linuksz> and the gtk3 lib is installed once on my system?
<linuksz> 23:12:58 Yxhuvud | no it wouldn't, as not every program would use every single function gtk3 exposes to the world.
<linuksz> e.g. how could firefox use gtk3 if it were compiled into the libreoffice binary?
<Yxhuvud> my claim wasn't that it wouldn't take more space, but that dead code elimination will eliminate the parts each program doesn't use and that it therefore would be less overhead than 70MB per using program.
<linuksz> Sorry Yxhuvud, I'm not good at English, and I misunderstood your sentence.
<linuksz> So if a shard declares 1000 functions, but my program only uses 10, then 990 won't be compiled into the binary?
<Papierkorb> Sure there is overhead, but not *that* bad
<Papierkorb> linuksz: More or less, yes
<linuksz> oh, ok.
<linuksz> thanks
<Papierkorb> For GUI libs and a simple program, maybe a few megs I guess
csk157 has joined #crystal-lang
linuksz has quit [Quit: WeeChat 1.9.1]
csk157 has quit [Ping timeout: 240 seconds]
claudiuinberlin has quit [Quit: Textual IRC Client:]
Guest77569 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Ven has joined #crystal-lang
Ven is now known as Guest44505
<travis-ci> crystal-lang/crystal#e095e93 (master - Fix docs path in .gitignore and Makefile (#5217)): The build passed.
<DeBot_> (Fix docs path in .gitignore and Makefile)
<watzon> Is there a method like Ruby's `Object.const_get`?
<Papierkorb> No
<watzon> Is there any way to do what `const_get` does? Maybe with a macro?
<Papierkorb> Well, what are you actually trying to do?
Guest44505 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<watzon> Basically just check if a constant exists on a module
<watzon> If it does then I want to get its value
<Papierkorb> You *can* do that with macros (And quite easily at that), but that sounds like black magic to me. Is it actually worth it?
<watzon> But I want o to be able to use strings to do it, not the actual namespace. ie. `const_get("MyModule::Const")`
<Papierkorb> Not possible
<Papierkorb> You can use class methods to mimic constant inheritance with optionally changing it if that fits the bill
<watzon> Oh well, I'll figure out a way around it. I'm converting a Ruby lib to Crystal and a lot of things just don't match up haha
<watzon> But I don't know if this method is really all that necessary anyway
<Papierkorb> Don't "convert", but actually port. Many ruby concepts and paradigms don't convert too well, or are actually impossible
<watzon> I guess port is what I meant. I've had to change quite a few methods so far to fit into Crystal concepts
<Papierkorb> Take a double (or if not enough, triple) look whenever meta programming comes into play
<Papierkorb> Many many ruby libs use it without any need.
<Papierkorb> or in other words, Meta programming is a popular sport in ruby
<Papierkorb> Not because it makes sense
<Papierkorb> But because you can™
<watzon> So far I haven't seen too much meta programming surprisingly, but I guess DHH would know how to do things right for the most part
DTZUZO has joined #crystal-lang
<RX14> perhaps we should have a load of "core shards" which are globally installed and we just change CRYSTAL_PATH like "/path/to/stdlib:lib:/path/to/core/shards"
<RX14> and then you can override the core shards requires to update them and they're versioned differently
<RX14> but a version of them can be packages
<RX14> idk it's just a random idea
* robacarp doesnt want
<crystal-gh> [crystal] RX14 closed pull request #4746: JSON output for docs (
tdc has quit [Ping timeout: 240 seconds]
<watzon> Was `alias_method` removed? I'm finding issues about it back in 2014, but it doesn't seem to work now
notdaniel has joined #crystal-lang
<crystal-gh> [crystal] MakeNowJust opened pull request #5222: Fix ASTNode#to_s to wrap with parenthesis as needed (master...fix/crystal/ast-to-s-wrap-parenthesis-as-needed)
illyohs has joined #crystal-lang
* illyohs pokes RX14
<travis-ci> crystal-lang/crystal#2e00b8f (master - Add json export to docs generator (#4746)): The build passed.
* RX14 pokes illyohs
<RX14> watzon, we removed it, and decided to remove as many aliases as possible from the language
<RX14> having 1 method with essentially 2 names just means all developers have to learn and remember both names, as invariably they'll see both in the wild
<RX14> so it's better to just have 1 name and avoid the bikeshedding, debate, and duplication
<watzon> True, I guess it is a bit antipattern
<watzon> big*
<RX14> i found an alias in XML::Node a few days ago
<RX14> i should probably remove it
<FromGitter> <faustinoaq> RX14, What are your favorite programming languages in addition to Crystal? 😄