ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.34.0 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <simonhf> If I have h["two"].as(Hash)["foo"] then I can have x strings instead of "two" and y strings instead of "foo" ... whereas with the record mechanism "one" and "two" are not strings and hard-coded as structure members.
<FromGitter> <simonhf> How can the structure help me to have x and y strings and access via strings
<FromGitter> <simonhf> ?
deavmi has quit [Ping timeout: 260 seconds]
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <Blacksmoke16> if you need dynamic key access then yea would have to use a hash (or some macro stuff)
deavmi has joined #crystal-lang
<FromGitter> <simonhf> right... that's what I thought... and so, the question is: How can could I shorten the hash syntax from 'h["two"].as(Hash)["foo"]' and get rid of the '.as(Hash)' part to make things more compact like Perl: '$h{two}{foo}' ?
<FromGitter> <Blacksmoke16> got some sample code of what actually is the value in these cases?
<FromGitter> <simonhf> crystal eval --time --progress --error-trace 'h=Hash{"one" => 1, "two" => Hash{"foo" => 3}}; printf %[debug: >#{h}< >%s< >%s< >%s<\n], h["one"], h["two"], h["two"].as(Hash)["foo"];'
<FromGitter> <Blacksmoke16> if you have like `{"two" => {"foo" => "bar"}, "one" => 1}` then you need the `.as(Hash)`
<FromGitter> <Blacksmoke16> hence why hashes are a pain to work with
<FromGitter> <Blacksmoke16> because the compiler doesnt know that the value of `"two"` is a hash, as i could be a hash or int32, so you need to tell it what it should be
<FromGitter> <Blacksmoke16> are other ways to handle it as well, but thats the most direct
allisio has joined #crystal-lang
<allisio> So I know capturing keyup events in the terminal is "impossible", but is this an okay way to do it? https://carc.in/#/r/95id
renich_ has joined #crystal-lang
<allisio> It's working really well for me on my machine, but something feels a little un-robust about it. That might just be that Crystal made it surprisingly straightforward.
renich_ has quit [Remote host closed the connection]
renich has quit [Ping timeout: 246 seconds]
<FromGitter> <simonhf> @Blacksmoke16 this works: crystal eval --time --progress --error-trace 'h=Hash{"two" => Hash{"foo" => 3}}; printf %[debug: >#{h}< >%s< >%s<\n], h["two"], h["two"]["foo"];'
<FromGitter> <Blacksmoke16> right, because in this case the type of the hash is `Hash(String, Hash(String, Int32))` not `Hash(String, Hash(String, Int23) | Int32)`
<FromGitter> <simonhf> I just need to ensure that the first level key always points consistently to a hash and then bingo...
<FromGitter> <Blacksmoke16> right
<FromGitter> <simonhf> I think this isn't explained well in the crystal docs but makes sense now... will be confusing to people coming from the Perl world and maybe other languages too...
<FromGitter> <Blacksmoke16> if you're coming from a dynamic language then yea.
<FromGitter> <Blacksmoke16> prob would have this issue in any static lang
<FromGitter> <simonhf> yep
HumanG33k has quit [Quit: Leaving]
travis-ci has joined #crystal-lang
<travis-ci> crystal-lang/crystal#499d08d (master - Simplify Link annotation handling (#8972)): The build passed. https://travis-ci.org/crystal-lang/crystal/builds/691539349
travis-ci has left #crystal-lang [#crystal-lang]
<DeBot> https://github.com/crystal-lang/crystal/pull/8972 (Simplify Link annotation handling)
sz0 has quit [Quit: Connection closed for inactivity]
<FromGitter> <j8r> Does this keys are totally dynamic (set by the user)?
<FromGitter> <j8r> If not, a case/when is also an option
<FromGitter> <simonhf> @Blacksmoke16 new example: crystal eval --time --progress --error-trace 'record A, foo : Int32; h=Hash{"two" => A.new(foo: 3), "three" => A.new(foo: 4)}; printf %[debug: >#{h}< >%s< >%s<\n], h["two"], h["two"].foo; p! h;'
<FromGitter> <simonhf> is there a way to do something the same without explicitly defining record A ?
<FromGitter> <simonhf> a sort of anonymous record?
<FromGitter> <Blacksmoke16> no
<FromGitter> <Blacksmoke16> there are named tuples, but those arent exactly the same
<FromGitter> <j8r> That's hard to say what would fit the best for your use-case without knowing it
<FromGitter> <j8r> What's the issue with record?
<FromGitter> <simonhf> just trying to figure out how to make the one liner shorter :-)
<FromGitter> <Blacksmoke16> does it matter?
<FromGitter> <simonhf> maybe because shorter one liners are easier to type and comprehend?
<FromGitter> <simonhf> but maybe it doesn't matter so much :-)
<FromGitter> <Blacksmoke16> given you example up there, id say thats not either of those compared to ⏎ ⏎ ```record A, foo : Int32``` [https://gitter.im/crystal-lang/crystal?at=5ecdb78ff0b8a2053ab66782]
<FromGitter> <j8r> Not always, can be cryptic.
<FromGitter> <j8r> Also they are not always the most efficient way to do things
<FromGitter> <simonhf> hehe yes... I come from Perl world and cryptic is the #1 critique :-)
<FromGitter> <simonhf> yep, one liners are always trickier to comprehend than multi liners... I agree...
<FromGitter> <simonhf> this seems very similar to the record A example but without the record A definition: crystal eval --time --progress --error-trace 'h=Hash{"two" => {foo: 3}, "three" => {foo: 4, bar: 5}}; printf %[debug: >#{h}< >%s< >%s<\n], h["two"], h["two"][:foo]; p! h;'
<FromGitter> <Blacksmoke16> throw in another non hash key and see what happens
<FromGitter> <simonhf> you mean in addition to "two" and "three"
<FromGitter> <Blacksmoke16> yes
<FromGitter> <Blacksmoke16> `"one" => 1,`
<FromGitter> <Blacksmoke16> and will be same issue
<FromGitter> <simonhf> yeah, the 1 will presumably cause the same issue as before needed something like the .as(Hash) because the value is no longer consistently a named tuple?
<FromGitter> <Blacksmoke16> yes
<FromGitter> <simonhf> here we go: crystal eval --time --progress --error-trace 'h=Hash{"two" => {foo: 3}, "three" => {foo: 4, bar: "baz"}, "four" => 1}; printf %[debug: >#{h}< >%s< >%s<\n], h["two"], h["two"].as(NamedTuple)[:foo]; p! h;'
<FromGitter> <Blacksmoke16> and? not much better than it was before
<FromGitter> <simonhf> this is my fav because it's the shortest: crystal eval --time --progress --error-trace 'h=Hash{"two" => {foo: 3}, "three" => {foo: 4, bar: "baz"}}; printf %[debug: >#{h}< >%s< >%s<\n], h["two"], h["two"][:foo]; p! h;'
<FromGitter> <Blacksmoke16> right yea, but its not equivalent to the other examples
<FromGitter> <simonhf> and I don't have to declare a record or the hash K V types... as long as I am consistent with the use of values...
<FromGitter> <Blacksmoke16> could just do `{two: {foo:3}, three: {foo: 4, bar: "baz"}}`
<FromGitter> <Blacksmoke16> and make it all a named tuple
<FromGitter> <simonhf> that's right... but I'm interested in having the first level in the hierarchy as a hash...
<FromGitter> <Blacksmoke16> why?
<FromGitter> <Blacksmoke16> assuming more values i assume?
<FromGitter> <simonhf> it's one of the patterns I use in Perl to munge data... but Perl doesn't have either records or named tuples... so I just make all levels a hash key :-)
<FromGitter> <Blacksmoke16> 😐
<FromGitter> <simonhf> let's say if I was reading some kind of bigger log file contain info on x things with can be stored as the hash key... then I might use in Perl $h{$thing}{$info1} and $h{$thing}{$info2} etc
<FromGitter> <Blacksmoke16> does info1 and info2 have the same structure?
<FromGitter> <simonhf> so in Perl I'm just abusing the hash table has a kind of struct or named tuple for simplicity... but I like the crystal record and named tuple way better...
<FromGitter> <Blacksmoke16> mhm, you get more type saftey
<FromGitter> <simonhf> right...
<FromGitter> <Blacksmoke16> and its more extendable as you can add methods and such to it
<FromGitter> <simonhf> right...
<FromGitter> <simonhf> BTW do you know if anybody has ever created a kind of crystal cheat sheet for Perl programmers?
<FromGitter> <Blacksmoke16> i doubt it
<FromGitter> <simonhf> yeah, I had a quick look but nothing came up
<FromGitter> <simonhf> I've been stuck with Perl for donkeys years and so far no other languages had the feature set I'm after to switch... but crystal does nearly everything I want :-P
<FromGitter> <Blacksmoke16> nice one
<FromGitter> <Blacksmoke16> glad to hear
<FromGitter> <simonhf> there's only one thing it doesn't seem to do so far...
<FromGitter> <Blacksmoke16> oh?
<FromGitter> <simonhf> and I can live without that...
<FromGitter> <simonhf> in perl you can write if statements backwards, e.g. printf qq[hello] if ($x == 10);
<FromGitter> <Blacksmoke16> `puts if x == 10`
<FromGitter> <simonhf> haha... so it is possible... yay! :-)
<wmoxam> I see Perl + Crystal being complimentary rather than interchangable
<wmoxam> Perl is great for a lot of things that Crystal is not (goes for other scripting langs too)
rocx has quit [Ping timeout: 260 seconds]
zorp_ has joined #crystal-lang
zorp_ has quit [Ping timeout: 272 seconds]
<FromGitter> <watzon> Idk I'd go Ruby over Perl for scripting
<FromGitter> <naqvis> nah, Lua rocks lol
woodruffw has quit [Ping timeout: 258 seconds]
woodruffw has joined #crystal-lang
woodruffw has quit [Ping timeout: 256 seconds]
<FromGitter> <watzon> If only Lua arrays didn't start at 1
<FromGitter> <watzon> I'd be on board
<FromGitter> <naqvis> πŸ˜†
woodruffw has joined #crystal-lang
gangstacat has quit [Quit: Ĝis!]
gangstacat has joined #crystal-lang
<raz> watzon: +1 in every way
<raz> lua could have been near perfect. the syntax is lovely and "everything is a table" fun to work with
<raz> plus the blazin' speed
<raz> but they totally broke it with some idiotic decisions like array start at 1....
<raz> (lua makes me a bit bitter because it already broke the opportunities of many other projects. nginx could've been a huge app platform but will never be - cause lua. etc.
<raz> s/already/also/
JuanMiguel has joined #crystal-lang
JuanMiguel has quit [Quit: This computer has gone to sleep]
tdc has joined #crystal-lang
JuanMiguel has joined #crystal-lang
allisio has quit [Quit: WeeChat 2.8]
JuanMiguel has quit [Quit: This computer has gone to sleep]
sz0 has joined #crystal-lang
JuanMiguel has joined #crystal-lang
JuanMiguel has quit [Quit: Saliendo]
<hightower4> simonhf I was planning to do a ruby/python/perl (and easily crystal) side-by-side cheatsheet, but never gotten around to doing it. Do you have an example of one for some other language?
Liothen_ has joined #crystal-lang
olbat[m] has quit [*.net *.split]
Andriamanitra has quit [*.net *.split]
Liothen has quit [*.net *.split]
Liothen_ is now known as Liothen
Andriamanitra has joined #crystal-lang
olbat[m] has joined #crystal-lang
<raz> hmm, i'm observing a beautiful bell curve in my crystal code complexity. crystal is very sketch-friendly, almost everything starts simple. then the more intricate parts tend to explode into a crazy macro hell.
<raz> but then, more often than not, i discover a way to simplify it back down to a very tidy one-screener.
<raz> (in guess to a degree it goes that way in all languages, but i find that effect especially pronounced in crystal)
deavmi has quit [Read error: No route to host]
deavmi has joined #crystal-lang
<jhass> I found to be able shave off a lot of the height of that curve by constantly forbidding myself to use macros
<jhass> I do the same for metaprogramming/reflection in Ruby
<jhass> often by being repetetive and not DRY first on purpose to look at the true patterns rather than the ones I tend to envision upfront and then looking for classical OOP based refactoring to DRY that pile of code up first (in any OOP language)
<raz> yep agree. trying to avoid them where at all possible is def a good idea. my comment above was actually mostly about the situations where it isn't possible. :)
<jhass> and only then looking at macros or reflection, considering whether I want to pay that complexity to make it look nicer
csaba has joined #crystal-lang
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
gangstacat has quit [Quit: Ĝis!]
gangstacat has joined #crystal-lang
rocx has joined #crystal-lang
zorp_ has joined #crystal-lang
<oprypin_> jhass: good stuff
<oprypin_> that principle is applicable very generally
<oprypin_> beginners, having learned about functions
<oprypin_> , tend to try to apply them everywhere and expect functions to somehow solve any problem they have
<jhass> yeah
<jhass> I often copy paste code
<jhass> I just never commit the copy pasted code
<jhass> by the time I commit, either the copy pasted code changed enough to not be repeating anymore, or got extracted into something generalized
<jhass> but I just don't pretend to be all seeing upfront about which one of the two it will be
<yxhuvud> oprypin_: on the other hand, I've seen plenty of old farts that really should know better start writing a small python script and then expand it and expand it and never introduce the proper abstractions that would have made it simple to manage.
<jhass> somehow I see that happening dominantly in python though
<jhass> I wonder why that is, so far I attributed to a lot of not primarily programmers, so scientists for example
<yxhuvud> no, these were old C and Java farts.
<yxhuvud> mostly C.
<jhass> mmh. C makes sense, you need to look really hard there to find proper abstractions
<jhass> and then you end up with stuff like gobject/glib, emulating OOP
<yxhuvud> which is perfectly fine, it is not as if OOP came from nothing. There is an argument that not everything map cleanly to OOP APIs, but a heckofalot does.
<jhass> yeah, it's just either a quite invasive dependency or a lot of work to implement your own, so I can see it not being the first thing in people's mindset
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
rocx has quit [Remote host closed the connection]
rocx has joined #crystal-lang
<yxhuvud> I just wish people got introduced to it from the refactoring path rather than from the top down architecture of shape or animal objects.
<FromGitter> <damianham> Dear crystal core team - is there any chance that the problems compiling on arm architecture (e.g. https://github.com/crystal-lang/crystal/issues/9297) will be addressed and arm/raspbian will become a supported plaform with a binary distribution ? I have a project targetted for Raspberry Pi and I am hoping I won't have to re-engineer to Rust in order to release to market.
<FromGitter> <igor-alexandrov> Hello everyone. Working on FastImage lib (https://github.com/sdsykes/fastimage) implementation on Crystal: https://github.com/jetrockets/fastimage.cr. Already implemented dimensions for BMP, PNG and GIF. Hope to finish by the end of the week.
<FromGitter> <xmonader> silly question ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ this works when i do `crystal run ishi_example.cr` [https://gitter.im/crystal-lang/crystal?at=5ece70472c49c45f5aa60f57]
<FromGitter> <xmonader> but when i do `shards build` and try to run it it prints on stdout, ignoring the io memory thing and gives ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ece706ea91f120a6cc73bc1]
<FromGitter> <xmonader> can some explain?
<FromGitter> <Blacksmoke16> whats the target?
<FromGitter> <Blacksmoke16> `shards build` builds off the `targets` hash in `shard.yml`
<FromGitter> <xmonader> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ece70a089941d051a27201a]
<jhass> damianham: I'm sorry but this is probably not the best place to address this, it might be better brought up on the forum
<jhass> that said Manas is a consulting company, so if you got budget left, you know what to do ;)
<yxhuvud> It might even be quicker to actually do figure out a fix by yourself. While there exists people that get paid for writing on Crystal, most that do don't.
<FromGitter> <xmonader> @Blacksmoke16 any hint?
<FromGitter> <Blacksmoke16> not off the top of my head
<FromGitter> <igor-alexandrov> @xmonader what is `ishi/png`?
<FromGitter> <xmonader> @igor-alexandrov this one https://github.com/toddsundsted/ishi/blob/master/src/ishi/png.cr
<livcd> xmonader: are you betraying us?!
<FromGitter> <xmonader> @livcd what are you doing here xD
<livcd> I am watching you.
<FromGitter> <xmonader> lol. I'm working on crystal full time now, my company adopted it instead of Nim :(
<livcd> damn! dont want to offtopic here but do you want to talk about it @ #nim-offtopic? :D
<FromGitter> <xmonader> ah sure! here's the back story See https://twitter.com/xmonader/status/1252153536621789184
<yxhuvud> where have you found a company that uses crystal? :)
<FromGitter> <xmonader> oh we started using it for a set of things, but mainly rust, go, python shop
<raz> brrrr python *and* go
<FromGitter> <naqvis> @xmonader why are you using `StumpyPNG` ?
<FromGitter> <simonhf> newbie question: what is the crystal equiv of this in Perl: ($a, $b) = $var =~ m~(.*)(foo.*)~ ?
<FromGitter> <simonhf> how can I auto assign variables to $1 and $2 ?
<FromGitter> <Blacksmoke16> whats the english version of that Perl? :P
<FromGitter> <igor-alexandrov> I had exactly the same question :)
<FromGitter> <Blacksmoke16> you can do like `a, b = c.split(' ')` where its essentially sugar syntax to like
<FromGitter> <Blacksmoke16> ```_tmp = c.split(' ') ⏎ a = _tmp[0] ⏎ b = _tmp[1]``` [https://gitter.im/crystal-lang/crystal?at=5ece8b47549761730b5f5318]
<FromGitter> <Blacksmoke16> should work with any array/tuple response iirc
<FromGitter> <Blacksmoke16> dont think there is a way to ignore extra values tho
<FromGitter> <simonhf> for example this works in crystal: crystal eval --time --progress --error-trace 'x= "abcdefg"; x =~ /(.*)(c.e).*/; a,b=$1,$2; printf %[%s %s\n], a, b;'
<FromGitter> <simonhf> but I'd like to optimize / shorten the a,b=$1,$2; part :-)
<FromGitter> <Blacksmoke16> whats the use case here?
<FromGitter> <Blacksmoke16> might be some other method versus just regexing it
<FromGitter> <Blacksmoke16> also, shouldn't it output `ab cde`?
<FromGitter> <simonhf> yes, it outputs that
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ece8c1ab101510b201e919e]
<FromGitter> <Blacksmoke16> not on mac at least
<FromGitter> <simonhf> this works but gives 3 items back instead of 2: crystal eval --time 'x= "abcdefg"; x =~ /(.*)(c.e).*/; a,b,c = $~; printf %[%s %s %s\n], a, b, c;'
<FromGitter> <Blacksmoke16> `crystal eval --time 'x= "abcdefg"; x =~ /(.)(c.e)./; _,b,c = $~; printf %[%s %s\n], b, c;'` fixed :p
<FromGitter> <simonhf> interesting... a star went missing when I copy and pasted the line above: crystal eval --time --progress --error-trace 'x= "abcdefg"; x =~ /(.*)(c.e).*/; a,b=$1,$2; printf %[%s %s\n], a, b;'
<FromGitter> <simonhf> and again... gitter is re-writing the line...
<FromGitter> <simonhf> ```code paste, see link```
<FromGitter> <simonhf> here we go
<FromGitter> <simonhf> sorry about that... I will post here with markdown in future
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <Blacksmoke16> either way, could probably help more if you share what you're trying to actually do
<FromGitter> <Blacksmoke16> assuming there is more to it than this example
<FromGitter> <simonhf> I'm trying to get a shorter one-liner matching to the programming patterns I use when writing one-liners in Perl :-)
<FromGitter> <Blacksmoke16> imo id prob look into the Crystal way of doing this versus trying to make everything 1 line like its Perl
<FromGitter> <simonhf> In Perl you can do something like this which is shorter but the syntax does not work with crystal: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ece8d9c9da05a060a34bbca]
<FromGitter> <simonhf> normally there is more than one way to skin a cat, or ?:-)
<jhass> trying to port idioms of one language to learn another is a bad way of doing so honestly
<FromGitter> <Blacksmoke16> `crystal eval --time --progress --error-trace 'x= "abcdefg"; a,b = /(.*)(c.e).*/.match(x).not_nil!.captures; printf %[%s %s\n], a, b;'`
<FromGitter> <simonhf> e.g. I found out in crystal that you can do `all, a, b = $~;` however it unexpectedly assigns the whole string to variable all even though I didn't ask the regex to do that...
<FromGitter> <xmonader> > @xmonader why are you using `StumpyPNG` ? ⏎ ⏎ I've a chart I want to save as PNG, and stumpyPNG was recommended in this channel
<FromGitter> <Blacksmoke16> `crystal eval --time --progress --error-trace 'x= "abcdefg"; x =~ /(.*)(c.e).*/; a,b = $~.captures; printf %[%s %s\n], a, b;'`
<FromGitter> <naqvis> @xmonader but isn't that library already doing that for you?
<jhass> >> _, a, b = "abcdef".match(/(.*)(c.e)/).not_nil!; {a, b}
<DeBot> jhass: # => {"ab", "cde"} - https://carc.in/#/r/95mw
<jhass> idk, Crystal is not a one liner language
<FromGitter> <naqvis> @xmonader ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ece8ef32c49c45f5aa68239]
<jhass> doesn't try to be even
<FromGitter> <naqvis> this is all you need @xmonader
<FromGitter> <simonhf> @Blacksmoke16 nice! thanks!
<FromGitter> <xmonader> oh let me try that! thanks
<FromGitter> <simonhf> @Blacksmoke16 in Perl, one can do something like `(undef, $a, $b)=@a;` if you don't care about assigning the array element zero to a variable... is there an equiv in crystal? might be shorter than writing `.captures` :-)
<FromGitter> <xmonader> @naqvis that worked! but i still have no explanation why the prev snippet worked with crystal run and not with shards build xD
<jhass> simonhf: didn't I just show that?
<FromGitter> <Blacksmoke16> George Dietrich @Blacksmoke16 12:00 ⏎ `crystal eval --time --progress --error-trace 'x= "abcdefg"; x =~ /(.*)(c.e).*/; _, a,b = $~; printf %[%s %s\n], a, b;'`
<FromGitter> <simonhf> oh, yes, sorry you did! thanks!
<FromGitter> <Blacksmoke16> yes, the `_` like jhass did
<FromGitter> <Blacksmoke16> mainly was just trying to show that `$~` is that type, so you can use those methods
<FromGitter> <naqvis> That shouldn't have worked eitherway, as you were passing the PNG encoded data to `StumpyPNG`
<FromGitter> <naqvis> also `StumpPNG` requires data to be written via its own Canvas, so don't believe passing any arbitrary IO to `Stumpy` will make that as png
<FromGitter> <simonhf> > *<jhass>* idk, Crystal is not a one liner language ⏎ ⏎ Seems like a one-liner language to me :-) I've been using Perl for years for one liners and always wanted to switch away... now crystal looks like a viable candidate!!! which language do you think is a good one-liner langugae?
<FromGitter> <Blacksmoke16> any language can be one liners, just depends on how long the lines are πŸ˜‰
<FromGitter> <Blacksmoke16> longer the line the lower and lower readability gets
<FromGitter> <simonhf> hehe yes!
<jhass> well, I'm a rubyist by heart and ruby is certainly capable of doing that
<jhass> but I only use onliners for throw away code and even there I tend to prefer a REPL
<FromGitter> <simonhf> @Blacksmoke16 that's why in perl I have totally different patterns for one liners and for actual scripts... preferring one liners to be as short as possible in order to rattle them off on-the-fly and comprehend them faster, later...
<jhass> thinking about it I write a lot of oneliners in shell I guess...
<FromGitter> <simonhf> > *<jhass>* well, I'm a rubyist by heart and ruby is certainly capable of doing that ⏎ ⏎ so what can ruby one liners do that crystal one liners cannot?
<jhass> for once they execute faster because you don't pay the compile time
<jhass> Ruby has a stronger Perl heritage, so you got more of that cryptic $vars
<FromGitter> <simonhf> yeah... same with Perl... but I'm assuming / hoping that the crystal roadmap item 'incremental build' will help with that in the future?
<jhass> but the major point is probably Crystal's forced nil handling
<FromGitter> <simonhf> what is 'forced nil handling' ?
<jhass> which is completly going against the usecases of oneliners, where you don't care if it blows up on you
<jhass> like in my example above, it had to do .not_nil!
<FromGitter> <j8r> where this one liners are used, in a shell?
<jhass> in proper code that would be an if check of course
<FromGitter> <simonhf> you mean like in Perl when a variable is undefined but used?
<FromGitter> <xmonader> > also `StumpPNG` requires data to be written via its own Canvas, so don't believe passing any arbitrary IO to `Stumpy` will make that as png ⏎ ⏎ yeah but that's after changing the IO using the ishi png object, it will have the png content that cant be saved into that canvas
<jhass> >> _, a, b = "foo".match(/bar/)
<DeBot> jhass: Error: undefined method '[]' for Nil (compile-time type is (Regex::MatchData | Nil)) - https://carc.in/#/r/95mz
<jhass> this is a compile time error, Crystal didn't even run my code
<FromGitter> <j8r> Crystal is not a scripting language, that's why it is not meant for executing one liners in a shell prompt
<FromGitter> <kinxer> Re porting language idioms to other languages: my company wrote a huge application decades ago in Fortran, then the government (our usual client) required Ada, so they converted the whole thing to Ada *still using Fortran idioms*. Then, when the government abandoned Ada, they didn't want to manually convert it to C, so they wrote a translator to convert the Ada program into C, and we currently build the C
<FromGitter> ... program into an executable. As you can imagine, this is extremely laborious to maintain, and I haven't even touched it yet (having worked at the company almost 2 years) because it's not economical for me to waste time learning how to do anything with it. The initial problem was probably that the program was a monolith designed t ... [https://gitter.im/crystal-lang/crystal?at=5ece91f83ffa6106f1d9fddd]
<FromGitter> <kinxer> So don't do that.
<FromGitter> <j8r> @kinxer A better approach would be to manually convert it?
<FromGitter> <j8r> And link C to the main Ada program
<jhass> Crystal has a Ruby heritage and Ruby has a Perl heritage. So learning Ruby in addition to Crystal might quite fit you actually, Ruby for the one off experimental stuff and then taking that to Crystal is probably fairly low effort
<FromGitter> <j8r> As usual, right tool for right job. ⏎ awk can do surprisingly some task perl does
<FromGitter> <sam0x17> crystal would be effective for scripting with a good ccache-like caching system --- if files with `#!/usr/bin/crystal` compiled "instantly" when there are no changes because of a good cache, then it becomes possible. It's something I've been meaning to try to develop
<FromGitter> <j8r> I don't think it will change much
<FromGitter> <j8r> Because usually scripts/shell commands are not run often
<FromGitter> <j8r> If if there are, just compile the program then
<FromGitter> <Blacksmoke16> ^
<FromGitter> <Blacksmoke16> and add it to bin
<jhass> yeah I never quite understood the push of using crystal for scripting, Ruby and Shellscript fit that role much better in my toolbelt
<FromGitter> ... lang/crystal?at=5ece935d225dc25f54ac57e2]
<FromGitter> <simonhf> > *<jhass>* >> _, a, b = "foo".match(/bar/) ⏎ ⏎ I agree with you about the compile time error. However, you could write the same code pattern in Perl and yes, it would work, but... the results would be misleading. ⏎ Therefore in Perl I would write a different pattern to get better results. And that pattern does work in crystal: ⏎ ... [https://gitter.im/crystal-
<FromGitter> <simonhf> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ece936b2280c80cbfd0bbf7]
<FromGitter> <j8r> @sam0x17 Also there is already a good cache, which kind of compile very fast the second time
<FromGitter> <sam0x17> a second call to `shards build` takes 53 seconds on my linode VPS
<FromGitter> <sam0x17> for our web app
<FromGitter> <simonhf> jhass: therefore I think that crystal might be *better* for writing one liners than ruby or perl because it forces the writer to write cleaner code?
<FromGitter> <sam0x17> so my plan was actually to do it at the `shards` level, use inotify to watch `shards build` and see all the files it reads, then base cache key off of whether any of those files changed since the last run, if not then don't even let shards build run just plop in the last set of binaries from the cache and don't call the real `shards build`
<FromGitter> <j8r> @simonhf I mean, just use the right language for the right job
<jhass> ruby -ep '"[#{"foo"[/(o)/, 1]}]"'
<FromGitter> <j8r> Depending of the problem to solve, grep, awk, etc may be enough.
<jhass> for me oneliners are by definition unclean code
<FromGitter> <j8r> Even sed is Turing complete haha
<FromGitter> <sam0x17> so cache key would be hash(args to `shards build` + sha256 of all files `shards build` read on the last run)
<FromGitter> <j8r> jhass yep, for too long one
<FromGitter> <sam0x17> so if there are no relevant changes, it should return back in like 20ms ish
<FromGitter> <kinxer> @j8r At this point, the right move is probably to write something new, re-using the things we can get from it, but we'd need to be paid for that (i.e. it would need to fall under a govt contract). But yeah, we're at least trying to abandon the C step and just compile straight from Ada, 'cause there's no way that'll be *worse* than the automatically-translated C program.
<FromGitter> <j8r> But it is not realistic to rewrite all from scratch :/
<FromGitter> <jwoertink> Anyone here familiar with parsing XML?
<FromGitter> <jwoertink> I have this markup `<People><Person><Media><Pic><Full Src="" /></Pic></Media></Person> ...</People>`. I'm using xpath and doing `person_element.xpath_node("//Media/Pic/Full").not_nil!["Src"]`, but I ALWAYS get the first person's pic.
<FromGitter> <jwoertink> I get that the xpath is saying from the top, but I'm at the `<Person>` level, so I'd expect the "top" to be that element, and not of the whole doc
<FromGitter> <Blacksmoke16> isnt that what your path is saying? get the first node at that path
<jhass> / searches from the root
<jhass> eh, //
<jhass> it ignores the context node
<FromGitter> <jwoertink> is that an error?
<FromGitter> <jwoertink> or is there a flag to say don't do that?
<jhass> no, that's how // works
<FromGitter> <simonhf> another newbie question: what is the equiv of Perls sub BEGIN{} and sub END{} ?
<jhass> just use "Media/Pic/Full" as XPath
<FromGitter> <Blacksmoke16> whats that do?
<jhass> if you already found the context node, why restart the search
<jhass> simonhf: pretty sure we don't have this. I guesss you could abuse macro finished for END{} but eh
<FromGitter> <simonhf> @Blacksmoke16 e.g. sub END{} is a special function which will automatically run when the perl script exits
<FromGitter> <jwoertink> I assumed that once I have a specific element, that's all I have access to. So the whole document at that level is just `<Person></Person>`
<jhass> or at_exit
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/toplevel.html#at_exit(&handler:Int32,Exception?-%3E):Nil-class-method prob this then
<FromGitter> <jwoertink> in which case `//` is the top of that document
<FromGitter> <simonhf> a bit like atexit() in C but with an especially named function
<jhass> This only exists for perl -n / perl -p, which crystal doesn't have and shouldn't
<jhass> jwoertink: yeah, that assumption is just wrong :)
<FromGitter> <jwoertink> lol. Indeed it is.
<FromGitter> <jwoertink> I don't do a whole lot of XML parsing, so is that common to do it that way?
<jhass> XPath has the concept of a context node, referenced by . and it's set to the node you call the query function on
<jhass> yeah
<FromGitter> <jwoertink> What I was doing is at the top level, I find all of the `<Person>` elements, and iterate over each passing that element in to a `Person.new(person_element)`
<jhass> I think it's even in the standard
<jhass> node's really just references into the document tree
<jhass> *nodes are
<jhass> you can .parent your way all the way up
<jhass> what you're thinking of is a (document) fragment
<FromGitter> <simonhf> thanks @Blacksmoke16 and jhass but having some difficulties with at_exit: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ece966d225dc25f54ac6560]
<FromGitter> <jwoertink> Yeah, exactly. I expected each one to act like a fragment
<jhass> it's just a node though :)
<FromGitter> <Blacksmoke16> @simonhf missing a `;`
<jhass> >> at_exit { printf %[cruel world\n]; }; printf %[hello world\n]
<FromGitter> <jwoertink> Ok, now that I understand, it's cool. Thanks
<DeBot> jhass: hello world - more at https://carc.in/#/r/95n3
<FromGitter> <simonhf> interesting! thanks!
<FromGitter> <Blacksmoke16> also could just do like `crystal eval --time --progress 'at_exit { puts "cruel world" }; puts "hello world";'
<FromGitter> <Blacksmoke16> veruss printf stuff
<jhass> you could just puts "hello world\ncruel_world"
<FromGitter> <Blacksmoke16> πŸ˜‰
<FromGitter> <simonhf> :-)
<jhass> Crystal will never put an implicit loop around anything for you, so any sub END usecases you're thinking of here will never apply
<FromGitter> <simonhf> I'm guessing there is no equiv for Perls sub BEGIN{} then?
<jhass> sure is, just put it at the start of your program
<jhass> see above
<FromGitter> <Blacksmoke16> prob some also could do something with redefining main
<FromGitter> <Blacksmoke16> but 😬
<FromGitter> <kinxer> It really sounds like you want to use AWK, though. :P
<FromGitter> <simonhf> does crystal have a command line option for implicit loops like Perl has? ⏎ https://www.perl.com/pub/2004/08/09/commandline.html/
<FromGitter> <j8r> πŸ’― for AWK!
<jhass> (in theory you could do fun main(argc: Int32, argv: UInt8**) : Int32; Crystal.main do; start_code; Crystal.main_user_code(argc, argv); end; end; but why would you do that)
<FromGitter> <j8r> awk is anywhere, even on busybox
<FromGitter> <simonhf> In Perl one liners then sub BEGIN{} is useful in combination with implicit loops
<jhass> simonhf: I answered this question preemptively two times above while pointing out that you won't need at_exit for the usecases you're thinking of
<jhass> so: no and it never will
<jhass> it doesn't want to be this kind of language
<FromGitter> <simonhf> example of using sub END{} in Perl with implicit loop: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ece986f9da05a060a34e6eb]
<FromGitter> <j8r> sure
<jhass> ruby supports all of these features
<jhass> Crystal intentionally does not
<FromGitter> <j8r> that's good, they are not mandatory in any way
<FromGitter> <simonhf> hmmm... but the authors of crystal list their love of ruby as one of the main motivators of crystal... so I guess they do not love that particular ruby feature?
<FromGitter> <j8r> It would be better to think that crystal should be used in a `.cr` file
<FromGitter> <j8r> `eval` is just for quick testing
<FromGitter> <simonhf> interesting
<jhass> Ruby has Perl heritage but it grew big as the foundation of Rails, a web framework
<FromGitter> <sam0x17> slow testing :P xD
<FromGitter> <j8r> lol, cna be painful for all but fairly small snippets
<jhass> Crystal came out of that kind of userbase, writing long running programs in Ruby
<jhass> as such it shed most of the Perlisms, the most Perly stuff left in Crystal is $~, $1, $2, ...
<jhass> maybe ARGF
<jhass> but that's about it
<FromGitter> <j8r> @simonhf It is fine to keep using perl if you like it. What push you to use Crystal?
<ryanprior> Does anybody use crystal-readline and statically compile their binary? I'm getting a linker error when I try to do so.
<jhass> I don't but I'd bet you don't have a static version (.a file) of readline (and probably some more) available
<FromGitter> <j8r> Try `find /usr/lib -name "*readline.a"`
<FromGitter> <j8r> or `find /usr/lib -name "*readline*.a"`
<FromGitter> <sam0x17> TLDR for static compilation you almost always have to use a MUSL-based system aka alpline linux
<hightower4> simonhf things like BEGIN{} and END{} that you mention are a side-effect of Perl doing program compilation in two phases, and then additionally having -p and -n flags to like maximize the potential of writing oneliner scripts that process "lines" of code automatically separated by record separator etc... So, overall, part of this exists due to limitations in perl's design, and another part exists to write oneliners... Crystal is much more
<hightower4> similar to ruby. Ruby also provides -p, -n, $1, =~ // pattern matching and other similar gimmicks seen in Perl, but Crystal, due to it being compiled and strongly-typed, is not the ideal language for trying to rice oneliners.
<hightower4> If you're trying out crystal, be prepared to abandon "cool tricks" from perl (which in significant part exist due to perl's own design quirks) and instead learn/discover a proper, clean, object-oriented language.
<jhass> fun fact: ruby even sports BEGIN { } and END { }
<jhass> did I ever see them in a .rb file? no
<csaba> what I wonder... why 'crystal eval' does not support passing arguments
<csaba> rather it _concatenates_ all arguments passed
<csaba> crystal eval 'p ARGV' 1 2 3
<csaba> syntax error in eval:1
<csaba> Error: unexpected token: 1
<csaba> however:
<jhass> because if the program you pass to it is that complex, maybe it better goes to file already
<jhass> I tend to just have test.cr or tmp.cr and run that over using crystal eval
<csaba> crystal eval p ARGV
<csaba> []
<hightower4> csaba haha, yeah I remember a discussion about this a long time ago, I think the original idea was to allow like writing `crystal eval p 1 + 2` (which works). But this idea is totally strange I would say, and not what you'd expect from a unix command line program
<csaba> -- here p and ARGV are two different words but a single body of code is formed out of them
<hightower4> it would have been better to accept eval input only from STDIN
<FromGitter> <simonhf> > *<hightower4>* simonhf things like BEGIN{} and END{} that you mention are a side-effect of Perl doing program compilation in two phases, and then additionally having -p and -n flags to like maximize the potential of writing oneliner scripts that process "lines" of code automatically separated by record separator etc... So, overall, part of this exists due to limitations in perl's design, and another part
<FromGitter> ... exists to write oneliners... Crystal is much more ⏎ I'm not sure I buy that explanation, e.g. if i write a C program then I can have more than one main() function (i.e. constructor functions called by glibc et al) and choose when I start the C program which main() function to use. So why can't there be a main() function which ... [https://gitter.im/crystal-lang/crystal?at=5ece9eb3a91f120a6cc7e671]
<csaba> hightower4: indeed a strange syntax
<FromGitter> <simonhf> > @simonhf It is fine to keep using perl if you like it. What push you to use Crystal? ⏎ ⏎ I like everything about Perl (one-liners) except for the speed of execution... and until now there were no alternatives for me and I have looked at quite a few over the years... :-)
<csaba> actually even for simple test programs one may wish pass various arguments as the simplest form of input. This way one is forced to pass it either via STDIN or ENV
<jhass> so keep using perl for your onliners and use Crystal for your stuff that just runs too long (and I bet isn't a oneliner)
<jhass> if your long running stuff is really oneliners, it's probably IO bound and you won't get the level of speed up you might hope for from Crystal anyways
<jhass> at least not until you go out of one liner territory and towards custom data structures and generally smarter algorithms that never will fit into a one liner
<FromGitter> <simonhf> wow... you guys really are not one liner fans... but I'm not judging and isn't variety the spice of life?
<jhass> I use tons of oneliners, I even have a Ruby REPL permanently open
<jhass> we're trying to tell you that Crystal is not the right tool for those usecases
<hightower4> simonhf it's not about our preference... it's just advising you that you're trying to use the Crystal language for something that is not its primary target.
<hightower4> simonhf do you know Ruby? If you're approaching this knowing just Perl, you'll have a very steep learning curve because Perl is not a proper object oriented language. When I learned Ruby in 2008 (after 10 years of Perl), my programming wisdom improved a lot. Perl is just not a top-class language.
<FromGitter> <simonhf> @hightower4: I don't know Ruby and I'm not so interested in OO although I think it has it's place... but probably not in one liners :-)
<jhass> then you won't enjoy Crystal :)
<jhass> Ruby's other heritage besides Perl is Smalltalk
<jhass> and from that branch, Crystal actually inherits a whole lot
<FromGitter> <simonhf> @jhass: I've been enjoying Crystal so far :-)
<FromGitter> <kinxer> Are you writing one-liners whenever you need them or are you re-using these programs a lot?
<FromGitter> <kinxer> Also, is it only you reading (and writing) them?
<jhass> maybe you should try one of the code golfing languages :D
<FromGitter> <simonhf> @kinxer good question: I generally work the following way: do a lot of investigations and make lots of notes in e.g. wiki pages while doing them. the one liners are easy to copy and paste into the wiki notes. then n months / years later I can search and revisit the notes and it's low friction to copy and paste the one liners.
<FromGitter> <simonhf> If the one liners go into files suddenly then that adds more friction... having to make up file names, attach the files to wiki pages, more difficult to keep notes, etc etc
<jhass> maybe your workflow could vastly improve from tools like a jupyter notebook?
<jhass> or even just crystal playground's markdown file interpretation thingy
<jhass> is that documented somewhere btw?
<FromGitter> <simonhf> I've looked at jupyter but it's pretty niche and so the rest of the employees use status quo tools like confluence...
<FromGitter> <kinxer> My thought is also that if you're doing stuff that way (recompiling the program every time you need it), you're losing a fair amount of the performance you'd gain by using Crystal "as it's meant to be used" (i.e. compiling with `--release` and re-using the resulting executable).
<FromGitter> <kinxer> That is, you're losing the performance because you lose time to compilation.
<FromGitter> <kinxer> I guess if the scripts are doing work on the order of hours or days (in Perl), though, compilation time isn't gonna be a meaningful loss.
<FromGitter> <simonhf> @kinxer ... yes you're right... but luckily the one liners are generally short and so are sub second to compile and I'm hoping that the roadmap item 'incremental build' might help in the future :-)
<jhass> simonhf: did you run crystal play yet? Had a look at the "Workbook" tab?
<FromGitter> <Blacksmoke16> lol, i never noticed that...
<FromGitter> <simonhf> @jhass: probably at some point... I've looked at many crystal resources so far... still in the phase of trying to work out the crystal way to perform many of the patterns I use in Perl...
<jhass> Blacksmoke16: Most awesome hidden feature :D
<jhass> great for doing crystal talks
<FromGitter> <simonhf> not sure I looked at the workbook tab
<FromGitter> <simonhf> oh yeah I did... but it wasn't immediately obvious what it does...
<FromGitter> <simonhf> obvious to me :-)
<FromGitter> <simonhf> or what it's use case is...
<jhass> pretty similar to jupyter
<jhass> far less full featured of course
<hightower4> mighty tip jhass
<ryanprior> j8r, sam0x17: I do have /usr/lib/x86_64-linux-gnu/libreadline.a and I'm trying to compile for the same platform. Do I need to pass a special flag to crystal to help it find that .a file?
<jhass> maybe it's time to share the error you're getting then :)
<FromGitter> <simonhf> Here's a typical Perl one-liner with and without implicit loop, and the best I could do as a crystal newbie to make the shortest equivalent crystal one liner: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ Can the crystal one liner be made shorter? [https://gitter.im/crystal-lang/crystal?at=5ecea7f03ffa6106f1da4dc3]
<FromGitter> <Blacksmoke16> does it matter?
<jhass> yeah, shell out to ruby :D
<FromGitter> <Blacksmoke16> prob could just do like `STDIN.each_line.sum { ...`
<FromGitter> <Blacksmoke16> `crystal eval 'pp STDIN.each_line.sum { |l| /^(\d+)/.match(l); $1.to_i; }'`
<jhass> `| crystal eval system("awk '{s+=$1} END {print s}'"
<FromGitter> <kinxer> Why use `crystal eval` vs `crystal run`?
<oprypin_> kinxer, you pass source code directly to it rather than passing a file name with source
<jhass> crystal eval runs the argument(s) as code, crystal run executes the given file
<FromGitter> <kinxer> Ah, right.
<FromGitter> <simonhf> Definitely the .sum is a bit shorter :-) ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ecea9252280c80cbfd10b08]
<FromGitter> <simonhf> > *<jhass>* `| crystal eval system("awk '{s+=$1} END {print s}'" ⏎ ⏎ thanks... I should have said shorter and with similar performance :-)
<hightower4> haha
<jhass> well skipping the crystal eval system part from it is probably faster than perl
<jhass> and even shorter
<FromGitter> <simonhf> > Why use `crystal eval` vs `crystal run`? ⏎ ⏎ Does `crystal run` work with one liners?
<jhass> they're not interchangable in any way
<FromGitter> <kinxer> No, I was just having a brain fog moment.
<FromGitter> <simonhf> > *<jhass>* well skipping the crystal eval system part from it is probably faster than perl ⏎ ⏎ probably depends on the length of the input stream...
<FromGitter> <simonhf> but in the example, yes...
<FromGitter> <kinxer> `crystal eval 'puts "total: #{STDIN.each_line.sum { |l| /^(\d+)/.match(l); $1.to_i; }}"'`
<FromGitter> <kinxer> You don't need the `printf` if you use string interpolation.
<FromGitter> <Blacksmoke16> and `puts` adds the `\n`
<hightower4> can even use 'p' if you don't mind the pair of quotes printed
<jhass> also no need for regex, just .each_line.sum {|l| l.to_i? || 0 }
<FromGitter> <simonhf> > `crystal eval 'puts "total: #{STDIN.each_line.sum { |l| /^(\d+)/.match(l); $1.to_i; }}"'` ⏎ ⏎ Right... I just put that in there as a constant overhead to compare with the length of the Perl one liner... and I'm not trolling with Perl... I'm genuinely interested and wanting to figure out how to get the line length down with crystal :-)
<FromGitter> <kinxer> @jhass Yeah, I was thinking there must be a better way to do that matching...
<FromGitter> <kinxer> I'm glad to know it's that short.
<FromGitter> <Blacksmoke16> a not nilable version of `.match` may be useful
<jhass> that's String#[]
<jhass> so if you insist on regex for some weird reason, l[/\d/].to_i
<FromGitter> <Blacksmoke16> :0
<jhass> if you insist on a regex group for some weird reason, l[/(\d+)/, 1]
<FromGitter> <kinxer> I think `#to_i` should be sufficient, though.
<ryanprior> Here's my build log from trying to build static binary with readline: https://gist.github.com/ryanprior/11db1d75a7711e88feb912836a1ce695
<FromGitter> <kinxer> *`#to_i?`
<FromGitter> <simonhf> > *<jhass>* if you insist on a regex group for some weird reason, l[/(\d+)/, 1] ⏎ ⏎ no, the first perl example and the shortest uses no regex and I added the other ones just for fairness... it would be okay to remove the regex...
<FromGitter> <Blacksmoke16> is the first example essentially just stripping non numeric values?
<jhass> ryanprior: mmh, sounds like it doesn't pull in curses for some reason?
<jhass> or whatever library these functions come from
<FromGitter> <Blacksmoke16> `perl -e 'foreach(1..100){ printf qq[%u\n], $_;}' | crystal eval 'puts "total: #{STDIN.each_line.sum { |l| l.to_i strict: false }}"'`
<FromGitter> <simonhf> starting to get into Perl shortness territory :-) ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eceab80ff7a920a72163f34]
<jhass> ryanprior: try to find which library defines these symbols (the `nm` tool should help), make sure to get a static archive of it and pull it in via --link-flags
<FromGitter> <Blacksmoke16> `perl -e 'foreach(1..100){ printf qq[%u\n], $_;}' | crystal eval 'puts "total: #{STDIN.each_line.sum &.to_i}"'` not sure how this works tho
<FromGitter> <Blacksmoke16> would think `to_i` would fail
<FromGitter> <simonhf> as a newbie I don't quite understand `l.to_i strict: false` and `l.to_i? || 0` in the above examples...
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/String.html#to_i(base:Int=10,whitespace:Bool=true,underscore:Bool=false,prefix:Bool=false,strict:Bool=true,leading_zero_is_octal:Bool=false)-instance-method
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/String.html#to_i?(base:Int=10,whitespace:Bool=true,underscore:Bool=false,prefix:Bool=false,strict:Bool=true,leading_zero_is_octal:Bool=false)-instance-method
<oprypin_> wow i ended up with the condition `if path.ends_with_separator? && !path.anchor || !path.basename.includes?(".") && !path.basename.empty?` - that's quite something
<FromGitter> <Blacksmoke16> ah it works since perl is just printing the numbers
<FromGitter> <Blacksmoke16> i thought it was printing like `qq1` ...
<FromGitter> <simonhf> > https://crystal-lang.org/api/master/String.html#to_i?(base:Int=10,whitespace:Bool=true,underscore:Bool=false,prefix:Bool=false,strict:Bool=true,leading_zero_is_octal:Bool=false)-instance-method ⏎ ⏎ Ahhh... so it's just handling the nil case...
<ryanprior> jhass: thanks for the suggestion! I'm reading the man page for nm but it doesn't seem clear to me what I'd need to run it on. Do I do a partial build of my program to get an object file and then run it on that?
<FromGitter> <simonhf> how is `sum &.to_i` different than `sum.to_i` ?
<FromGitter> <Blacksmoke16> `sum &.to_i` is the same as `sum { |v| v.to_i }`
<FromGitter> <Blacksmoke16> `sum.to_i` would call `.to_i` on the return value of `.sum`
<FromGitter> <Blacksmoke16> which you cant use in this context since the values are strings
<jhass> ryanprior: no, you'd run it on the .a file you suspect those missing symbols in!
<jhass> to verify they're actually in there
<jhass> with some scripting you might even be able to iterate through all the *.a's you have and grep for a missing symbol to find the right one
<FromGitter> <simonhf> > `sum &.to_i` is the same as `sum { |v| v.to_i }` ⏎ ⏎ nice, a little short cut... what is that called and where is it described in the docs?
<FromGitter> <simonhf> thanks!
<FromGitter> <simonhf> those last example definitely get crystal into Perl short one liner territory: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eceade92c49c45f5aa6fc72]
<FromGitter> <Blacksmoke16> if you dont use printf, prob a bit shorter yea
<FromGitter> <simonhf> right... but then the Perl equivalent would also be a bit shorter too :-)
<ryanprior> jhass: I tried searching in my .a files for one of the undefined references (tgetflag) and found it matches libreadline.a, libtermcap.a, and libtinfo.a
<FromGitter> <kinxer> Sure, but why not compare those shorter versions instead? I mean, what you're getting from Crystal is speed, not terseness. You just want something that approaches the terseness of perl.
<ryanprior> So supposing I want to try linking libtinfo.a in, how do I do that?
<FromGitter> <kinxer> Regardless, the Crystal is approximately 10**20% more readable.
<jhass> ryanprior: never tried, my first guess would be adding `--link-flags="-ltinfo"` to `crystal build`
<ryanprior> Yep that worked in the sense that I see that in the linker flags, but the build still fails with either of those linked in.
<ryanprior> Or both.
<jhass> ryanprior: the captial letter in front of the symbol of the nm output tells you whether the library defines or references it
<jhass> U says it referenes it, pretty much everything else should mean it's defined there
<jhass> mmmh, weird
<jhass> is it really the exact same build failure?
<jhass> also couldn't hurt to try linking both in, --link-flags="-ltinfo -ltermcap`
<ryanprior> I diffed them and it is the exact same build failure, modulo the new linker flags in the command echo
<ryanprior> I did try linking them both in
<jhass> stackoverflow suggests -lncurses πŸ€·β€
<FromGitter> <simonhf> > Sure, but why not compare those shorter versions instead? I mean, what you're getting from Crystal is speed, not terseness. You just want something that approaches the terseness of perl. ⏎ ⏎ This is for you @kinxer : ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5eceb12f9da05a060a3545c3]
<FromGitter> <Blacksmoke16> close enough id say
<FromGitter> <simonhf> oh yeah, it is :-)
<ryanprior> Exact same failure with -lncurses or with both termcap and ncurses.
<ryanprior> Bizarre that this works fine if I accept dynamic linking.
<ryanprior> I just don't understand how to get in here and figure out what it can't find.
<jhass> with dynamic linking the linker doesn't have to resolve those
<jhass> because the dynamic library is already linked against what it needs
<jhass> so only the runtime linker needs to resolve it
<jhass> idk, https://github.com/monero-project/monero/issues/2919 suggests -ltermcap helps
<jhass> where in the linker output do the --link-flags appear? it's a bit order dependent, especially around the -static flag
<FromGitter> <simonhf> another newbie question: in Perl then `printf "foo\n"` will not necessarily output the line due to output buffering which can be fixed with the cryptic `$|++` ... how does that work in crystal?
<ryanprior> jhass: they get added before -static or anything else
<FromGitter> <Blacksmoke16> ^ that'll be set to `true` by default i think in next version
<jhass> default is true if STDOUT.tty? iirc, we switched it around so much though that I'm no longer sure
<jhass> ryanprior: aha, that's probably it!
<FromGitter> <Blacksmoke16> or was it the other way...
<ryanprior> Oh well crap. It doesn't offer any ability to append flags to the end. I suppose I'll have to break apart the build and write my own linker invocation?
<jhass> ryanprior: we need to figure out to push them behind... or maybe it doesn't error on having static twice? so --link-flags="-static -ltermcap" or so
<ryanprior> Oh yeah I'll try that
<jhass> ryanprior: I also vaguely remember something about -l:termcap doing a static link... not sure
<jhass> worst case will be adding a nother @[Link] annotation to LibReadline or whatever it is in your code
<ryanprior> Got it. Kinda tortured but we got it.
<jhass> cool :)
<ryanprior> Here's what worked: `crystal build --release --static --link-flags "-rdynamic -static -lreadline -ltermcap -lncurses" meet.cr` X.X
<jhass> Β―\_(ツ)_/Β―
<ryanprior> Also works without ncurses.
<ryanprior> Does not work with ncurses but no termcap. So termcap is the missing bit.
<ryanprior> I'm gonna submit a PR to crystal-lang/crystal-readline with some static linking advice =D
<jhass> <3
<ryanprior> Thanks for offering many hints and nudges!
<FromGitter> <Blacksmoke16> https://gitter.im/crystal-lang/crystal?at=5ecdb0832c49c45f5aa430ae ⏎ ⏎ allisio: if you're still here prob should checkout that lib as well. Should help with what you're doing i think?
<jhass> gladly :)
<FromGitter> <watzon> What are you using readline for?
<FromGitter> <Blacksmoke16> *reading lines* :trollface:
<ryanprior> A little config wizard which asks you "What's your server's base URL? > " etc and creates your config yaml.
<FromGitter> <watzon> Lol just saying https://github.com/crystal-term/reader
<ryanprior> This is for https://github.com/ryanprior/meet/ which you should definitely use if you start a lot of Jitsi meetings :)
<oprypin_> >> File.executable?("/usr") # πŸ˜‘
<DeBot> oprypin_: # => true - https://carc.in/#/r/95nz
oprypin_ is now known as oprypin
<ryanprior> watzon: starred & will check that out! Thank you for the link!
<FromGitter> <watzon> No problem :) there's also https://github.com/crystal-term/prompt if you're just accepting user input and want some nice prompts.
<FromGitter> <watzon> Wip, but it seems pretty stable so far in my testing
<oprypin> ok how do i actually check if something is an executable file
<jhass> oprypin: fwiw ruby thinks the same: https://carc.in/#/r/95o1 :D
<jhass> chain .file? ?
<oprypin> i think it's two stat calls
<ryanprior> H*ck yeah, bookmarking all of this
<FromGitter> <Blacksmoke16> looks like CI is broken on the one @watzon
<jhass> the other day I saw https://github.com/Papierkorb/fancyline
<jhass> oprypin: maybe you can pull it out of File.info then?
<FromGitter> <watzon> Yeah I know. I'll fix it right now actually.
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <watzon> Should be fixed as soon as this run is finished
<FromGitter> <Blacksmoke16> nice
<oprypin> jhass, aa then i'd need to figure out how `accessible?(path, LibC::X_OK)` translates to Permissions::OwnerExecute or such
<oprypin> two calls it is
<FromGitter> <simonhf> > *<jhass>* https://crystal-lang.org/api/0.34.0/IO/Buffered.html#flush_on_newline=(flush_on_newline)-instance-method ⏎ ⏎ Thanks. I got it working: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ecebcb24412600ccd705e5f]
<FromGitter> <simonhf> In Perl you could write either `use IO::Handle; STDOUT->autoflush(1);` or the short cut `$|++` ... are there such short cuts in crystal in general, and is there one for flush_on_newline?
<FromGitter> <Blacksmoke16> lol no
<FromGitter> <Blacksmoke16> crystal would rather use english than hieroglyphics
<FromGitter> <simonhf> I thought so... I am slowly getting into the crystal mindset of the authors :-)
<FromGitter> <simonhf> But as as newbie you never know... there is still $~ and $1, $2, etc :-)
<FromGitter> <Blacksmoke16> thats all there is
<FromGitter> <simonhf> must have pained not to call them e.g. $capture1, $capture2, etc :-)
<FromGitter> <kinxer> To be honest, I didn't know they existed until today (and I'm still not sure what they do), because I haven't needed them.
<FromGitter> <asterite> and these were considered for removal too
<ryanprior> Don't say it too loud or they'll change their minds.
<ryanprior> Crystal isn't 1.0 yet
<oprypin> ryanprior, fyi asterite is the main "they" πŸ˜‚
<FromGitter> <asterite> nah, right now Juan and Brian are the main "they" :-)
<oprypin> :D
<FromGitter> <asterite> I'm the "they were" :-P
<FromGitter> <kinxer> Ary "The Original 'They'" Borenszweig
<FromGitter> <kinxer> Actually, "The Original They" sounds like a pretty good band name.
<oprypin> :>
<FromGitter> <simonhf> another newbie question: is there any equivalent to the Perl command line `perldoc perlre` if I want to read up on regexes? or `perldoc -f printf` if I want to read up on a particular function?
<FromGitter> <simonhf> or are all docs online?
zorp_ has quit [Ping timeout: 258 seconds]
<FromGitter> <Blacksmoke16> you can download the HTML
<FromGitter> <Blacksmoke16> but yea, docs are all via html/json
<FromGitter> <simonhf> also, for online docs, is there any equivalent to the PHP docs which have the excellent feature of an examples section and a user contributed notes section? ⏎ https://www.php.net/manual/en/function.printf.php
<FromGitter> <watzon> No there aren't right now
<FromGitter> ... variety, so things like if() as suffixes and short cuts and command line eval might just disappear before version 1.0. This seems like a potential shame because although OO fans likely are in the majority, the OO obsession will alienate many others. And does it really need to be like that? Why shouldn't crystal source code allow ... [https://gitter.im/crystal-lang/crystal?at=5ecec3614c9b0f060d29fff8]
<FromGitter> <simonhf> > *<ryanprior>* Crystal isn't 1.0 yet ⏎ ⏎ This might be the biggest issue for switching to crystal for me... and the biggest difference between Perl and crystal mentality AFAIK: With Perl then the mentality is that variety is the spice of life to the point where there are short cuts and if() as suffixes and implicit loops, etc. Whereas crystal mentality seems obsessed with OO to the point of killing off
<ryanprior> I write pretty functional-style Crystal and hope that remains a viable option.
<FromGitter> <simonhf> follow-up question: approx. when will crystal likely hit version 1.0 ?
<FromGitter> <Blacksmoke16> > Why shouldn't crystal source code allow the variety more. ⏎ ⏎ Because then you end up with syntax like `$|++`
<FromGitter> <Blacksmoke16> and no idea what it means if you dont already know what it means
<FromGitter> <Blacksmoke16> versus anyone can read `STDOUT.flush_on_newline = false` and know what it means
<FromGitter> <asterite> Rumors say 1.0 is around the corner. And there won't be any more big changes to 1.0 as far as I know
<FromGitter> <Blacksmoke16> there are plenty of shortcuts, they're just not cryptic. `$1` and such are the only instances of that style
<FromGitter> <simonhf> > > Why shouldn't crystal source code allow the variety more. ⏎ > ⏎ > Because then you end up with syntax like `$|++` ⏎ ⏎ haha but just because it exists as an option doesn't mean you have to use it yourself... just like with the if() suffix stuff :-) ... [https://gitter.im/crystal-lang/crystal?at=5ecec61c4c9b0f060d2a0bcc]
<FromGitter> <Blacksmoke16> if suffix isnt a far comparison. Its the same just on one line
<FromGitter> <Blacksmoke16> fair*
<FromGitter> <simonhf> I'm not sure about that... it's a fashion option just like the short cuts... and many people avoid it like the plague... just like with the short cuts...
<raz> psa, next time you need a hash, blake2b is your friend: https://carc.in/#/r/95ob
<raz> (kudos to didactic for bringing sodium to crystal)
<FromGitter> <Blacksmoke16> there isnt any cognitive overload to `puts "hi" if expression` versus ⏎ ⏎ ```if expression ⏎ puts "hi"``` [https://gitter.im/crystal-lang/crystal?at=5ecec6be9da05a060a3599a3]
<FromGitter> <Blacksmoke16> compared to `STDOUT.flush_on_newline = false` and `$|++`
<FromGitter> <Blacksmoke16> overhead*
<FromGitter> <j8r> I hope ARM support is targeted for 1.0
<FromGitter> <simonhf> hehe... maybe not for you... but there's all different people with different cognitive overloads :-)
<FromGitter> <Blacksmoke16> :thinking:
<FromGitter> <Blacksmoke16> if they have trouble with that then they'll deff have trouble with `$|++`
<FromGitter> <j8r> that's quite funny, at times there are people with their number one languages :) ⏎ There was the TCL guy, and now Perl guy haha
<FromGitter> <asterite> I don't understand what's the benefit of using `$|++` vs a more clear expression. It just saves you 5 seconds of typing?
<FromGitter> <Blacksmoke16> there isnt one, expect for writing super short one liners that no one can easy read :P
<FromGitter> <j8r> We only save 1 char
<FromGitter> <j8r> `i+=1` is valid
<FromGitter> <asterite> Oh, wait, `$|` is a variable and it's being incremented? :-O
<raz> leave cryptic additions to the Crypto and OpenSSL namespaces please :P
<FromGitter> <simonhf> > if they have trouble with that then they'll deff have trouble with `$|++` ⏎ ⏎ I think there's also two separate questions: 1. Should there be short cuts like Perl and Ruby? and 2. What should those short cuts be? I'm not arguing that `$|` is the right short cut for the particular job... :-)
<raz> if someone feels a need to make their code hard to read they can always go to town with macros...
<FromGitter> <Blacksmoke16> 1) no, 2. irrelevant :P
rocx has quit [Ping timeout: 260 seconds]
<FromGitter> <Blacksmoke16> here you go
<FromGitter> <kinxer> While I'm sympathetic to the "people should be allowed their coding styles" argument, it just becomes an unnecessary issue when you're working on a team (what version do you use? do you have to learn everyone else's way of doing this one thing?).
<FromGitter> <Blacksmoke16> its a balance
<FromGitter> <simonhf> > I don't understand what's the benefit of using `$|++` vs a more clear expression. It just saves you 5 seconds of typing? ⏎ ⏎ I think so == more productive. Also, some people compose very 'flowery' sentences because they prefer that. And some people get the same point across with terse sentences. We tolerate both in real life and there is no clear winner, or? And people can be flowery one day and terse
<FromGitter> ... the next :-)
<FromGitter> <Blacksmoke16> depends on context ofc
<FromGitter> <Blacksmoke16> or be in the middle ground and just be clear
<raz> ^
<FromGitter> <Blacksmoke16> then there is no problem
<raz> unless there's a strong reason for offering multiple ways to do something, there should be exactly one way.
<FromGitter> <Blacksmoke16> using fancy words doesn't make your sentence more clear. Using a bunch of simple words also doesn't. Using standard language for your target age is the most clear and readable
<FromGitter> <Blacksmoke16> then you dont leave anyone out, everyone's sentence (code) is the same level
<FromGitter> <simonhf> > *<raz>* if someone feels a need to make their code hard to read they can always go to town with macros... ⏎ ⏎ Thanks! I think this is a really good and practical suggestion!
<FromGitter> <Blacksmoke16> 😬
<raz> yw :)
<FromGitter> <j8r> haha
<FromGitter> <j8r> I wonder it is possible to write an actual program only with macros...
<FromGitter> <j8r> what a mad idea
<FromGitter> <Blacksmoke16> :thinking:
<FromGitter> <simonhf> another newbie question here: so gcc has the option `--include` to automatically force an include file to be included as line #1... is there some kind of mechanism which would have a similar effect for crystal? maybe an environment variable or something to force my crystal macro file to always be loaded the first thing?
<raz> require?
<FromGitter> <Blacksmoke16> whats the use case?
<FromGitter> <Blacksmoke16> require "./macros.cr"
* raz smells an obfuscated crystal contest in the making
<FromGitter> <Blacksmoke16> someone should make an `uglify.cr` :S
<FromGitter> <simonhf> > *<raz>* require? ⏎ ⏎ yep... require is the obvious one... but then you have to type it in every time... I wondered if there is a way of auto including / requiring ?
<FromGitter> <Blacksmoke16> *rearranges random bytes within the binary to keep your code secure!*
<FromGitter> <Blacksmoke16> type it once in your `main.cr` file and not worry about it?
<FromGitter> <Blacksmoke16> or are you still talking about one liners and wanting some helper file...
<FromGitter> <simonhf> > type it once in your `main.cr` file and not worry about it? ⏎ ⏎ and if you want to auto include it for a command line eval ?
<oprypin> i don't understand, where can i put common one-time initialization code for specs?
<FromGitter> <Blacksmoke16> `Spec.before_suite { }`
<oprypin> `describe foo; create_files; it { use_file }; it { use_file}; end`
<oprypin> `describe foo; Spec.before_suite { create_files }; it { use_file }; it { use_file}; end`
<oprypin> but will it run at the beginning of everything or before my describe?
<FromGitter> <Blacksmoke16> before_suite runs once at very start
<FromGitter> <Blacksmoke16> if you want once for describe block you want `before_all` iirc
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Spec/Methods.html#before_all(&block)-instance-method
<oprypin> oh . well yea that's what i want
<oprypin> thanks
<FromGitter> <Blacksmoke16> @simonhf i suppose you could use a custom `--prelude` and require it in there
<FromGitter> <simonhf> > > type it once in your `main.cr` file and not worry about it? ⏎ > ⏎ > and if you want to auto include it for a command line eval ? ⏎ ⏎ I guess this would also be useful not just for shorter macros for commonly used code, but also for things like the `STDOUT.flush_on_newline` where you are not sure if the particular version of crystal has that on or off by default...
<FromGitter> <Blacksmoke16> then alias to something so it uses that for each crystal call
Human_G33k has joined #crystal-lang
<FromGitter> <simonhf> > then alias to something so it uses that for each crystal call ⏎ ⏎ that sounds interesting... where to find examples of that?
<FromGitter> <Blacksmoke16> make a copy of that, add your require, then to `--prelude=my_prelude.cr`
<FromGitter> <simonhf> @Blacksmoke16 thanks for the tip!
alexherbo2 has joined #crystal-lang
HumanG33k has quit [Ping timeout: 256 seconds]
<FromGitter> <simonhf> hmmm... maybe `--preclude` does not work with eval?
<FromGitter> <Blacksmoke16> dunno
<FromGitter> <Blacksmoke16> getting into even more hackiness so yea...
<FromGitter> <simonhf> hmmm... gcc's `--include` option comes in useful sometimes... not sure I'd call it hacky...
<FromGitter> <Blacksmoke16> no but editing prelude kinda is
<FromGitter> <asterite> what's the difference between doing `crystal eval --include foo 'code'` and `crystal eval 'require "foo"; code`?
<FromGitter> <asterite> Also, I think crystal eval is not really used a lot... and I personally have a really hard time understanding code inside a crystal eval, so I just avoid it
<oprypin> excuseme. i use it like every day
<FromGitter> <Blacksmoke16> prob be better just putting this stuff in a file, then do a `crystal run`?
<FromGitter> <j8r> For small snippets, can be convenient
<FromGitter> <j8r> I usually prefer to have a quick `a.cr` and quickly code inside to test a thing
<FromGitter> <Blacksmoke16> `subl test.cr` :P
<FromGitter> <asterite> I always have a `foo.cr` file in the crystal repo where I can try stuff
<FromGitter> <Blacksmoke16> eya
<FromGitter> <asterite> and `bar.cr` and `baz.cr` in case I need multiple files :-)
<FromGitter> <simonhf> > what's the difference between doing `crystal eval --include foo 'code'` and `crystal eval 'require "foo"; code`? ⏎ ⏎ I guess the difference is that with `--preclude` outside the single quotes one could write a shell macro to auto preclude? just like people have short cuts for `ls -al` and call the short cut `ll` ?
<FromGitter> <j8r> same here
<FromGitter> <j8r> Otherwise, good luck to search in your history
rocx has joined #crystal-lang
<FromGitter> <asterite> @simonhf that makes sense. Maybe you can send a proposal and someone might do it
tdc has quit [Ping timeout: 272 seconds]
<FromGitter> <simonhf> > @simonhf that makes sense. Maybe you can send a proposal and someone might do it ⏎ ⏎ Thanks for the suggestion. I created this github ticket: ⏎ https://github.com/crystal-lang/crystal/issues/9364 [https://gitter.im/crystal-lang/crystal?at=5eced03b4412600ccd70adaa]
<FromGitter> <asterite> Thanks! But note that `--prelude` is not what you want for eval, you always want the default prelude and require some extra file(s)
<FromGitter> <simonhf> Wouldn't the prelude file specified just include the default prelude file as well, and then all is good? Or how else to pre-include a misc file?
<FromGitter> <Blacksmoke16> that suggestion was a hacky workaround idea ^
* raz fails to see the point of all this
<FromGitter> <simonhf> > that suggestion was a hacky workaround idea ^ ⏎ ⏎ hehe ... is there a better suggestion?
<raz> yes, i have one
<raz> make a shell script that performs all the pre-processing you want and then calls crystal
<FromGitter> <simonhf> it is valid suggestions and sounds like a perl one liner ;-)
<FromGitter> <simonhf> or a crystal one liner :-)
<raz> exactly. you can even make it perform substitutions on your crystal files to enable your $| syntax!
<FromGitter> <simonhf> but I think it would be consistent for the `--prelude` option to work for eval and will as build...
<FromGitter> <simonhf> I guess other build options like `--link-flags` and `--define` etc might also be useful for eval too?
<oprypin> oh i didnt realize that Crystal enforces always yielding the same number of items
<FromGitter> <asterite> > Wouldn't the prelude file specified just include the default prelude file as well ⏎ No, the --prelude option replaces the default prelude. And it actually has just a single use case: for us the compiler developers to try out code without any prelude at all (using "empty" as a prelude). Users shouldn't find any use in that flag.
<oprypin> Blacksmoke16, so before you were saying that i can use `before_all`. then um how can i expose a variable from that to be visible to every test inside?
<FromGitter> <Blacksmoke16> now *that* im not sure about
<FromGitter> <Blacksmoke16> maybe just declare it top level and see if you can edit it? :P
<oprypin> hmmm
<FromGitter> <Blacksmoke16> or use some private module as a singleton for it?
<oprypin> no it doesnt work
<FromGitter> <Blacksmoke16> :shrug: whats the use case?
<oprypin> oh god
<oprypin> i just want to create a temporary directory with a complex file structure
<oprypin> and pass its name to each test
<FromGitter> <Blacksmoke16> prob be easier to use some custom `it` wrapper
<oprypin> tell me
<FromGitter> <Blacksmoke16> `with_temp_file do |file| ...`
<oprypin> wait no dont tell me
<FromGitter> <Blacksmoke16> πŸ‘
<oprypin> Blacksmoke16, so i did that, wrapped everything in `with_tempfile`, and put a bunch of `it`s inside it. but the thing is, the files get deleted before any of the tests run
<oprypin> thats probably not what you meant, huh
<FromGitter> <Blacksmoke16> i was picturing like
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ecedaf0778fad0b132e43d7]
<FromGitter> <Blacksmoke16> er i guess thats what you did
<FromGitter> <Blacksmoke16> plan b
<FromGitter> <Blacksmoke16> ```it "do something" do ⏎ with_file do |file| ⏎ ... ⏎ end ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5ecedb2a3ffa6106f1db092b]
<FromGitter> <Blacksmoke16> other option maybe add an overload of `it` called `with_file`?
<FromGitter> <Blacksmoke16> probably would work..
<oprypin> Blacksmoke16, i want to create those files only once
<FromGitter> <Blacksmoke16> ogh right
<FromGitter> <Blacksmoke16> private module class property?
<FromGitter> <Blacksmoke16> this used to work, but specs use `at_exit` now so yea...
<oprypin> at_exit it is then
<FromGitter> <Blacksmoke16> not what i meant
<FromGitter> <Blacksmoke16> the code outside of the `it` blocks runs and exits before the `it` block code runs
<oprypin> what the heck, now at_exit stuff runs before any of the tests
<FromGitter> <Blacksmoke16> would need to define your `at_exit` before you `require "spec"`
<oprypin> thats so dumb
<oprypin> aaaaaaaaaaaaaaaaaaaaa
<FromGitter> <j8r> @Blacksmoke16 I'm still thinking how to implement Any, I see 2 ways: ⏎ ⏎ 1) Having an Any interface (module or abstract struct) that can be implemented by the format (this is literally a 5 line struct) ⏎ 2) Having a common Any, which has a `Type` alias of a lots of types that a format can support [https://gitter.im/crystal-lang/crystal?at=5ecedeb12c49c45f5aa7acd6]
<FromGitter> <j8r> I'm highly favoring the first option
<FromGitter> <j8r> This also allows to have custom methods for formats, but also maintains compatibility between different Anys implementation
<FromGitter> <Blacksmoke16> oprypin: i agree
<FromGitter> <j8r> there is also the monkey-patching option, as done in the stdlib now - which I don't really want to reproduce
<FromGitter> <Blacksmoke16> was nice when: ⏎ ⏎ ```with_file do |file| ⏎ it "" { file ... } ⏎ it "" { file ... } ⏎ end``` ⏎ ⏎ worked... [https://gitter.im/crystal-lang/crystal?at=5ecedf8cb101510b201fc53f]
<FromGitter> <Blacksmoke16> isnt that what i did @j8r ?
<FromGitter> <Blacksmoke16> and just add it to `JSON::Any` and such?
<FromGitter> <j8r> Looking at it, yes
<FromGitter> <j8r> With one different - minus all the abstract methods to implement
<FromGitter> <j8r> It is fine for your use-case, but other formats may not have types like Bool or Float
<FromGitter> <j8r> I will just implement a `to(type : T) :T forall T`
<FromGitter> <Blacksmoke16> our use cases are a bit diff, since yours happens while deserializing the data, while mine is after it has been parsed
<FromGitter> <Blacksmoke16> they could still be defined, just raise a `NotImplemented` or something :shrug:
<FromGitter> <bararchy> Extracted and OpenSourced the helpers we use in NeuraLegion for MultiThreading -> https://github.com/NeuraLegion/mt_helpers
alexherbo2 has quit [Ping timeout: 260 seconds]
<oprypin> ah lol and if there's any error in specs outside of `it`, it says "Error running at_exit handler" always
<oprypin> i was soooo confused by that
<FromGitter> <Blacksmoke16> long term i think it would make sense to add some more abstractions and an actual common interface, but meh is fine for now
<FromGitter> <christopherzimmerman> @bararchy thanks for that, I will definitely steal it :P, been trying to bring MT to my numerical library for a while
<FromGitter> <j8r> For example, how to convert a XML to JSON and vice versa
<FromGitter> <j8r> I think it will be good to have a Any for XML, which can have additional methods
<FromGitter> <Blacksmoke16> prob
<FromGitter> <j8r> I'm afraid with a single Any there were always types lacking that a format supports
<FromGitter> <j8r> I tried to have a generic `Any(T)` - was not possible :/
<FromGitter> <Blacksmoke16> like what?
<FromGitter> <christopherzimmerman> Is there a way to force a class getter to compute itself again? https://gist.github.com/christopherzimmerman/b5d5b33a89c874332e8658767c378c0d I have this bit of code which caches OpenCL Kernels as `class_getters`, but for some methods I want to add a flag for JIT compilation.
<FromGitter> <Blacksmoke16> most of the time its going to be some scalar value, list of values, or a mapping of key => values
<FromGitter> <Blacksmoke16> lazy getters?
<FromGitter> <Blacksmoke16> wont run until you call it
<FromGitter> <christopherzimmerman> That's what I use currently (pretty sure you actually were the one that showed me that), but I'd like a way that I can call it more than once if I want.
<FromGitter> <j8r> I guess XML
<FromGitter> <christopherzimmerman> So `class_getter foo : T { something here }`, but then I can call `foo` or `foo.recompute`, idk.
<FromGitter> <christopherzimmerman> So the lazy thing gets called again for the second one
<FromGitter> <Blacksmoke16> it would recompute if you return `false` or `nil` from the block
<FromGitter> <Blacksmoke16> but idt thats really helpful..
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <christopherzimmerman> Hmm, maybe the best I can do is have another `class_getter foo_jit` that computes it every time, not a big deal
<FromGitter> <christopherzimmerman> Probably can make a macro so I don't have to type it twice :P
<FromGitter> <Blacksmoke16> or just abstract the logic that goes in the block
<FromGitter> <Blacksmoke16> then you could rerun it within a `reset` method or something?
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ecee471549761730b60978c]
<FromGitter> <christopherzimmerman> I think I like that the best, thanks!
<FromGitter> <Blacksmoke16> prob making it private as well
<FromGitter> <j8r> Just seen, GitHub has changed their icons
<FromGitter> <j8r> IIRC, assuming an object has a given method to perform an action - it's duck-typing?
<FromGitter> <j8r> like `to_json` for serialization?
<FromGitter> <christopherzimmerman> I'm not a fan of the new look honestly
<FromGitter> <j8r> The icons are more thin, more void inside
<FromGitter> <christopherzimmerman> They should fill in stuff that you have starred
<FromGitter> <christopherzimmerman> Now the only difference is that it says "Unstar" instead of "Start", no visual difference like before
<FromGitter> <j8r> right, that's very confusing
<oprypin> temp directory with cleanup
<oprypin> the path to them is kinda hardcoded tho
<FromGitter> <Blacksmoke16> hmm
<oprypin> thanks for advice, the initial one helped
<FromGitter> <Blacksmoke16> np
<oprypin> this test suite tho. im so proud of it. it captures the fact that on Windows, `CreateProcess("sub/")` will launch the file `"sub/.exe"` if it exists. https://github.com/crystal-lang/crystal/pull/9365/files#diff-412cadfdfe4e441610dad047abe6a485R29
cloaked1 has joined #crystal-lang