ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.31.1 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <ilanpillemer> so a sort by with a secondary sort..
<FromGitter> <ilanpillemer> if two values are equal the secondary sort should apply
<FromGitter> <tenebrousedge> `sort_by {|x| [x.value1, x.value2] }`
<FromGitter> <ilanpillemer> interestinly char does not seem to have a natural sort order
<FromGitter> <tenebrousedge> I guess you can use `c.ord`
<FromGitter> <tenebrousedge> but that is odd
<FromGitter> <ilanpillemer> you should just be able to use the unicode/ascii value
<FromGitter> <tenebrousedge> are you sure that's not a thing?
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da50d41894dee56e5442256]
<FromGitter> <tenebrousedge> well, okay
<FromGitter> <tenebrousedge> it doesn't compare with `Int`
<FromGitter> <tenebrousedge> but `'a' < 'c' #=> true `
<FromGitter> <ilanpillemer> so the sort by needs to compare different parts of the array value
<FromGitter> <tenebrousedge> you need to narrow your type for `<=>` to work
<FromGitter> <tenebrousedge> what exactly does your code look like?
<FromGitter> <ilanpillemer> ```room.each_char.tally.invert.to_a.sort_by { |x| [x[0], x[1]] }.reverse```
<FromGitter> <tenebrousedge> `sort_by {|(a, b)| [a, b] }` for one thing
<FromGitter> <ilanpillemer> same error
<FromGitter> <tenebrousedge> apparently `[a.as(Char), b.as(Int32)]` works
sorcus has quit [Ping timeout: 250 seconds]
<FromGitter> <tenebrousedge> well, I used a tuple
sorcus has joined #crystal-lang
<FromGitter> <tenebrousedge> fixed
<FromGitter> <tenebrousedge> using an array doesn't work because each element is `Char | Int32`
<FromGitter> <ilanpillemer> ahh.. after the `to_a`
<FromGitter> <tenebrousedge> or in the `sort`
<FromGitter> <ImAHopelessDev_gitlab> me right now (https://i.imgur.com/50W5AhF.png)
<FromGitter> <tenebrousedge> I'm surprised that didn't happen a long time ago
<FromGitter> <tenebrousedge> a while back, `&.` was proposed by some Crystallists for inclusion in Ruby
<FromGitter> <ilanpillemer> Anyway.. tomorrow I will try understand better.
<FromGitter> <tenebrousedge> kk
<FromGitter> <ilanpillemer> and what happened?
<FromGitter> <tenebrousedge> people hated it
<FromGitter> <tenebrousedge> "Waaaagh why change Ruby? This is so illogical!"
<FromGitter> <tenebrousedge> "Not intuitive! It sux!"
<FromGitter> <tenebrousedge> I may be overstating the intelligence of the responses. It was profoundly disappointing, particularly in light of crazy decisions they've made since
alex``` has quit [Ping timeout: 240 seconds]
absolutejam has joined #crystal-lang
absolutejam has quit [Ping timeout: 240 seconds]
f1refly has quit [Ping timeout: 246 seconds]
f1refly has joined #crystal-lang
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
<FromGitter> <asterite> It was me who proposed &. for Ruby but they said it's not consistent, I don't know why
<FromGitter> <asterite> Also, I think we could add sort_by to Hash, keys are stored in a separate Array, sorted by insertion. So sorting that secondary array would be really easy
<FromGitter> <asterite> I might give it a try one of these days
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <asterite> Also, I forked Ruby because I recently found a bug in irb for Ruby 2.7 so I sent a PR some hours ago
<FromGitter> <tenebrousedge> do you read everything that happens here?
<FromGitter> <asterite> Haha, it sounds scary said like that ^_^
<FromGitter> <watzon> Question. Is there a way to create an Array of class type definitions using the `Array(Type.class).new` method instead of `[] of Type.class`. Obviously it fails because `Type.class` isn't seen as a constant, so I assume I could just create a constant and pass that in.
<FromGitter> <watzon> But is there a better way?
<FromGitter> <asterite> I enter from time to time to read what you are all up to, maybe give a hand with something
<FromGitter> <asterite> Most of the time I learn something new I didn't know about Crystal :-P
<FromGitter> <tenebrousedge> o_O
<FromGitter> <asterite> Like, ways to do algorithms, or clever macros
<FromGitter> <asterite> Or cool usages of annotations
<FromGitter> <tenebrousedge> @watzon don't all constants have to exist at compile time?
<FromGitter> <watzon> Annotations are awesome
<FromGitter> <asterite> I think Array(Type.class) should work
<FromGitter> <watzon> Oh wait, you know what I think I made a mistake in my code
<FromGitter> <watzon> Lemme check
<FromGitter> <watzon> Yep, this is the problem with creating classes that have the same name as built-ins lol
chemist69 has quit [Ping timeout: 246 seconds]
chemist69 has joined #crystal-lang
ht_ has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> nice one, @asterite πŸ‘ https://github.com/ruby/ruby/pull/2555
<FromGitter> <ImAHopelessDev_gitlab> "A PROGRAMMER'S BEST FRIEND"
<FromGitter> <ImAHopelessDev_gitlab> that's how I feel with Crystal, well.. prob because I started with Crystal not Ruby. But damn that's so true.
<FromGitter> <ImAHopelessDev_gitlab> There definitely is something with the elegance of the syntax the resonates with you
ht_ has quit [Quit: ht_]
<FromGitter> <watzon> Crystal is pretty great
absolutejam has joined #crystal-lang
absolutejam has quit [Ping timeout: 276 seconds]
ma_ has joined #crystal-lang
dwdv_ has joined #crystal-lang
ma_ has quit [Read error: Connection reset by peer]
livcd has quit [Quit: Lost terminal]
absolutejam has joined #crystal-lang
<FromGitter> <bajro17> @watzon I still wait to become your colleague
<FromGitter> <bajro17> :D
<FromGitter> <bajro17> to we work in same company
jrayhawk has quit [Quit: migration]
jrayhawk has joined #crystal-lang
livcd has joined #crystal-lang
Yxhuvud has quit [Read error: Connection reset by peer]
FromGitter has quit [Read error: Connection reset by peer]
FromGitter has joined #crystal-lang
flaviodesousa has joined #crystal-lang
absolutejam has quit [Ping timeout: 265 seconds]
<FromGitter> <cserb> For how long does play.crystal-lang.org keep the code saved?
<oprypin> cserb, this probably hasnt been given much thought, so "forever"
absolutejam has joined #crystal-lang
dwdv_ has quit [Ping timeout: 245 seconds]
<FromGitter> <mavu> Morning, I am looking for an example/code for something I have not done before: ⏎ I am considering using Crystal to interface with Cisco UCCX CTI which is a protocol used in Cisco callcenter agent software. ⏎ This protocol is "bytes on a wire" over TCP, and I have never done such low level implemetation. ⏎ Could someone suggest a place where I can see some best practices and patterns how this kind of thing
blassin has quit [Quit: The Lounge - https://thelounge.chat]
blassin has joined #crystal-lang
blassin has quit [Client Quit]
blassin has joined #crystal-lang
<FromGitter> <sam0x17> if it's over TCP and not over UDP, then it isn't really that low level. My advice is to make a bunch of structs to describe the different packets, and maybe use channels as an abstraction before you send/receive from network, so you can easily spoof the network for testing
<FromGitter> <sam0x17> or whatever abstraction you like, channels sound fun though
<FromGitter> <sam0x17> with a channel, you can have it accept only your packet structs, so it will be impossible to send invalid data in theory
<FromGitter> <sam0x17> @mavu
<FromGitter> <sam0x17> there are some really good java examples floating around for that
<FromGitter> <sam0x17> as a lot of 300-level cs networking classes do that stuff
<FromGitter> <sam0x17> things like implementing a UDP chat client (though you are over TCP)
<FromGitter> <sam0x17> you'll have to do an unsafe_as cast most likely to get the raw bytes of the struct when sending
<FromGitter> <sam0x17> in terms of best practices, just bear in mind that even with TCP, you can end up receiving arbitrary garbage at any time (especially in the case of a malicious client), so even if you trust the client, you should design things such that you are handling every possible error (or at least gracefully failing)
<FromGitter> <sam0x17> that said, TCP guarantees data integrity to a certain extent, but in practice clients don't behave so you still have to distrust everything
<FromGitter> <sam0x17> be careful if there are strings involved, that takes special handling when working with a binary protocol
<FromGitter> <sam0x17> that's my 2 cents xD
<FromGitter> <mavu> @sam0x17 thank you, those are helpful concepts. ⏎ So, I would make structs and add a custom serialization method that produces the bytes to send, or is there some mechanism already builtin to structs?
<FromGitter> <mavu> Using channels as an abstraction layer is also nice too. I'll definitely do that.
alex``` has joined #crystal-lang
davic has quit [Ping timeout: 250 seconds]
dwdv_ has joined #crystal-lang
dwdv_ has quit [Ping timeout: 268 seconds]
<FromGitter> <fenicks> Hi guys,
<FromGitter> <fenicks> I'm trying to use db connection and my password (I can't change it now) has a '@'. How can protect the first '@' id db uri ?
DTZUZO has quit [Ping timeout: 265 seconds]
DTZUZO has joined #crystal-lang
<FromGitter> <andrius> It is possible to get value assigned to the JSON::Any in a elegant way? ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da5b7c7c87a1d28acb3c73b]
<FromGitter> <tenebrousedge> @andrius is this json data totally without any sort of schema?
<FromGitter> <andrius> without schema, it is an further "event filter" vs real events. the only condition: it is a hash of stings or hash of hashes of strings
DTZUZO has quit [Ping timeout: 240 seconds]
<FromGitter> <andrius> in most of the cases I will use 'type' in filters but not always, other fields could be random
<FromGitter> <andrius> and value for type is always a string
<FromGitter> <tenebrousedge> the elegant way is to use JSON::Serializable or the `mapper` to put your data into structs
<FromGitter> <tenebrousedge> beyond that, @Blacksmoke16 probably has some ideas
DTZUZO has joined #crystal-lang
<FromGitter> <andrius> I am thinking on that but that would work only for first level, so ... ;)
DTZUZO has quit [Ping timeout: 268 seconds]
<FromGitter> <andrius> example of usage ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da5bb66809de9699f404070]
<FromGitter> <andrius> and this ```# Set custom event handler for event "ChannelStateChange" and channel ⏎ ⏎ #channel_id ⏎ ⏎ event_filter = JSON.parse(%({"type": "ChannelStateChange", ... [https://gitter.im/crystal-lang/crystal?at=5da5bba880e62056e40b0b31]
<FromGitter> <Blacksmoke16> there is a dig method you could use maybe
<FromGitter> <Blacksmoke16> otherwise, how many event types are there?
<FromGitter> <sdogruyol> Hey everyone πŸ‘‹ Long time no see, how's it going?
<FromGitter> <Blacksmoke16> o/
<FromGitter> <sdogruyol> Hey @Blacksmoke16, thanks a lot for all the PRs and issues πŸ‘
<FromGitter> <sdogruyol> can't keep up with you :P
<FromGitter> <Blacksmoke16> think you might have the wrong person :p
<FromGitter> <sdogruyol> probably...haven't been sleeping well hahah
<FromGitter> <mavu> Ok, I feel stupid, but how do I get from a Int(i.e. 42) to a 4 byte representation that is part of a protocol I'm trying to 'speak' to a server. ⏎ The server expects for example a message header with 4 bytes of content length and then 4 bytes of message ID. ⏎ how do I construct a Slice that has 4 bytes and represents the number 42 or whatever.
<FromGitter> <mavu> I'm sure I am missing something completely obvious, but I cant see it.
<erdnaxeli> maybe by doing a pointer of this Int and using to_slice() ? https://crystal-lang.org/api/0.20.0/Pointer.html#to_slice%28size%29-instance-method
<FromGitter> <firejox> @navu use `unsafe_as` https://crystal-lang.org/api/0.31.1/Object.html#unsafe_as(type:T.class)forallT-instance-method
davic has joined #crystal-lang
DTZUZO has joined #crystal-lang
<FromGitter> <mavu> @firejox ahh, that looks like what I need. thanks.
return0e_ has joined #crystal-lang
HumanGeek has joined #crystal-lang
return0e has quit [Ping timeout: 240 seconds]
HumanGeek has quit [Remote host closed the connection]
HumanGeek has joined #crystal-lang
Human_G33k has quit [Ping timeout: 240 seconds]
<FromGitter> <bajro17> @sdogruyol welcome back my dear Serdar thanks for tweet about this shopify CEO it encourage me to keep going with crystal :)
<FromGitter> <ilanpillemer> what was discouraging you before?
DTZUZO has quit [Ping timeout: 240 seconds]
<FromGitter> <sdogruyol> @bajro17 you're welcome, anytime!
<FromGitter> <sdogruyol> @ilanpillemer I think he meant it motivated him more
DTZUZO has joined #crystal-lang
swin has joined #crystal-lang
<swin> Hi, is there any ORM recommendation?
<FromGitter> <Blacksmoke16> you have a few options. what db were you going to use?
<swin> PostgreSQL
<FromGitter> <Blacksmoke16> https://github.com/amberframework/granite/ - One im most familiar with ⏎ https://github.com/imdrasil/jennifer.cr ⏎ https://github.com/anykeyh/clear/ - PG only ⏎ https://github.com/luckyframework/avram/ - Used with Lucky, and also PG only. Imagine it could be used outside of Luck [https://gitter.im/crystal-lang/crystal?at=5da5dd87870fa33a4df8fa40]
flaviodesousa has quit [Quit: KVIrc 4.9.3 Aria http://www.kvirc.net/]
<FromGitter> <Blacksmoke16> if you're planning on using annotations for anything (serialization/validations for example) afaik granite is the only one that supports that
<FromGitter> <andrius> @Blacksmoke16 sorry, were out, work meetings. There is about 50 events
<FromGitter> <Blacksmoke16> ouch, yea deserializing the data into a struct or something would be most ideal
<FromGitter> <Blacksmoke16> i assume most of those events have diff properties?
<swin> @Blacksmoke16 Thanks! I've tried `clear` but it didn't work on my machine (said I need to install a library), I will try it again.
<FromGitter> <Blacksmoke16> what library?
<swin> @Blacksmoke16 `/usr/bin/ld: cannot find -lgmp (this usually means you need to install the development package for libgmp)`
<FromGitter> <Blacksmoke16> does crystal work for you?
<swin> Yes, I tried with `Kemal`
<FromGitter> <Blacksmoke16> crystal uses that lib internally for some math related stuff
<FromGitter> <andrius> yes, and I already have events
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da5dfeaf1c89c0758f34abf]
<FromGitter> <Blacksmoke16> id imagine that wouldnt work locally for you, which clear is prob using big to support some column types
<FromGitter> <Blacksmoke16> so would just have to install libgmp as it says
<FromGitter> <andrius> now I implement event filters for callbacks/hooks. I want to get them triggered only when certain event with conditions will occur. I made `json_includes?` that does perform search
<swin> @Blacksmoke16 Oh, it doesn't run. OK, I will install that package. Thanks! :)
<FromGitter> <Blacksmoke16> np
ht__ has joined #crystal-lang
<FromGitter> <Blacksmoke16> if every event and type referenced within each event includes `JSON::Serializable` it should work
<FromGitter> <Blacksmoke16> assuming your JSON string has the data for the nested types
<FromGitter> <Blacksmoke16> also FWIW you could simplify the event to be like
swin has quit [Quit: Leaving]
<FromGitter> <Blacksmoke16> ```struct Asterisk::ARI::Events::BridgeDestroyed ⏎ property bridge : Bridge ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5da5e12465dd8569a0e0562b]
<FromGitter> <Blacksmoke16> or even ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da5e14a89acff6ff5fe3247]
absolutejam has quit [Ping timeout: 265 seconds]
<FromGitter> <sam0x17> happy to report that crystal is being used in a research capacity within the DoD ^_^
<FromGitter> <tenebrousedge> whoo boy
<FromGitter> <sam0x17> some scientists have a lot of autonomy, and use things like Rust etc, and one asked me several crystal questions
gangstacat has quit [Quit: Ĝis!]
<FromGitter> <kinxer> @sam0x17 I assume you can't give more info than that (e.g. which lab/office)?
<FromGitter> <sam0x17> nope ^_^
<FromGitter> <vlazar> what's DoD?
<FromGitter> <sam0x17> U.S. department of defense
<FromGitter> <kinxer> A'ight. :) I use Crystal at work as a contractor, so it would be nice to know if our company could make some Crystal connections on the government side.
<FromGitter> <sam0x17> @kinxer there is no general approval, but it is in use by a few isolated groups with autonomy, think national labs, AFRL, NRL type situations, etc
<FromGitter> <kinxer> That makes sense. It's encouraging to know.
<FromGitter> <vlazar> @sam0x17 I guess Crystal popularity can skyrocket soon? ;)
<FromGitter> <sam0x17> 90% of that is rust but seems to be a little bit of crystal
<FromGitter> <sam0x17> hah, well I would argue that python's skyrocketing is due to it being installed by default on all DoD machines, which steered AI research in the direction of python for the past 20 years
<FromGitter> <sam0x17> and you can peg that on apt and a few package managers deciding to use python
<FromGitter> <asterite> @mavu you probably want https://crystal-lang.org/api/0.31.1/IO.html#write_bytes(object,format:IO::ByteFormat=IO::ByteFormat::SystemEndian)-instance-method
<FromGitter> <rishavs> Need some help. I am trying to parse html and get the url to embedded images from a site url. If the url itself is a path to the image, I would just take that. ⏎ I am getting an SSL error, which I am not able to grok; ⏎ `Unhandled exception: SSL_shutdown: error:14094123:SSL routines:ssl3_read_bytes:application data after close notify (OpenSSL::SSL::Error)` ⏎ ⏎ Here is a quick repl.it with the code
<FromGitter> <sam0x17> @kinxer in the mean time, your best bet is to use something that can compile to an approved language like C++ (I think nim can?)
gangstacat has joined #crystal-lang
<hypercore> is crystal as performant as go?
<FromGitter> <sam0x17> its close enough that it depends on whatever skewed benchmark methodology you decide to use, am I right?
<FromGitter> <kinxer> We mostly use C++ and Java, but one project uses Crystal, and I've had the chance to create some development support tools for the company in Crystal.
<FromGitter> <sam0x17> gotcha
<FromGitter> <sam0x17> acquisition people won't know what crystal is
<FromGitter> <sam0x17> there is a 1% chance they will know what rust is
<FromGitter> <kinxer> I've also been looking into Rust, since it can be compiled into a shared object that you can use from C, but I don't know if and when I'll be able to try using it.
<FromGitter> <sam0x17> but its going to be probably over a decade before you can start getting gov contracts to use that stuff
<FromGitter> <kinxer> Yeah, which is a bummer.
<FromGitter> <kinxer> An understandable bummer, but a bummer nonetheless.
<FromGitter> <sam0x17> but like I said, encourage the authors of your favorite language to add the ability to compile to C++
<FromGitter> <sam0x17> then your conversation with acquisitions is just "it's in C++"
<FromGitter> <sam0x17> stuff that runs on bytecode also has an in, so Kotlin is probably usable
<FromGitter> <tenebrousedge> hypercore, you can Google for benchmarks. The ones I've seen are generally in the same ballpark, but Go seems to have an edge
<FromGitter> <sam0x17> it's one of those things where it's almost always a benchmark specific difference (e.g. programmer knows one language better than the other and doesn't know how to take advantage of X optimization, so benchmark is biased)
<hypercore> they're both LLVM, does that mean performance is theoretically similar?
<FromGitter> <sam0x17> right
<FromGitter> <sam0x17> all the compiled LLVM languages are within the same magnitude of performance
<FromGitter> <kinxer> @rishavs https://repl.it/repls/BurdensomeAngelicWheel and https://crystal-lang.org/api/0.31.1/HTTP/Client.html#get(url:String%7CURI,headers:HTTP::Headers?=nil,body:BodyType=nil,tls=nil,&block)-class-method
<FromGitter> <sam0x17> give or take some constant factor
<FromGitter> <Blacksmoke16> repl.it uses a quite older crystal version btw
<FromGitter> <kinxer> It looks like you need to set the `tls` argument to something (though I'm not sure what).
<FromGitter> <sam0x17> has anyone tried the crystal katas on codewars.com? I didn't realize they had added crystal support
<FromGitter> <straight-shoota> hypercorde, there is an alternative Go compiler using an LLVM backend, but the default compiler does not use LLVM
<FromGitter> <straight-shoota> *hypercore
<hypercore> oh ok
<hypercore> must've been getting it confused with swift
<FromGitter> <sam0x17> I legitimately thought it was LLVM xD
<FromGitter> <sam0x17> but that makes sense go is a bit older
<FromGitter> <straight-shoota> Rust is also on LLVM
<FromGitter> <sam0x17> ^
<FromGitter> <straight-shoota> Rust and Go both came around in 2009/10 and LLVM had been available at that time, so it's not just Go's age
<FromGitter> <vlazar> hypercore, some bencmarks here https://www.techempower.com/benchmarks/#section=data-r18&hw=ph&test=json&l=zdjvnj-f
<FromGitter> <rishavs> @kinxer , your code is also throwing the same error. ⏎ https://repl.it/repls/BurdensomeAngelicWheel
<FromGitter> <kinxer> I've been messing with it.
<FromGitter> <kinxer> Your code works if you just remove the `s` from `https` on your URL (not ideal, of course).
<FromGitter> <kinxer> I'm currently trying to figure out how to use an SSL context (and have actually succeeded in getting a different error).
<FromGitter> <vlazar> oh, TFB benchmarks are using Crystal 0.26.1... time flies
<hypercore> yeah i saw the techempower benchmarks, amber seems to match most go frameworks, i use lucky so it should be similar i imagine
<FromGitter> <tenebrousedge> @rishavs passing a block is what's making it explode
<FromGitter> <vlazar> I think results should be better with 0.31.1 and upcoming 0.32.0
<FromGitter> <vlazar> also TFB are not optimized for max throughput at the moment which is default view
<FromGitter> <kinxer> @rishavs My bad, I was wrong about getting a different error.
<hypercore> wow rocket (the rust framework is has a terrible score on that benchmark)
<FromGitter> <kinxer> @rishavs Based on what @tenebrousedge said: https://repl.it/repls/BurdensomeAngelicWheel
<hypercore> how does amber/lucky compare to phoenix?
<hypercore> when would you use one over the other?
<FromGitter> <rishavs> @tenebrousedge , i should be able to use blocks with Client.get as is shown here https://crystal-lang.org/api/0.31.1/HTTP/Client.html#get(url:String%7CURI,headers:HTTP::Headers?=nil,body:BodyType=nil,tls=nil,&block)-class-method
<FromGitter> <rishavs> @kinxer , your code works but I am more confused now. AM i not supposed to use the block version of Http::client.get?
<FromGitter> <tenebrousedge> Maybe you should be able to, but if it throws an error...
<FromGitter> <kinxer> @rishavs I'm not sure. I suspect it has something to do with the block ending before the SSL context expects it to end, though.
<FromGitter> <rishavs> Should I log this as a bug?
<FromGitter> <tenebrousedge> SSL issues are usually misconfiguration rather than a problem with Crystal
<FromGitter> <tenebrousedge> which is not to say filing an issue would be a bad idea, but it's probably good to research this issue thoroughly first to make sure that this is incorrect behavior
davic has quit [Read error: Connection reset by peer]
<FromGitter> <vlazar> > <hypercore> wow rocket (the rust framework is has a terrible score on that benchmark) ⏎ ⏎ not necessarily mean it's good benchmark, can be some misconfiguration
<FromGitter> <vlazar> I mean implementation for rocket
<FromGitter> <rishavs> I got the block to work by using a Client.get block inside of a Client.new block. -__- ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da5f0e84afd703a4ee55f16]
<FromGitter> <tenebrousedge> how very interesting
<FromGitter> <tenebrousedge> seems like a lot going on for an `initialize` method though
<FromGitter> <kinxer> @rishavs I updated my repl.it (https://repl.it/repls/BurdensomeAngelicWheel).
<FromGitter> <kinxer> Also, I agree with @tenebrousedge. This would make more sense as a class method, like `Image.parse_uri`.
<FromGitter> <tenebrousedge> I would probably want to write an `each_site` method that would do `yield result`
<FromGitter> <rishavs> Thanks both of you! I will be using a method instead of the initialize, as you suggested.
<FromGitter> <tenebrousedge> so then you might do `SiteList.new(sites).each_site.partition &.end_with?(",jpg")
<FromGitter> <rishavs> @tenebrousedge , I actually need to parse only 1 site per http client.
<FromGitter> <tenebrousedge> yes, but multiple clients, yeah?
<FromGitter> <rishavs> I am making a link aggregating site like HN and each post will spawn a client which will get the thumbnail for that page
<FromGitter> <Blacksmoke16> could use https://github.com/watzon/arachnid
<FromGitter> <Blacksmoke16> is essentially what you need
<FromGitter> <rishavs> I am less worried about the scraping itself as I plan on using the open graph tags. This works fine for me; ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da5f37889acff6ff5feb106]
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <Blacksmoke16> the image var is kinda useless
<FromGitter> <rishavs> I am trying to use pretty much no libraries if I can help it. On the client side, I've got vanilla js going on without using any bundler
<FromGitter> <sam0x17> right on, that's my stack
<FromGitter> <rishavs> shameless plug: I wrote an article on the front end part, in case anyone is interested https://dev.to/rishavs/making-a-single-page-app-in-ye-good-olde-js-es6-3eng :D
<FromGitter> <naqvis> @rishavs your initial code is failing due to abnormal IO termination, if your main intention is to validate the URL then I would suggest to go with `head` instead of `get`
<FromGitter> <sam0x17> if you need asset minification for that @rishavs , I actually got html-minifier, uglify-js, and clean-css working directly in crystal via duktape.cr, though I haven't cleaned up the repos yet and there isn't much customization, but the defaults are very sane: https://sam0x17.github.com/html-minifier https://sam0x17.github.com/css-minifier https://sam0x17.github.com/js-minifier
<FromGitter> <sam0x17> TLDR: minify css, javascript, and/or HTML directly from within crystal, without having nodejs installed. Duktape is a lightweight c++ based runtime environment for javascript, and duktape.cr provides very complete bindings
<hypercore> does that mean you can run a web app using a single binary?
<FromGitter> <sam0x17> yup
<FromGitter> <sam0x17> or package one or whatever
<hypercore> sweet
<FromGitter> <sam0x17> NOW links are correct -- I kept doing sam0x17.github.com rather than github.com/sam0x17 xD
<FromGitter> <sam0x17> I've been meaning to clean them up and get amber and lucky to use them, but so busy with other stuff
<FromGitter> <vlazar> you might wanna take a look at Terser instead of Uglify for js-minifier
<FromGitter> <sam0x17> thanks for the tip, I wasn't aware
<FromGitter> <sam0x17> the tricky part is finding a version with npm stripped out
<FromGitter> <sam0x17> *node
<FromGitter> <sam0x17> has to be vanilla ES5
<FromGitter> <vlazar> I see
return0e_ has quit [Remote host closed the connection]
<FromGitter> <vlazar> how is the speed of Duktape btw, is it good enough compared to v8?
return0e has joined #crystal-lang
<FromGitter> <sam0x17> I think they have benchmarks on their site. It's fast
<FromGitter> <sam0x17> best part is its basically a single header file
<FromGitter> <sam0x17> versus V8 which is like LOL
<FromGitter> <sam0x17> I wouldn't use it to directly serve a live page though, more like cache the result in a variable and only re-minify if there is a change, or just minify at compile time sort of thing
<FromGitter> <sam0x17> but that goes for all minification imo
<FromGitter> <rishavs> How about Ballad's quickjs? HN was pretty excited about ithttps://news.ycombinator.com/item?id=20411154
<FromGitter> <sam0x17> ooh, exciting because it supports ES2019
<FromGitter> <sam0x17> I didn't make the duktape bindings, but this would definitely be worth bringing into crystal
<FromGitter> <rishavs> ES2020 actually and is tiny
<FromGitter> <sam0x17> nice
<FromGitter> <vlazar> was trying to find it
<FromGitter> <vlazar> yeah, looks cool
<FromGitter> <vlazar> how hard is it to create bindings?
ht__ has quit [Quit: ht__]
ht__ has joined #crystal-lang
<FromGitter> <sam0x17> not that hard
<FromGitter> <sam0x17> mostly depends on how easy it is to build the project -- have to have it build in a hook
<FromGitter> <sam0x17> and how extensive the API for it is
<FromGitter> <rishavs> qq; How would one write "if given string ends in any element of an array of strings?" ⏎ Currently, I am doing ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da603ccf88b526fb9440286]
<FromGitter> <Blacksmoke16> `[arr of options].any? { |val| str.ends_with? val }`
<FromGitter> <rishavs> Thanks!
dwdv_ has joined #crystal-lang
<FromGitter> <sam0x17> for optimality, you should extract the file extension, use a `Set` of the file extensions you want, and see if `set.includes?(ext)` to avoid the if chain.
<FromGitter> <Fryguy> `File.extname` gets you the extension
<FromGitter> <sam0x17> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da60719158cfd6735379a19]
<FromGitter> <Fryguy> So, `Set{".jpg", ".jpeg", ".png", ".gif"}.includes?(File.extname(uri.path)`
<FromGitter> <sam0x17> oh that's even better yeah
<FromGitter> <sam0x17> didn't know about the literal notation
<FromGitter> <Blacksmoke16> at that point just use a tuple?
<FromGitter> <Fryguy> or that would work too
<FromGitter> <sam0x17> not sure if you are supposed to include the "."
<FromGitter> <Fryguy> File.extname returns it with the "."
<FromGitter> <sam0x17> but yeah also definitely store the set in a constant
<FromGitter> <Fryguy> even so, at this small of a list an Array, Set, Tuple are practically the same perf-wise
<FromGitter> <sam0x17> unless someone here knows that the compiler will optimize that the same way
<FromGitter> <sam0x17> totes
<FromGitter> <sam0x17> I wasn't sure if there were way more extensions
<FromGitter> <Blacksmoke16> if you have the file might also be able to use MIME type of it
<FromGitter> <sam0x17> yes, that is often key with user submitted images
<FromGitter> <sam0x17> and often they wont have an ext
<FromGitter> <bew> Array and Set would need to allocate something, Tuple does not
<FromGitter> <sam0x17> but negated if you do it in a constant
<FromGitter> <sam0x17> as in at that point who cares if its heap or stack
<FromGitter> <sam0x17> though you could make the micro amount of extra startup time argument I suppose
<FromGitter> <bew> It's the same in a constant afaik
<FromGitter> <sam0x17> what I mean is if its in a constant you remove the set initialization overhead from whatever method we are actually in
<FromGitter> <sam0x17> but you still deal with that when the app first launches
<FromGitter> <bew> Ah yes, right
<FromGitter> <sam0x17> does Tuple have some sort of O(1) includes? method I don't know about?
<FromGitter> <sam0x17> so good for a web app, bad for implementing grep
<FromGitter> <Fryguy> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da6093e4fefd829ea3f7bbe]
<FromGitter> <Fryguy> I'm actually surpised how much faster a tuple is over a set const ... I figured it be faster, but not 5x faster
<FromGitter> <Fryguy> probably because it's on the stack and not the heap
<FromGitter> <Blacksmoke16> main benefit of a set is that ofc it cant have duplicates
<FromGitter> <Blacksmoke16> its more of a hash than an array
<FromGitter> <Blacksmoke16> or tuple for that matter
<FromGitter> <rishavs> interesting discussion to follow for me. And thanks for all the suggestions!
<FromGitter> <Fryguy> Set uses a Hash under the covers, but does it do any tricks when there are a small number of items?
<FromGitter> <Fryguy> I think Ruby does that in that Set uses an Array when there are only a handful of items, since the Hash overhead isn't worth it
<FromGitter> <Fryguy> or I forgot I can just read the source cause it's in Crystal πŸ˜† - and no, it's just a wrapper around a Hash
<FromGitter> <kinxer> These are the results I got: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da60d1080e62056e40d6a1b]
<FromGitter> <kinxer> (code (https://play.crystal-lang.org/#/r/7t64))
<FromGitter> <kinxer> It's strange to me that the constant tuple is slower than the literal tuple...
<FromGitter> <ilanpillemer> in `Go` they dont bother to provide Set. The docs just say use Hash.
<FromGitter> <ilanpillemer> isnt a constant compiled at compile time?
dannyAAM has quit [Quit: znc.saru.moe : ZNC 1.6.2 - http://znc.in]
<FromGitter> <tenebrousedge> yes
dannyAAM has joined #crystal-lang
<FromGitter> <ilanpillemer> so normally constants are faster, unless a compiler can work out that a literal can be changed to a constant during optimisation?
<FromGitter> <ilanpillemer> unless I am just still too much of a novice at language hacking
<FromGitter> <kinxer> I thought that non-class constants were inlined, so I'd expect the constant and literal tuple to be about equivalent in speed.
<FromGitter> <tenebrousedge> I think that tuples are fast because they have a defined size
<FromGitter> <kinxer> Yeah, I'm not surprised that tuples are the fastest, but I am surprised about how much of a difference there is between using a constant tuple and a literal tuple.
<FromGitter> <kinxer> And that the literal tuple is faster.
<FromGitter> <tenebrousedge> I mean, a constant is a reference, right?
<FromGitter> <asterite> @Fryguy bad benchmark, you should create Set, array, etc., outside of the block, otherwise you are benchmarking creating those structures too
<FromGitter> <Fryguy> that was intentional
<FromGitter> <kinxer> I thought that it was a reference when its type inherited from `Reference` or `Object` and inlined when its type inherited from `Value` (as `Tuple` does).
<FromGitter> <asterite> ah, okay
<FromGitter> <Fryguy> I moved 1 set out of the block into a const and the tuple is technically static as well
<FromGitter> <kinxer> @Fryguy Did you run your benchmark with `--release`?
<FromGitter> <Fryguy> was just trying to get a comparison with building it over and over
<FromGitter> <Fryguy> @kinxer yes
<FromGitter> <kinxer> Hm... I'll change my benchmark so it doesn't use `File.extname`.
<FromGitter> <Fryguy> yeah I removed the File.extname because that would hav eto be done regardless, so it's noise in the benchmark
<FromGitter> <kinxer> Though it is more indicative of how much actual effect differing the data structure will have.
<FromGitter> <ilanpillemer> this is clearly *not* idiomatic, but how do you these do until strange conditions in idiomatic crystal?
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da61045809de9699f42bd21]
<FromGitter> <tenebrousedge> loop normally, use `break` on condition?
<FromGitter> <ilanpillemer> thats what I am doing effectively with a while
Yxhuvud has joined #crystal-lang
<FromGitter> <Fryguy> The loop; break style allows you to put the conditionals at the end and offer an "at least once" loop as opposed to while
<FromGitter> <Fryguy> so you don't necessarily need the "setup for the first loop" bits
<FromGitter> <Fryguy> is that what you were asking for?
<FromGitter> <ilanpillemer> not really. I was wondering if there was a one liner fluent version.
<FromGitter> <Fryguy> oh I think one-liner loops were specifically avoided in the language design
<FromGitter> <ilanpillemer> πŸ‘
<FromGitter> <ilanpillemer> I just want to make sure I am not missing some significantly better way.
<FromGitter> <tenebrousedge> `while` should generally be used when the maximum number of iterations cannot be known
<FromGitter> <tenebrousedge> here there seems to be a knowable maximum
<FromGitter> <Fryguy> if there's a knowable count, then one can also do `counter.times {}` or `1.upto(counter) {}`
<FromGitter> <tenebrousedge> or `(0...str.size).map`
<FromGitter> <tenebrousedge> which it seems that the index is being used here
<FromGitter> <Fryguy> that screenshot reminds me of hacker movies where the hacker hooks up a device to a computer or a safe and it slowly rips through individual digits until it figures out the password
<FromGitter> <tenebrousedge> I would probably create an iterator that would yield up the initial-zero hashes
<FromGitter> <tenebrousedge> but @ilanpillemer may be tired of me saying, "create an iterator" by now
<FromGitter> <lbarasti> Would you expect the following to compile? I'd say no ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da6150e39d0c70757b5e29c]
absolutejam has joined #crystal-lang
<FromGitter> <lbarasti> shouldn't the compiler complain that type A doesn't have a #f method?
<FromGitter> <Blacksmoke16> no because b does
<FromGitter> <Blacksmoke16> which is the type that is actually being used
<FromGitter> <lbarasti> yes, but the compiler should care about the declared type, that's the foundation of polymorphism
<FromGitter> <Fryguy> a.class # => B
<FromGitter> <lbarasti> same example in Scala: https://scastie.scala-lang.org/n9D3Wz8oSbCi8nAmNyDAwA
<FromGitter> <Blacksmoke16> its a restriction on the type `a` can be, which in this case `B` is inherently `A` since it includes module `A`
<FromGitter> <Fryguy> typeof(a) # => B
<FromGitter> <lbarasti> I don't think the declared type should not be ignored by the compiler. Let me try something different
<FromGitter> <Fryguy> This one is interesting `a.as(A).f # => 5`
<FromGitter> <Blacksmoke16> you could define `abstract def f` within module `A` to ensure includers implement that method
<FromGitter> <Fryguy> even though `typeof(a.as(A)) # => A` o_O
<FromGitter> <lbarasti> this also compiles, again, I have some doubts ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da6168a57c2517c6a143b2f]
<FromGitter> <Blacksmoke16> try adding another class that includes A but doesnt define the method
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/7t6z
<FromGitter> <kinxer> https://carc.in/#/r/7t71
<FromGitter> <kinxer> That does seem odd.
<FromGitter> <ilanpillemer> there isnt a knowable maximum
<FromGitter> <Blacksmoke16> im not sure i see the problem
<FromGitter> <lbarasti> The type signature of the function really should prevent a user from calling a non-existing method on it, no matter what its runtime is
<FromGitter> <Blacksmoke16> `A` doesnt make any promise there should be a method to call
<FromGitter> <Blacksmoke16> `def f` is within the class not related at all to `A`
<FromGitter> <Blacksmoke16> https://carc.in/#/r/7t79 is what you should do if you want to ensure includers implement that method
<FromGitter> <lbarasti> I don't mean to ensure includers to implement a method, I mean to ensure that users of a function are restricted in the methods they can call on the input parameter
<FromGitter> <Blacksmoke16> wouldnt that just work by default tho?
<FromGitter> <Blacksmoke16> compiler would know x doesnt implement method y and error
<FromGitter> <lbarasti> let me explain my rationale for this. In golang they have the concept of read-only channels, write-only channels and regular channels
<FromGitter> <lbarasti> in a function signature, they will use channel type that makes sense in the context of the function
<FromGitter> <lbarasti> this way, a regular Channel passed by the caller is seen as either a read-only or a write-only one
<FromGitter> <lbarasti> I thought they'd achieve that by having Channel inherit from both the other two, they might be taking a different approach, though
<FromGitter> <lbarasti> anyhow, it would be good to find another compiler that behaves like the crystal one in this scenario, just to check general expectation
<FromGitter> <Blacksmoke16> use overloaded methods one for each channel type?
<FromGitter> <lbarasti> yes, I could make them private in a subclass of Channel, but that looks a bit off to me
<FromGitter> <Blacksmoke16> https://carc.in/#/r/7t7f
<FromGitter> <Blacksmoke16> sorry im still not sure i see the problem, isnt that what you want?
<FromGitter> <Blacksmoke16> allow both types thru but error if the method they want isnt defined?
<FromGitter> <lbarasti> No, I'd like the function signature to dictate what methods can be called on the parameters. I really appreciate you looking into this BTW @Blacksmoke16
<FromGitter> <lbarasti> this is the behaviour I'm looking for: https://scastie.scala-lang.org/n9D3Wz8oSbCi8nAmNyDAwA
<FromGitter> <lbarasti> will do some more thinking on this, thanks!
<FromGitter> <tenebrousedge> @ilanpillemer https://play.crystal-lang.org/#/r/7t7i
<FromGitter> <Blacksmoke16> oh i see
<FromGitter> <Blacksmoke16> @asterite would prob know
<FromGitter> <jwoertink> Anyone else having issues running any `shards` command?
<FromGitter> <jwoertink> weird.. my shards is hosed somehow
<FromGitter> <Blacksmoke16> https://carc.in/#/r/7t7q
<FromGitter> <kinxer> So it looks like it's specific to modules.
<FromGitter> <kinxer> @jwoertink Sorry, my `shards` seems to work fine.
<FromGitter> <jwoertink> yeah, I reinstalled it and it's good now. Not sure what happened there
<FromGitter> <lbarasti> @kinxer abstract classes seemed to behave the same, let me retry
<FromGitter> <Blacksmoke16> you dont want to use abstract class in this case
<FromGitter> <absolutejam_gitlab> Don't bother with abstract classes, they're pointless
<FromGitter> <absolutejam_gitlab> πŸ˜‰
<FromGitter> <lbarasti> regular classes also behave the same: https://play.crystal-lang.org/#/r/7t7w
<FromGitter> <Blacksmoke16> the key is 1) don't use abstract class, 2) cast `B` as `A`
<FromGitter> <Blacksmoke16> `B.new.as(A)`
<FromGitter> <Blacksmoke16> gets you what you want
<FromGitter> <asterite> @lbarasti that's how Crystal works. It's very different from other statically typed languages
<FromGitter> <asterite> and there's no way to restrict the type of a variable to some supertype, the compiler will always analyze all subtypes
<FromGitter> <lbarasti> yes, @Blacksmoke16 that does the trick
<FromGitter> <lbarasti> thanks for the comment @asterite, I will pursue a different way to achieve this
<FromGitter> <bajro17> @ilanpillemer I just sometimes scare that crystal is not stable enough or I worry how to find libraries but I work with crystal long time for myself, also I scare how to suggest to clients crystal and its still not version 1.0. But when I see a lot of big websites in production using crystal also some important people in IT world use it I be more motivated to keep use it
<FromGitter> <lbarasti> @asterite I'm thinking it's OK that the compiler analyses the subtypes, but it could then `ceil` the parameter type to the type in the function signature, that sounds doable, right? It would use the same mechanism, just on a superclass/module
<FromGitter> <ilanpillemer> @tenebrousedge that fails to get the right answer… but I will see if I can get it working
<FromGitter> <ilanpillemer> what’s the point of abstract classes then?
<FromGitter> <absolutejam_gitlab> It's a contract for child classes to full
<FromGitter> <absolutejam_gitlab> fill*
<FromGitter> <lbarasti> alternatively, `a : A = B.new` could be expanded to `a = B.new.as(A)` πŸ’₯
<FromGitter> <Blacksmoke16> id rather just add the .as(A) manually
<FromGitter> <Blacksmoke16> are cases where you dont want that to happen
<FromGitter> <ilanpillemer> @tenebrousedge managed to fix first bug
<FromGitter> <ilanpillemer> but the second I am unsure about.
<FromGitter> <ilanpillemer> is not necessarily the first 8
<FromGitter> <lbarasti> Well, I don't know, it looks like module and class do behave inconsistently: ⏎ module - no compilation error: https://play.crystal-lang.org/#/r/7t9b ⏎ class - compilation error: https://play.crystal-lang.org/#/r/7t9c
<FromGitter> <ilanpillemer> quite fascinating how asterite solved it in terms of the use of the md5 lambda. I didn’t know you could invoke lambdas like this. https://github.com/asterite/adventofcode2016/blob/master/crystal/5/5.2.cr
<FromGitter> <lbarasti> I'm going by the principle of minimum surprise here. I'm OK with either behaviours, let's pick one
<FromGitter> <Blacksmoke16> maybe make a forum thread/issue about it
<FromGitter> <Blacksmoke16> my guess is that thats just how it works but :shrug:
<FromGitter> <lbarasti> πŸ‘
<FromGitter> <tenebrousedge> @ilanpillemer the problem description doesn't seem to add up
<FromGitter> <lbarasti> FYI @Blacksmoke16, I opened an issue here https://github.com/crystal-lang/crystal/issues/8334
<FromGitter> <lbarasti> thanks for your support
alex``` has quit [Remote host closed the connection]
ht__ has quit [Quit: ht__]
<FromGitter> <sam0x17> @lbarasti I think that has to do with how crystal supports unspecified types on method params and in other places, and then bases things off of what methods you call on the object
<FromGitter> <sam0x17> I am also surprised that that compiles, however
<FromGitter> <ilanpillemer> is there a method to give the most common value in an array?
<FromGitter> <ilanpillemer> ie the mode?
<FromGitter> <tenebrousedge> you could do `max_by {|v| arr.count(v) }` but the performance will be terrible
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Enumerable.html#max_by(&block:T-%3EU)forallU-instance-method
<FromGitter> <Blacksmoke16> max_by { |v| v } would prob work no?
<FromGitter> <Blacksmoke16> er no
<FromGitter> <sam0x17> you need a `Hash(String, Int32)`
<FromGitter> <sam0x17> (or whatever array type is for key)
<oprypin> tally is probably relevant https://crystal-lang.org/api/master/Enumerable.html#tally:Hash(T,Int32)-instance-method
<FromGitter> <tenebrousedge> yes
<FromGitter> <Blacksmoke16> `arr.group_by { |val| val }.max`
<FromGitter> <Blacksmoke16> `[1,2,1,1,2,3,].group_by(&.itself).max`
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/7ta6 er not quite
<FromGitter> <Blacksmoke16> `[1,2,1,1,2,3,].group_by(&.itself).max_by { |_k, v| v.size }`
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <ilanpillemer> can you do max by the value of a hash?
<oprypin> do tally, a lot more efficient
<FromGitter> <ilanpillemer> once I have tallied, I need to then max by the value
<oprypin> https://play.crystal-lang.org/#/r/7tab `pp [1,2,1,1,2,3].tally.max_by { |k, v| v }.first`
<FromGitter> <Blacksmoke16> oo tally is defined on enumerable
<FromGitter> <sam0x17> I think this is optimal: ⏎ https://play.crystal-lang.org/#/r/7tag
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da6337389acff6ff500996e]
<FromGitter> <tenebrousedge> why not `reject(&.==('\n'))` ?
<FromGitter> <Blacksmoke16> whats the point of the `.to_a`
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da633f1dbf676673467152c]
<oprypin> sam0x17, the only problem is that u got the entire body of `tally` in there πŸ˜‚
<FromGitter> <sam0x17> lol
<FromGitter> <ilanpillemer> @Blacksmoke16 ``` ⏎ Error: undefined method 'transpose' for Iterator::InGroupsOf(Iterator::Select(IO::CharIterator(IO::FileDescriptor), Char, Bool), Char, Int32, Nil)
<FromGitter> <ilanpillemer> thats what happens without the to_a
<FromGitter> <tenebrousedge> I don't think you need `each`
<FromGitter> <tenebrousedge> `map` should work
<FromGitter> <tenebrousedge> then you can nix the `answer` declaration
<FromGitter> <sam0x17> good to know about tally
<FromGitter> <tenebrousedge> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da63492809de9699f43cf69]
<FromGitter> <ilanpillemer> @tenebrousedge ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da6350b80e62056e40e9972]
<FromGitter> <tenebrousedge> `max_by(&.last)` then
<FromGitter> <ilanpillemer> doesnt give any answer. Mine works on the toy example, but still has a bug in the real test intput
<FromGitter> <tenebrousedge> no answer? hmmm...
<FromGitter> <tenebrousedge> what's a test case?
<FromGitter> <ilanpillemer> Hah! Mine works,, they were sneaky.. need to group by 8 for the actual test
<FromGitter> <ilanpillemer> that test case should return β€œeaster"
<FromGitter> <tenebrousedge> `map` works for me
<FromGitter> <ilanpillemer> it should.. there is probably a typo somwhere I guess.
<FromGitter> <ilanpillemer> anyway.. at least I am getting closer to idiomatic Crystal
<FromGitter> <tenebrousedge> https://play.crystal-lang.org/#/r/7tal
<FromGitter> <ilanpillemer> I dont quite get the max by last?
<FromGitter> <tenebrousedge> the last value in the tuple
<FromGitter> <ilanpillemer> so tally gives a hash
<FromGitter> <ilanpillemer> Max by changes to tuples?
<FromGitter> <tenebrousedge> `max_by` yields up the values of the hash as `{Key, Value}`
<FromGitter> <tenebrousedge> (a tuple)
<FromGitter> <ilanpillemer> just like a to_a?
<FromGitter> <tenebrousedge> yes
<hypercore> should "Postinstall script/precompile_tasks" take a while? (one of the outputs after fetching shards)
<hypercore> i've only ever used dynamic languages before, is this just slow because crystal is compiled?
<oprypin> hypercore, this is entirely specific to the shard
<oprypin> could be a C library being compiled or literally anything
<oprypin> (incl. deleting everything on your disk 😬)
<hypercore> oh ok, well it's the dependencies for the lucky framework
<hypercore> taken about 5 minutes so far
<oprypin> that doesnt sound good
<hypercore> it is running on a tiny vps, not sure if that matters or not
<oprypin> oh yes it does
<oprypin> the poor thing coulve ran out of RAM long ago and struggling on swap
<hypercore> oprypin: ah that could be why then...
<oprypin> crystal needs a ton of ram
<hypercore> does crystal have higher hardware requirements than elixir? i saw some benchmarks where the "RAM used" for crystal was much lower than that for elixir, but elixir runs fine on a $5 VPS
<hypercore> or is that just for the compilation step?
<oprypin> compilation
<hypercore> gotcha
<hypercore> trying with 2GB now
<FromGitter> <ilanpillemer> how you refer to the top namespace?
<FromGitter> <Blacksmoke16> `::Type`
<FromGitter> <ilanpillemer> if I want to refer to a variable in the top namespace?
<FromGitter> <Blacksmoke16> `::var` would prob do it
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da647c4dbf6766734679962]
<FromGitter> <bew> won't work for variables, only for methods, types (and constants)
<FromGitter> <Blacksmoke16> got a playground link?
<FromGitter> <Blacksmoke16> of what you're trying to do
<FromGitter> <bew> variables are not accessible from methods
<FromGitter> <bew> -> no global variables
<FromGitter> <ilanpillemer> https://play.crystal-lang.org/#/r/7taq
<FromGitter> <Blacksmoke16> make `mode` a const
<FromGitter> <bew> huh no he redefines it in the method
<FromGitter> <ilanpillemer> Yes. its a global variable
<FromGitter> <Blacksmoke16> crystal doesnt have global variables
<FromGitter> <Blacksmoke16> better off using a module with a class var
<FromGitter> <ilanpillemer> better off, or no choice other than?
<FromGitter> <Blacksmoke16> better than passing that variable to every method πŸ˜‰
<FromGitter> <ilanpillemer> maybe I can mutate it
<FromGitter> <ilanpillemer> can you assign via mutation?
<FromGitter> <bew> could fake global vars with a module, liek https://play.crystal-lang.org/#/r/7tav
<FromGitter> <ilanpillemer> Thanks!
<FromGitter> <ilanpillemer> so class_property is like property but for @@?
<FromGitter> <bew> yep
<FromGitter> <ilanpillemer> nice
<FromGitter> <bew> @Blacksmoke16 what's your timezone? it looks like you're "always there"^^
<FromGitter> <Blacksmoke16> US east coast
<FromGitter> <bew> oh, so it's the end of the afternoon for you now ~ ?
<FromGitter> <Blacksmoke16> 6:45pm yea
DeBot has quit [Quit: Crystal IRC]
asterite has quit [Quit: Bye]
jhass has quit [Quit: Bye]
<FromGitter> <bew> that explains it, in europe timezone even if I try to stay late you'll always be there :P I really need to sleep now, it'll makes me stop saying uninteresting things
<FromGitter> <Blacksmoke16> :p
absolutejam has quit [Ping timeout: 240 seconds]
<FromGitter> <Blacksmoke16> plus i keep it up at work so it seems like that haha
<FromGitter> <bew> I did that at my last internship, but I think I spent a bit too much time on crystal when I should be working... now I try to reduce my time exposed to my github notifications if I want to work
DeBot has joined #crystal-lang
chemist69 has quit [Ping timeout: 276 seconds]
asterite has joined #crystal-lang
jhass has joined #crystal-lang
dwdv_ has quit [Ping timeout: 240 seconds]
<FromGitter> <Blacksmoke16> @nsuchy https://github.com/Blacksmoke16/crylog/compare/logger-compatability added a class should help with using Crylog with frameworks that don't directly use it
<FromGitter> <Blacksmoke16> need to update docs, prob do a new release tomorrow
return0e has quit [Remote host closed the connection]