ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.23.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
<RX14> actually maybe thats a placebo
<RX14> regardless: spec (sometimes) works https://my.mixtape.moe/rcbmzd.png
<FromGitter> <marksiemers> A couple questions. ⏎ ⏎ 1) Is there a way to run spec for crystal itself (`make spec`) and specify just one file to run specs against? ⏎ 2) It looks like there are a couple failure for `lexer_spec.cr` in master - likely due to a case sensitive mismatch. Is someone working on the lexer, or could I take a shot at fixing that? [https://gitter.im/crystal-lang/crystal?at=5a3eee3affa3e37919733180]
<RX14> @marksiemers `bin/crystal spec spec/<file>_spec.cr`
<RX14> and no there definitely shouldn't be any spec failures in master
<RX14> please send a paste of your results
<RX14> Papierkorb, looks like codegen is broken for windows somehow
<FromGitter> <marksiemers> RX14 - I first saw it in Circle CI: https://circleci.com/gh/crystal-lang/crystal/2154 ⏎ Let me double check that this isn't because I need a rebase. I got failures locally too, but then realized I was about a dozen commits behind.
<RX14> @marksiemers it's fixed
<FromGitter> <marksiemers> Cool, a rebase should do the trick then.
<Papierkorb> RX14: looks like that old llvm3.x insanity
<RX14> it's not
<Papierkorb> Currently installing everything in WSL. The VM box pretty slow though.
<RX14> Papierkorb, it's LLVM 5.0.1
<RX14> as in arch linux latest
<Papierkorb> .. have you tried a different version?
<RX14> Papierkorb, not KVM?
<Papierkorb> it's a KVM host
<RX14> i'm just using KVM on my dev laptop
<RX14> it's pretty damn fast
<Papierkorb> My X201 I have here isn't strong enough for dev'ing, YT and VM at once lul
<RX14> rip
<RX14> what CPU?
<RX14> and does it have a 16gb ram upgrade?
<Papierkorb> Mh I haven't checked, maybe my TV Notebook has more power than that scrap
<Papierkorb> 8GiB RAM, i5 520M
<RX14> lol
<RX14> well my thinkpad 13 handles it pretty well
<Papierkorb> yeah anything more recent than my 2010 machine should do lul
<RX14> it's a bit slow whenever windows wants to do things in the background
<RX14> as it always does
<RX14> without being asked
<RX14> but othertimes it feels native
<RX14> which is fantastic
<Papierkorb> blacklist MS IPs on the host
<Papierkorb> Mh .. my other notebook should have a sandy bridge cpu .. but dunno if it was a quad core
<RX14> well my thinkpad 13 is dual core
<RX14> i5-7200U I think
<RX14> it handles really well for a dual core
<Papierkorb> ..That's a really recent CPU
<Papierkorb> even with the Underpowered bit set
<RX14> yes it is
<RX14> but it's still only a dualcore
<Papierkorb> A proper new fancy notebook is on the 2018 todo list though
<RX14> a dualcore with hyperthreading from 2017 still don't beat a quadcore i5 from 2012
<RX14> intel isn't magic
<Papierkorb> Holy shit "ubuntu on windows", is it so hard to process those triggers for man-db, whatever that is?
<Papierkorb> intel especially was sleeping on their money until ryzen
<RX14> Papierkorb, do you know of conemu?
<Papierkorb> "And next years i7 will be .." "RYZEN" "Next years i9 will be.."
<Papierkorb> No
<RX14> Papierkorb, an acceptable console emulator for windows
<RX14> far far better than the default cmd.exe
<RX14> even after it's makeover
<RX14> just a tip
<Papierkorb> Yeah will have a look, whatever that is that's running by default is tosh
<RX14> well, good luck...
<RX14> i'm off to sleep
<Papierkorb> gn8
<RX14> if you have problems just ping me
<RX14> well, in the morning
happycoder has joined #crystal-lang
<FromGitter> <unazed> hiya
Philpax has joined #crystal-lang
happycoder has quit [Quit: Yaaic - Yet another Android IRC client - http://www.yaaic.org]
happycoder has joined #crystal-lang
radagast__ has joined #crystal-lang
<radagast__> Hi. I found out about crytal a while ago, and I'm about to dive into the language. However I have a few questions... I can't seem to find many discussion regarding Crystal's GC. How does memory management work in Crystal? Does it support RAII? What algorithm does the current GC follow?
<oprypin> radagast__, no RAII, blocks are used instead. gc is https://github.com/ivmai/bdwgc
<oprypin> "no RAII" means that there are no guarantees about destructor being called in a timely fashion, or ever
<radagast__> Thanks. Are there any different strategies of mem management under consideration?
<radagast__> Like ARC
<oprypin> ARC has been basically dismissed, it doesnt work well in a concurrent environment due to need of locks
<radagast__> I see. Thanks :)
<oprypin> radagast__, past discussion if you want to dig deeper https://irclog.whitequark.org/crystal-lang/2017-11-08#20498154;
Philpax_ has joined #crystal-lang
<oprypin> people are not satisfied with the current generic GC implementation but it works and there are higher priority things
<radagast__> Understandable, the project is still new.
Philpax has quit [Ping timeout: 264 seconds]
<radagast__> Some people would be just happy with raw pointers and and unique_ptr<T> or shared_ptr<T>.
<oprypin> well everything is like a shared_ptr with garbage collection
<radagast__> Nice.
<radagast__> Another question, what IDE/Editor is popular among Crystal devs?
<oprypin> vscode apparently
<oprypin> sublime
<oprypin> vim
<oprypin> emacs
<oprypin> in approximate descending order
<oprypin> doesn't need an IDE though
<radagast__> Thanks, one last question. Is Crystal flexible enough to let me do crazy stuff, to the degree similar to Curiously Recurred Template Pattern (C++)?
<radagast__> I like TMP
<oprypin> macros are kept sane. they are likely more powerful than c++ metaprogramming but hard to say
<radagast__> Thank you very much.
<radagast__> We'll talk soon.
radagast__ has quit [Quit: Page closed]
Philpax_ has quit [Ping timeout: 248 seconds]
rohitpaulk has joined #crystal-lang
happycoder has quit [Ping timeout: 252 seconds]
rohitpaulk has quit [Read error: Connection reset by peer]
rohitpaulk has joined #crystal-lang
sz0 has joined #crystal-lang
happycoder has joined #crystal-lang
A124 has joined #crystal-lang
happycoder has quit [Ping timeout: 248 seconds]
_whitelogger has joined #crystal-lang
<Yxhuvud> speaking of editors, I really like the progress we have seen in the emacs crystal-mode lately.
alex`` has joined #crystal-lang
rohitpaulk has quit [Read error: Connection reset by peer]
rohitpaulk has joined #crystal-lang
faustinoaq has joined #crystal-lang
rohitpaulk has quit [Read error: Connection reset by peer]
rohitpaulk has joined #crystal-lang
_whitelogger has joined #crystal-lang
<RX14> As in any progress lol
<Yxhuvud> well, it is checking off a lot of the low hanging fruits when it comes to improvement and integration with the crystal binaries
claudiuinberlin has joined #crystal-lang
sz0 has quit [Quit: Connection closed for inactivity]
A124 has quit [Quit: '']
A124 has joined #crystal-lang
<RX14> well i'm more concerned by the indenting breaking whenever you do anything complex
<FromGitter> <MrSorcus> Can anyone glance? ⏎ My code is so bad or not? ⏎ https://github.com/MrSorcus/smtp ⏎ Thanks. [https://gitter.im/crystal-lang/crystal?at=5a3f8f56b48e8c35665f802f]
hightower2 has joined #crystal-lang
hightower3 has quit [Ping timeout: 256 seconds]
<Yxhuvud> yeah, mostly what bugs me is that methods that end with ? is parsed as ? if.
<FromGitter> <MrSorcus> What do you mean? Where?
<Papierkorb> The shard uses monkey patching, that's an instant reject by me if I needed a smtp shard
<Papierkorb> Libraries have no business to mess with the application environment, that's for the application to decide, not a random shard
<Papierkorb> Stuff like `Array#[](x : String)` is dangerous and can easily add bugs to client applications. Never ever do that.
<FromGitter> <MrSorcus> > **<Papierkorb>** The shard uses monkey patching, that's an instant reject by me if I needed a smtp shard ⏎ You talk about this? https://github.com/MrSorcus/smtp/blob/master/src/smtp.cr#L4-L20
<Papierkorb> Yes.
<FromGitter> <MrSorcus> > **<Papierkorb>** Libraries have no business to mess with the application environment, that's for the application to decide, not a random shard ⏎ ⏎ I don't understand a litle...
<Papierkorb> Lines 24-26, those aliases are confusing. Choose better names.
<Papierkorb> SMTP::Client wanted to live in a file named src/smtp/client.cr, not src/smtp.cr. Use the toplevel NAME.cr to require your shard, and only run code in there if absolutely needed. As your shard doesn't require initialization, you'd be fine without
<Papierkorb> Your class uses `setter`, but has no `getter`. Did you mean to write `getter`?
<FromGitter> <MrSorcus> It's better for me not to write code, right? *SAD*
<FromGitter> <MrSorcus> > **<Papierkorb>** Your class uses `setter`, but has no `getter`. Did you mean to write `getter`? ⏎ ⏎ No. I thought inside the class it was enough to use `setter`
<Papierkorb> MrSorcus, Let me tell you one thing: Failure Is Success. You learn so much faster by running against a wall. If everything is fluffy sunshine, you may feel good, but never actually get anywhere. Take a day or so and revisit your code and critique it on your own. Pretend that you've never seen the code before.
<Papierkorb> MrSorcus, getter/setter is for the user of your class. Inside the class, you can access your @ivars freely without getter/setter macros
<Papierkorb> Oh and I just saw, you should configure your git (`git config --set user.name` and `.. --set user.email`) to match your Github name, or some other name (like your real name). The "initial commit" was written by `root`
<FromGitter> <MrSorcus> > **<Papierkorb>** @MrSorcus, Let me tell you one thing: Failure Is Success. You learn so much faster by running against a wall. If everything is fluffy sunshine, you may feel good, but never actually get anywhere. Take a day or so and revisit your code and critique it on your own. Pretend that you've never seen the code before. ⏎ ⏎ I'm trying, but not always get it right. And i'm not a native english
<FromGitter> ... speaker, learn docs/articles/etc or just talks about code/something else is a little hard for me.
<Papierkorb> Not a native speaker myself, German is my mother tongue. Just keep on reading and writing (and if you can, talking) English, it'll get better quickly. From your message, I can't tell if you're a native english speaker or not at all. Don't undersell yourself.
<FromGitter> <MrSorcus> > **<Papierkorb>** Not a native speaker myself, German is my mother tongue. Just keep on reading and writing (and if you can, talking) English, it'll get better quickly. From your message, I can't tell if you're a native english speaker or not at all. Don't undersell yourself. ⏎ ⏎ Thank you so much.
<FromGitter> <MrSorcus> > **<Papierkorb>** Stuff like `Array#[](x : String)` is dangerous and can easily add bugs to client applications. Never ever do that. ⏎ ⏎ How is right? And how it can affect the client code?
<Papierkorb> MrSorcus, You're basically doing two things: 1) Write code to implement a protocol 2) Revise a code architecture to do that. You got 1) down, don't undervalue the knowledge that's needed for that part! Like, really don't. That's beyond the scope of someone new to programming. What you're having issues with is 2), and that's normal. One can find many articles on doing 1., but 2. .. kinda but most aren't good for those who're new to it. So
<Papierkorb> nothing to be ashamed about. But this gives you an opportunity to catapult your general developer knowledge into the next league: Take your code, as it is, and think about the components. Not the code, the components (Modules, classes, functions - Where to put what).
<Papierkorb> MrSorcus, if you want a term to google for, I'm not getting tired to recommend the SOLID pattern as a starting point. `Ruby solid` should give you plenty good results.
<FromGitter> <alerdenisov> Hello there. I'm looking at crystal and want to make a simple app to create trade orders on cryptocurrency exchange. Could you please suggest HTTP/REST client to me? I found next few: crest, halite, Cossack. But which is better?
<RX14> @alerdenisov I generally recommend starting with the one in the stdlib
<RX14> just require "http" and use HTTP::Client
<FromGitter> <alerdenisov> Thanks you @RX14. I will try
<FromGitter> <MrSorcus> > **<Papierkorb>** @MrSorcus, if you want a term to google for, I'm not getting tired to recommend the SOLID pattern as a starting point. `Ruby solid` should give you plenty good results. ⏎ ⏎ Ok, thanks for your helping.
<FromGitter> <bararchy> If someone is interested, we (NeuraLegion) just released our pure crystal neural network for use: https://github.com/NeuraLegion/shainet ⏎ Enjoy :)
alex`` has quit [Ping timeout: 265 seconds]
<FromGitter> <MrSorcus> > **<Papierkorb>** Stuff like `Array#[](x : String)` is dangerous and can easily add bugs to client applications. Never ever do that. ⏎ ⏎ You mean https://github.com/MrSorcus/smtp/blob/master/src/smtp.cr#L16-L20 ?
<FromGitter> <straight-shoota> @RX14 What's with the bulk milestone changes?
<RX14> @straight-shoota well the milestones got messed up
<RX14> we tagged 0.24.1 but then forgot to rename Next to 0.24.1
<RX14> so the Next molestone eded up as 0.24.1+next
<RX14> which I noticed and decided to fix early
<RX14> @straight-shoota make sense?
faustinoaq has quit [Ping timeout: 248 seconds]
<FromGitter> <straight-shoota> understood 👍
<FromGitter> <straight-shoota> I suspected something like that
<FromGitter> <straight-shoota> It's just Github's very detailed notifications that added some uncertainty about what's going on :D
<FromGitter> <straight-shoota> We might port that solution to Crystal... :P
faustinoaq has joined #crystal-lang
<RX14> Papierkorb, thats hillarious
alex`` has joined #crystal-lang
<greenbigfrog> This got broken/changed in 0.24.1, right? https://github.com/will/crystal-pg/blob/master/src/pg/decoder.cr#L220
thiamsantos has joined #crystal-lang
<FromGitter> <thiamsantos> What are the major problems that would be faced if I choose to use crystal in a production project? My app consists basically of a REST API that uses PostgreSQL as main database and Redis for cache. It will be deployed on heroku or other similar service. Windows support is not a issue.
<RX14> @thiamsantos well mainly you have 2 things: the library ecosystem isn't really there yet
thiamsantos has quit [Ping timeout: 260 seconds]
<RX14> so you might realise halfway through the project you have to actually write your own shard to do what you want
<RX14> or your own code
<RX14> and the other thing is that you'll have to deal with breakages when you upgrade versions of crystal
<RX14> for example upgrading from 0.23.1 to 0.24.1 there are breaking changes which you have to modify your code to get it to compile again
<Papierkorb> Works OOTB with WSL https://i.imgur.com/ai0Sdrf.png
<Papierkorb> Looks a bit off though, but I blame the half X-environment for that
<RX14> wow Papierkorb
<RX14> really?
<RX14> already?
<Papierkorb> Yeah just install XMing as X, launch it, set DISPLAY and it just works
<RX14> hmm
<RX14> Papierkorb, why would you need xming if it's Qt?
<RX14> oh this is WSL
<RX14> nvm
<RX14> i thougght this was windows-native QT
<greenbigfrog> anyone got an answer to my question?
<Papierkorb> My new KVM host is much faster (... heck it even compiled the Qt binding faster), so I could try using the windows crystal port
<Papierkorb> .. in a few mins or tomorrow. dunno
<FromGitter> <MrSorcus> @Papierkorb I apologize, but I didn't hear the answer. ⏎ ⏎ > > **<Papierkorb>** Stuff like `Array#[](x : String)` is dangerous and can easily add bugs to client applications. Never ever do that. ⏎ You mean https://github.com/MrSorcus/smtp/blob/master/src/smtp.cr#L16-L20 ? [https://gitter.im/crystal-lang/crystal?at=5a3fbeba03838b2f2a3134d4]
<Papierkorb> yes
<FromGitter> <MrSorcus> > **<Papierkorb>** yes ⏎ ⏎ Thanks.
<Papierkorb> MrSorcus, so lets say I use an array "ary" in my program. not unusual. Now, I have a method which I didn't restrict in result type (or loosely so). That method returns an Int32, and I feed the methods result directly into `ary[x]`. I change the method (or a method which is called by that method), so that instead of only int32, it suddenly can also return a string. This may make sense for whatever I did there. The problem now is that
<Papierkorb> suddenly, that `ary[x]` call won't complain like I'd expect it to (`There's no Array#[](String)`), but will silently pass.
<Papierkorb> Through other loose typing, or (bad) luck in my code, the result of your array#[] there may now change behaviour unexpectedly in other parts of my program. This can lead to bugs of crazy nature (and hard to trace, as I don't expect anyone to patch array like that), or even introduce security issues down the road.
<Papierkorb> Especially for your usage, array["foo"] isn't at all obvious that it's an alias for #includes?. #includes? is quite obvious, even if I'm new to crystal and never used that method myself (and never heard of it either), it's pretty obvious what it does
<FromGitter> <MrSorcus> @Papierkorb This is a great explanation, thanks you again.
rohitpaulk has quit [Ping timeout: 252 seconds]
<crystal-gh> [crystal] RX14 opened pull request #5447: Add Crystal::System::Dir (master...feature/system-dir) https://git.io/vbQNi
<crystal-gh> [crystal] RX14 opened pull request #5448: Remove c/winapi and rename some windows types (master...feature/remove-winapi) https://git.io/vbQNX
<FromGitter> <straight-shoota> @RX14 in the body text of #5448 you confused winapi woth winbase again ;)
<RX14> damnit
<RX14> @straight-shoota fixed
DTZUZO has joined #crystal-lang
<crystal-gh> [crystal] marksiemers opened pull request #5450: Add 'Hash#each_key_for' methods (master...feature/hash-each_key_for) https://git.io/vb7vI
<Papierkorb> RX14: What's the most recent, windows native Crystal branch?
<Papierkorb> With unmerged goodies
<RX14> windows-spec on my fork
<RX14> probably
<Papierkorb> Ah so I build your compiler on linux, then cross compile on lin, and link on windows?
<RX14> Papierkorb, dont even need to make crystal
<RX14> 0.24.1 compiler'll do fine
<RX14> Papierkorb, bin/crystal build --cross-compile --target x86_64-pc-windows-msvc
<RX14> and it'll spit out your linker command
<RX14> needs gc.lib and pcre.lib built though
<Papierkorb> My 0.24.1 from the arch repo can't build it, in /usr/lib/crystal/callstack.cr:1: while requiring "c/dlfcn": can't find file 'c/dlfcn' relative to '/usr/lib/crystal'
<Papierkorb> > crystal build --cross-compile --target x86_64-pc-windows-msvc samples/image_viewer.cr
<RX14> Papierkorb, bin/crystal
<RX14> also the samples are unlikely to build
<Papierkorb> that's one of Qts samples
<Papierkorb> qt5.cr's
<RX14> oh nvm
<RX14> yes its because you need to use bin/crystal
<RX14> look: /usr/lib/crystal/callstack.cr
<Papierkorb> MSVC2015?
<RX14> i'm suing 2017 Papierkorb
<RX14> you can try 2015
<RX14> it'll probably work
<Papierkorb> I'm positive that something will completely break
<Papierkorb> Especially because of Qt being C++, and me doing C++ things
Poeticode is now known as Poeticide
<RX14> Papierkorb, well things are already broken
<RX14> so that not hard
<FromGitter> <marksiemers> I'm working on a blog post about why Ruby-ists should consider learning Crystal. ⏎ I want to highlight method overloading - does anyone have a good broadly understood, higher-level, real-world example of method overloading being helpful?
<FromGitter> <marksiemers> I have this: http://exercism.io/submissions/8f3ab9ed90bc4d7691e799e9ee8c04a0 ⏎ But I think it is too contrived of an example - I don't think anyone uses an Atbash Cipher at their day job.
DTZUZU has quit [Quit: WeeChat 1.9]
<RX14> @marksiemers showcase it by defining methods which act on different types
<RX14> then pass a union to the call
<RX14> and watch the compiler always execute the right method
<RX14> so you avoid a case;when Type
<FromGitter> <marksiemers> Maybe a leap year example: https://carc.in/#/r/3afh
<Papierkorb> marksiemers, a pattern you sometimes see is a method taking arguments, and a method overloading that method accepting other types of arguments, "turning" those into the type of the other method, and then calling out to the original method
<Papierkorb> That's like a facade-in-a-box
<RX14> I do recommend showcasing the dynamic dispatch though
<FromGitter> <marksiemers> @RX14, Union's assume knowledge of a language other than Ruby. Though the example may be good, it may be lost on some of the audience.
<RX14> well yeah
<RX14> i guess you want to keep the showcases seperate
<RX14> as in not have unions leak into the method overloading example
<FromGitter> <marksiemers> Yeah, the showcases would be for a different audience, or more in depth.
<Papierkorb> If you want to go real fancy, build a "state machine" out of an enum and user input out of a case-tuple statement
<FromGitter> <marksiemers> That's too fancy for this purpose. What I want to go for is a time in Ruby where someone would write something hacky or not very elegant to deal with the dynamic typing, and how much smoother and safer it is in crystal with overloading. ⏎ And something that a Rubyist can understand in about 30 seconds.
<FromGitter> <marksiemers> Method overloading isn't the entire post - it will be 1 of 3-5 reasons to use crystal.
<FromGitter> <marksiemers> You think the leap year thing is too academic and simple?
<Papierkorb> leap year? typing? mh?
<oprypin> yeah that was ny reaction -- seems like there is no relation
<FromGitter> <faultyserver> The visitor pattern is a good example of overloads
<FromGitter> <faultyserver> maybe a bit too in-the-details, but if you compare something like arel in Ruby that has all this magic to dynamically create different methods names to emulate typing to just adding a type restriction to the parameter in Crystal, it's pretty great
<oprypin> faultyserver, hard to make this example compact, but still better than anything i could come up with
<FromGitter> <faultyserver> yeah, that's the main problem.
<FromGitter> <faultyserver> side question: any idea when 0.24.1 will be on brew?
<oprypin> isnt it dependent on brew itself? it's ready
<FromGitter> <faultyserver> probably
<FromGitter> <faultyserver> I'm in a weird predicament until then, though. I don't want to upgrade my project until 0.24.1 is universally available, but travis is already using 0.24.1 and fails to compile, needing a few changes that don't work on 0.23.1
<oprypin> u can also just install from master, i heard brew supports that, should be almost the same effect
<FromGitter> <faultyserver> can you just specify directly from a repo?
<oprypin> also like maybe just keep a local folder with crystal that you control?
<oprypin> it's very easy and u just add an alias cr='/full/path/to/crystal/bin/crystal'
<FromGitter> <faultyserver> I mean, I can easily install it locally, but it would be a little messy, I'd have to clean it up once the brew update is available, and I don't want other people contributing to my project to have to go through that as well
<FromGitter> <faultyserver> Easiest thing for me would be telling travis to run 0.23.1 for a week or so until brew pulls in the new release
<FromGitter> <marksiemers> The leap year thing is a little contrived, but you make it work for different types: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5a401b5effa3e379197784aa]
<FromGitter> <faultyserver> but I can't see a way to do that
<FromGitter> <faultyserver> there's only `latest` and `nightly`
<oprypin> marksiemers, this is an example of a code smell
<oprypin> probably dont use that one
<oprypin> implicitly eating up any type is not good practice
<FromGitter> <marksiemers> In general, throw out that idea, or explicitly type `def leap?(year : Int)`?
<oprypin> in general
<oprypin> duck typing is fine but the implicit conversions are not in trend
<FromGitter> <marksiemers> Ah, the `to_i` and `year` ?
<oprypin> yeah
<oprypin> auto conversion from string is the worst
ashirase has quit [Ping timeout: 240 seconds]
<Papierkorb> you can have a #leap? with versions for Time and Int
ashirase has joined #crystal-lang
<RX14> why not just have Time#leap? then?
<RX14> Time.leap_year? and Time#leap_year? sound like how i'd do it
<FromGitter> <marksiemers> It is how crystal has it.
<FromGitter> <marksiemers> So the example fails on real world useful-ness
<FromGitter> <marksiemers> It highlights some advantages over Ruby's duck-typing though. Ruby raises a runtime exception for `Date` and returns the wrong answer for `String` with the method below: ⏎ ⏎ ```def leap?(year) ⏎ year % 400 == 0 || (year % 100 != 0 && year % 4 == 0) ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5a402186a2a87ea02169e494]
<FromGitter> <marksiemers> In ruby `"2016" % 400 #=> "2016"` - I hadn't tested that before, `%` is a shorthand for using `sprintf`
<Papierkorb> On that, you can use Int#divisible_by? instead of `x % y == 0`
vivus has joined #crystal-lang
<FromGitter> <marksiemers> In Crystal, yeah. I don't think Ruby has Integer#divisible_by?
claudiuinberlin has quit [Quit: Textual IRC Client: www.textualapp.com]