jhass changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Crystal 0.35.1 | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <Daniel-Worrall> Well I'll see you in 5 hours for another AoC ;)
<straight-shoota> Blacksmoke16, I'm not familiar with PReader at all
<Andriamanitra> what is preader even for? it doesn't seem to be documented
<straight-shoota> for your use case it seems reasonable
<straight-shoota> it's the implementation for File#read_at
<Andriamanitra> i see, thanks
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang/crystal/blob/5751927b339dd2616caec65f1b0830336f22cd58/src/file/preader.cr#L15 from what i can tell it would be like, make that line only happen if its not nil or something
<FromGitter> <Blacksmoke16> i can make some issues for these, just didnt want to spam them and they already be known things
<straight-shoota> sure
<straight-shoota> I guess adding some Paths here and there could go directly into a PR
<straight-shoota> at this point it seems obvious that we should have Path as an option for every path-related argument
<FromGitter> <Blacksmoke16> πŸ‘ cool then ill make one about int type restriction and optional bytesize for preader
<FromGitter> <Blacksmoke16> issues that is
postmodern has joined #crystal-lang
<FromGitter> <HertzDevil> i wish preader is seekable
HumanG33k has quit [Quit: Leaving]
straight-shoota has left #crystal-lang ["Leaving"]
<oprypin> preader is private, what is going on
<FromGitter> <Blacksmoke16> `file.read_at 10_i64, 10_i64` files
<FromGitter> <Blacksmoke16> fails*
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
straight-shoota has joined #crystal-lang
<FromGitter> <Blacksmoke16> any of you guys know of a way to build master when on arch/manjaro when it updated to 11?
<oprypin> Blacksmoke16, install llvm10
<oprypin> as opposed to llvm
<FromGitter> <ImAHopelessDev_gitlab> just install the latest WSL 2
<oprypin> pls
<FromGitter> <Blacksmoke16> lol i didnt think it would be that easy
<FromGitter> <Blacksmoke16> thanks
<FromGitter> <ImAHopelessDev_gitlab> @Blacksmoke16 are you proficient in c?
<FromGitter> <Blacksmoke16> No
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> same. i find it very difficult to grasp but am trying
<FromGitter> <Blacksmoke16> why? just to be familiar with it?
<FromGitter> <ImAHopelessDev_gitlab> some code in godot's source is c, and i compile their 2.1 branch every now and then with some changes
<FromGitter> <ImAHopelessDev_gitlab> i'm watching some c tutorial videos. and oh my, they pass functions aroundl ike hotcakes
<FromGitter> <ImAHopelessDev_gitlab> look at this: https://i.gyazo.com/fd2349d2ed116ff7167b6c4267833e93.png it reminds me of what i do, but that's normal in c??
<FromGitter> <Blacksmoke16> pretty sure C isnt OO
<FromGitter> <Blacksmoke16> so thats prob what they have to do
<FromGitter> <3n-k1> oh yeah. c structs don't have methods. at most you can pass in a function pointer. generic structs in c are done with macros, or void function pointers. it's a pain lol
<FromGitter> <3n-k1> i know a decent bit of c if you need any help
robacarp has quit [Quit: robacarp]
f1refly- has joined #crystal-lang
f1refly has quit [Ping timeout: 240 seconds]
<FromGitter> <Blacksmoke16> that was a fun one :S
kevinsjoberg has quit [*.net *.split]
frojnd has quit [*.net *.split]
kevinsjoberg has joined #crystal-lang
frojnd has joined #crystal-lang
chachasmooth has quit [Ping timeout: 260 seconds]
chachasmooth has joined #crystal-lang
hightower2 has quit [Ping timeout: 260 seconds]
<FromGitter> <Blacksmoke16> has there ever been any disussions around adding more helper methods to like http types? mainly request/headers
<FromGitter> <Blacksmoke16> discussions*
avane has quit [Quit: ZNC - https://znc.in]
avane has joined #crystal-lang
<FromGitter> <Blacksmoke16> NVM
ua has quit [Quit: Leaving]
ua has joined #crystal-lang
<FromGitter> <3n-k1> what does `&->` notation do, pass a proc as a block?
<Andriamanitra> if i'm not mistaken values.each &->add_value(Int32) is just syntactic sugar for values.each { |x| add_value(x) }
postmodern has quit [Quit: Leaving]
<Andriamanitra> perfect place to use .tr :p
<Andriamanitra> went back and tried some silly optimizations, let me know what else i could do to make it fast (i'm bored) https://github.com/Andriamanitra/adventofcode2020/blob/main/day05/benchmarks.cr
<kevinsjoberg> Andriamanitra: would be faster if you added each seat_id to a set as you convert it? Then just grab the missing one from it?
<kevinsjoberg> nvm, didn't see the alt solution
<Andriamanitra> how would you grab the missing one? wouldn't that require some kind of set operation
<kevinsjoberg> I was thinking lower bound + upper bound - set of ids, but you alt solution is faster I believe.
<FromGitter> <mattrberry> @Andriamanitra I just reduced your example a little because I was curious. Damn, that's tiny! ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fcb4a563b3e7e2a2f9d2c88]
<FromGitter> <mattrberry> I'm in a discord server for emulator development where everybody uses c++. Most of the solutions people are posting there (for day 4 especially) are like 200+ lines haha
<FromGitter> <mattrberry> My day 5 wasn't nearly as clean as some of the other Crystal ones I'm seeing ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fcb4ac7ccac732a3a0093cc]
<straight-shoota> that `row.tr("FBLR", "0101").to_i(2)` is really neat
<straight-shoota> guess I overengineered with a record
<Andriamanitra> abusing .tr is something i picked up playing shortest mode on clash of code :D
<Andriamanitra> probably a bad habit but sometimes useful
<kevinsjoberg> Concise as hell.
<straight-shoota> My filter for part2 might be another one for your benchmark Andriamanitra: https://github.com/straight-shoota/aoc2020/blob/master/day05/solution.cr#L27
<straight-shoota> On average it's probably a bit slower than your BitArray, but it scales :D
<straight-shoota> `input.each_line.map { |row| seat_to_id(row) }.to_a.sort.each_cons_pair { |a, b| result = b - 1 if a < b -1 }`
<straight-shoota> eh `return b - 1`
<straight-shoota> with set creation included?
<straight-shoota> hashing integers isn't costly, but still...
<yxhuvud> It is less than 1000 numbers. Yes, it is still fast.
<yxhuvud> and yes, it is possible to simply sort the array instead and iterate, but then the code would end up with ugly if statements or trys ;)
<straight-shoota> okay, by fast you mean perceivably fast
<straight-shoota> `inputs.sort.each_cons(2, reuse: true).select { |a| a[0] < a[1] - 1 }.map(&.[1]).first - 1`
<yxhuvud> nice. I went looking for a `find!` but couldn't find any.
<yxhuvud> (or well, I'd guess they should have been named find? and find to match conventions)
<Andriamanitra> straight-shoota: i think the sorting makes it O(n log(n)), it seems to be about 1.6x slower
<yxhuvud> straight-shootas solution could probably be sped up by not making that composite seat type.
<yxhuvud> ie being able to use regular built-in ops instead of that custom comparator will help
<Andriamanitra> yeah i removed the extra stuff
<straight-shoota> For my answer (682) it's 1.3x slower
<straight-shoota> it can surely be sped up by removing all the iterators and inlining blocks
<straight-shoota> that's only for the part reading input
<Andriamanitra> i made it ever so slightly faster by using bsearch but i think the sorting is still a problem
<Andriamanitra> it's nice to have things like bsearch_index baked into the language :p
<straight-shoota> how does bsearch help?
<straight-shoota> there's no hint at whether a free seat is in the front or back
<Andriamanitra> yes there is, you just need to look at what the first seat is
<straight-shoota> and then?
<Andriamanitra> then you check if value - first_value != index
<straight-shoota> but you need to find the first seat, and that's O(n)
<Andriamanitra> well you're already sorting it anyway so really it's O(1)
<straight-shoota> oh right, I was confused by your comment that you might have done it without sorting somehow and tried to wrap my head around it
<straight-shoota> sounds like a good improvement, then
<FromGitter> <HertzDevil> just discovered that this won't always compile for all `T` and `U`:
<FromGitter> <HertzDevil> ```def foo(x : T, y : U) forall T, U ⏎ (true ? x : y).as(T) ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5fcb5c712d8b7c763842bfb2]
<FromGitter> <HertzDevil> and if it's `as?` it won't always work during runtime
<FromGitter> <asterite> interesting. what's on example of the latter?
<FromGitter> <asterite> ah, yeah. I would undo that behavior if I could
<FromGitter> <HertzDevil> you definitely should
<FromGitter> <HertzDevil> it's unsound
<FromGitter> <HertzDevil> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fcb5d74c980287e3678286d]
<FromGitter> <asterite> well, I can't, I'm not in charge of the language anymore
<FromGitter> <asterite> my idea for 1.0 is getting rid of redundant features, and doing cleanups, even if it means it will be a breaking change... because it will be the last breaking change
<FromGitter> <HertzDevil> is there a standalone issue for this
<FromGitter> <asterite> unfortunately the priority seems to be to release 1.0 soon without too many breaking changes, because people are already using the language and are happy with it
<straight-shoota> we can have breaking changes in 2.0, 3.0, 4.0, ...
<FromGitter> <asterite> there's no issue. Maybe if you open one Brian will want to make that change because he doesn't like unsound things in a type system
<FromGitter> <asterite> good point. Then I wouldn't make the next release 1.0
<FromGitter> <asterite> just look at how much time has passed since the last release
<oprypin> of course it's not time for 1.0 lol
<FromGitter> <asterite> :)
<oprypin> should we start a petition
<FromGitter> <asterite> change.org seems nice
<straight-shoota> "Mob of meth heads demand 0.36 release" ?
<oprypin> straight-shoota, do you want the next release to be 1.0?
<FromGitter> <asterite> by the way, I checked the chat before going into AoC today, what a mistake. You all spoiled me with tr and to_i(2). So concise!
<oprypin> aw
<straight-shoota> oprypin, no
<oprypin> welp
<jhass> maybe we can make it 0.100 as a compromise
<oprypin> πŸ˜‘
<straight-shoota> Well, there are obviously also advantages
<straight-shoota> And I came to accept going for 1.0
<jhass> I'm fine with 1.0 as long as we're not afraid of doing 2.0 even just six months later
<straight-shoota> But that was like in feburary
<oprypin> jhass, well we are afraid, im pretty sure
<straight-shoota> jhass, I'd like that but six months is too short.
<jhass> it's not if you commit to supporting 1.0 for a year or two and backport stuff
<straight-shoota> that's the time span between 0.35.1 and 1.0.0-rc1
<jhass> not sure how that's relevant
<oprypin> im pretty sure Nim supports every minor version for a year or two
<jhass> my requirement is "not being afraid of doing it if it looks necessary or beneficial", not "having to do it"
<straight-shoota> we didn't have a release with breaking changes in the last 4 months (because we had no release at all)
<straight-shoota> okay, that's a reasonable perspective
<jhass> as I got the story Manas wanted to be able to make commitments of "yes this is a stable API, you can rely on this in a longer term". Why would that stop us from moving beyond this, it's just a question of upholding that commitment alongside
<straight-shoota> true
<oprypin> umm you can't make that commitment for all libraries
<straight-shoota> It still doesn't seem very assuring if a followup major release was followed so shortly after, when prior to 1.0 seemingly smaller releases already took that long
<oprypin> especially considering the `crystal_version` forced obsolescence
<jhass> of course you cannot make commitments over projects you don't control. Not sure where anybody claimed they could.
<jhass> if somebody needs long term support from some project they should make an agreement with them in the same way they made it with Manas
<oprypin> what..
<oprypin> but it is in manas power to not take away the support of all libraries by default
<oprypin> so companies will demand that
<jhass> I don't follow you. Manas can commit to supporting 1.0 for period X. Doesn't stop them from releasing 2.0 alongside. The ecosystem can decide to move to 2.0, stay on 1.0 or run support branches for both. If somebody wants a particular project to stay on 1.0 or run support for both, they can incentivize them to do so
<yxhuvud> it is .. optimistic to think crystal adoption won't work like how rust used to work, with lots of libraries depending on a bleeding edge compiler.
<jhass> we had that phase, not sure why you think we'd enter a second round of it
<FromGitter> <asterite> well, I guess some things can wait for 2.0... maybe 1.0 is "what we have right now, polished" and 2.0 is "now let's make the breaking changes for the "real" deal"
<straight-shoota> asterite, yeah that's how I perceived 1.0
<yxhuvud> jhass: note that you can get to that state even without breaking changes, simply by adding features.
<jhass> which means you can get to it at any point, regardless of any 1.0 or whatever version or API stability policies
<jhass> pretty moot point in my opinion :)
<kevinsjoberg> Hmm, I just read through https://github.com/crystal-lang/crystal/pull/8893#issuecomment-631116376. Kind of a bummer it's pushed post 1.0.
<kevinsjoberg> IMO this shouldn't compile
gangstacat has quit [Quit: Ĝis!]
<kevinsjoberg> Out of curiosity, is there a use case for allow other types to #[] and #[]? than what's specified as the key for the hash itself?
<kevinsjoberg> s/allow/allowing/
gangstacat has joined #crystal-lang
<yxhuvud> yes, union types.
<yxhuvud> where one part of the union matches and the other doesn't.
<straight-shoota> kevinsjoberg, the general use case is that you want hash lookup to work identical to ==
<straight-shoota> == can be overridden to make that work
<straight-shoota> >> require "json"; JSON::Any.new("foo") == "foo"
<DeBot> straight-shoota: # => true - https://carc.in/#/r/a27i
<kevinsjoberg> straight-shoota: thanks, that was a solid writeup to be honest.
_whitelogger has joined #crystal-lang
<FromGitter> <asterite> yxhuvud: I also thought of having find! be like find but raising on nil... is there something similar in the std where bang raises?
<oprypin> there probably is, but cant think of something rn
<FromGitter> <asterite> maybe find! is also nice because it can raise a more descriptive error than "nil assertion failed"
<yxhuvud> to follow conventions I suppose it would be find? and find, but that is a breaking change :(
<yxhuvud> not_nil! and similar raises, but that is a different scenario.
<FromGitter> <asterite> well, find! being find + not_nil! at least makes sense, it's like grabbing the bang for. the second call and putting it in the first one
<yxhuvud> well I mean, that logic also holds for all methods that have a xxx? and xxx pair.
<yxhuvud> :shrug:
sorcus has quit [Quit: WeeChat 2.9]
sorcus has joined #crystal-lang
repo has quit [Ping timeout: 272 seconds]
repo has joined #crystal-lang
bazaar has quit [Ping timeout: 272 seconds]
bazaar has joined #crystal-lang
<straight-shoota> what find! are we talking about?
<FromGitter> <HertzDevil> there i sent an issue for the tuple variance thing
<yxhuvud> straight-shoota: The one that doesn't exist. The issue is that find is nilable, instead of being divided into find? and find like most other similar methods.
<straight-shoota> okay
sorcus has quit [Quit: WeeChat 2.9]
sorcus has joined #crystal-lang
<Andriamanitra> i don't think it's a great idea to give a million different meanings to ! at the end of a method call, it is already a bit confusing
<oprypin> Andriamanitra, really need https://github.com/crystal-lang/crystal/issues/8979 πŸ˜”
<Andriamanitra> .not_nil?! seems reasonable
<oprypin> yea that is some "i'm in this picture and i don't like it" stuff
<kevinsjoberg> Took me a few seconds of thinking "wtf" until I realised it was a joke, lol.
<FromGitter> <HertzDevil> ```typeof(Tuple(Int32 | String).new(1)) # => Tuple(Int32)```
<FromGitter> <HertzDevil> :rage2:
<FromGitter> <ImAHopelessDev_gitlab> good morning
<FromGitter> <ImAHopelessDev_gitlab> i had a dream about OOP and procedural. i found i actually like both and it's best to not be prejudice against either
<FromGitter> <ImAHopelessDev_gitlab> crystal allows that, you can either pass objects around like hotcakes, or tell objects to do something. up to you
<kevinsjoberg> @HertzDevil that's expected?
<kevinsjoberg> or what did you expect it would report?
<FromGitter> <tenebrousedge> it makes me sad to see the lack of love for `&->`
<FromGitter> <ImAHopelessDev_gitlab> is there a simple example of binary search in crystal? on playground, or github
<FromGitter> <tenebrousedge> isn't there a `bsearch` ?
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Indexable.html#bsearch(&block:T-%3EBool)-instance-method
<FromGitter> <Blacksmoke16> yes
<FromGitter> <ImAHopelessDev_gitlab> no i mean
<FromGitter> <ImAHopelessDev_gitlab> how it works
<FromGitter> <ImAHopelessDev_gitlab> not just a method
<FromGitter> <tenebrousedge> might want to take a look at the tests for that feature
<FromGitter> <ImAHopelessDev_gitlab> im watching this https://youtu.be/JQhciTuD3E8
<FromGitter> <ImAHopelessDev_gitlab> i understand linear search but am trying to understand binary search
<FromGitter> <Blacksmoke16> from the quick skim i did of that wiki article; i think it just checks the halfway point, checks value there compared to the block, then depending on that checks the halfway point to the right/left of it and repeat till it finds the value
<FromGitter> <naqvis> good visualization for linear and binary search
<FromGitter> <ImAHopelessDev_gitlab> omg
<FromGitter> <ImAHopelessDev_gitlab> @naqvis that is amazing!! WOW
<FromGitter> <naqvis> indeed :P
<FromGitter> <Blacksmoke16> https://www.youtube.com/watch?v=kPRA0W1kECg is also pretty great
<FromGitter> <ImAHopelessDev_gitlab> omg it makes sense
<FromGitter> <ImAHopelessDev_gitlab> but why do they use the word binary? seems like it hones in on the element between values
<FromGitter> <ImAHopelessDev_gitlab> ranges of low,mid, and high
<FromGitter> <tenebrousedge> because it's partitioning the set in two repeatedly
<FromGitter> <ImAHopelessDev_gitlab> but binary is 0 or 1
<FromGitter> <tenebrousedge> which is two states
<FromGitter> <ImAHopelessDev_gitlab> but there's 3 ranges
<FromGitter> <Blacksmoke16> :bigbrain:
<FromGitter> <ImAHopelessDev_gitlab> @Blacksmoke16 im serious
<FromGitter> <tenebrousedge> there's a terminal condition, not really three states
<FromGitter> <Blacksmoke16> a key point is the array has to be sorted
<FromGitter> <Blacksmoke16> i.e. if it checks the middle value and the value there is too big, then the right half of the array can be discarded, so the only two states would be the two section of the left half split in half
<FromGitter> <ImAHopelessDev_gitlab> @tenebrousedge so i understand binary as in 0 and 1. so that's two states. in a binary search, the two states is basically the range the element is searching in? the start an end?
<oprypin> @ImAHopelessDev_gitlab: binary is anything that relates to the number 2. binary search at every step splits the search space into 2 halves
<oprypin> also time complexity is log2(n)
<oprypin> wait maybe the last part is not correct, i don't remember
<FromGitter> <ImAHopelessDev_gitlab> okay i understand better. i keep thinking binary is a type with one value, either 0 or 1. however, binary is 1 or 0. two different states. it's it own type with the possibility of 2 different values, 0 or 1.
<FromGitter> <asterite> Quinton Miller: I'd say that's a bug, the Tuple.new thing. The return type should match the tuple type
<FromGitter> <asterite> Hm, actually, it might be hard to fix, not sure
<FromGitter> <ImAHopelessDev_gitlab> @oprypin go here: https://youtu.be/H4BstqvgBow?t=229 the binary value is `1101`. but i thought binary could only be 0 or 1
<FromGitter> <Blacksmoke16> they are, but its a bunch put together
<FromGitter> <Blacksmoke16> each *singluar* value can only be 1 or 0, which all of those are
<FromGitter> <ImAHopelessDev_gitlab> so binary can basically be a binary of binary values, too?
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <tenebrousedge> a binary number is a sequence of binary digits, or bits
<FromGitter> <Blacksmoke16> ^
<FromGitter> <tenebrousedge> from *bi*nary digi*t*
<FromGitter> <tenebrousedge> also probably because lazy
<FromGitter> <ImAHopelessDev_gitlab> well, this doesn't make sense to me because binary is 0 or 1, but in that khan video he says "if I were to write it in *binary*" it would be: `1101`
<FromGitter> <ImAHopelessDev_gitlab> how can 4 digits be 0 or 1
<FromGitter> <ImAHopelessDev_gitlab> that's an int
<FromGitter> <tenebrousedge> ints can be represented as binary numbers
<FromGitter> <tenebrousedge> or trinary numbers
<FromGitter> <tenebrousedge> it's a notation not a data type
<FromGitter> <Blacksmoke16> or hex :p
<FromGitter> <tenebrousedge> strings are numbers too if you look hard enough
<FromGitter> <ImAHopelessDev_gitlab> so 1101 is basically 4 binary digits represented in an int type for notation?
<FromGitter> <tenebrousedge> 1101 is the binary notation for the (decimal notation) number 13
<FromGitter> <ImAHopelessDev_gitlab> so when talking about binary search, they are talking about binary in the context of having 0 or 1 (two states). which it uses to compare and find the element
<FromGitter> <ImAHopelessDev_gitlab> not the digit sense
<FromGitter> <ImAHopelessDev_gitlab> ?
<FromGitter> <tenebrousedge> "binary" is an overloaded term, yes
<FromGitter> <ImAHopelessDev_gitlab> that makes sense
<FromGitter> <tenebrousedge> "binary search" divides the search space in two. "binary numbers" use two states to represent integers
<FromGitter> <ImAHopelessDev_gitlab> that helps
<FromGitter> <ImAHopelessDev_gitlab> a lot
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <ImAHopelessDev_gitlab> now i'm re-thinking what i just thought of the naming of binary search an hour ago, now i cna see why it's called a binary search, a bit ambiguous but it makes sense when u think about the 2 state thing
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
<kevinsjoberg> Hmm, I tried to bit shift the input instead of using tr for generating the seat ids. Looks like it's faster but not as concise.
<kevinsjoberg> e.g., boarding_pass.each_char.reduce(0) { |acc, c| acc << 1 | c_to_b[c] } where c_to_b is a hash mapping each char to either 0 or 1.
<FromGitter> <tenebrousedge> huh
<FromGitter> <tenebrousedge> I mean can't you just `XOR` some value?
<kevinsjoberg> what do you mean?
<FromGitter> <tenebrousedge> there should be a way to figure out whether or not it's 1 or 0 without a hash lookup
<kevinsjoberg> oh, yeah, I thought about that as well, but my brain didn't want me to find the solution right now.
<kevinsjoberg> I mean I could use comparison, but that's not super elegant either.
<kevinsjoberg> quite a lot faster though
<FromGitter> <tenebrousedge> hashes are slow
<kevinsjoberg> yeah, didn't think it would do such a big difference, but it really did.
<kevinsjoberg> This solution is roughly 1,5x faster the previous one
<kevinsjoberg> This is what I was comparing against
<kevinsjoberg> In any case, the first one, which I believe Andriamanitra had, is far more concise and readable.
<FromGitter> <tenebrousedge> you can check if the third bit is set
<kevinsjoberg> oh, you're right.
<FromGitter> <tenebrousedge> and theoretically you don't have to read the input as a set of strings
<FromGitter> <tenebrousedge> hmmm, why is negation not working?
<FromGitter> <tenebrousedge> because they're unsigned, tay
psydroid has quit [Ping timeout: 246 seconds]
ryanprior has quit [Ping timeout: 244 seconds]
return0e[m] has quit [Ping timeout: 246 seconds]
ryanprior has joined #crystal-lang
psydroid has joined #crystal-lang
<FromGitter> <tenebrousedge> ```code paste, see link``` ⏎ ⏎ Something like that I guess [https://gitter.im/crystal-lang/crystal?at=5fcbf7c7c980287e3679967b]
return0e[m] has joined #crystal-lang
hightower3 has joined #crystal-lang
<hightower3> Ehm, so I use simple logging with just Log.setup_from_env and calling Log.info { ... } etc. How do I change the log level in runtime? I see #level=, but that's an instance method and I didn't create any log specifically.
hightower3 has left #crystal-lang ["Leaving"]
hightower3 has joined #crystal-lang
<FromGitter> <Blacksmoke16> im not so sure you can
<FromGitter> <tenebrousedge> can you call `setup_from_env` again?
<hightower3> Yes, I did so just now and tested that it works. Not sure if it's the most elegant, but hey.
<FromGitter> <tenebrousedge> add a comment explaining it, I guess
<FromGitter> <tenebrousedge> `# N.B. This may not be a good idea`
<FromGitter> <Blacksmoke16> fwiw when you do `Log.info` im pretty sure `Log` is a const that returns a `Log` instance
<FromGitter> <Blacksmoke16> so `.level = :debug` might work
<FromGitter> <Blacksmoke16> i got confused with changing the severity at runtime
<hightower3> 4 | Log.level = :info
<hightower3> Error: undefined method 'level=' for Log.class
<hightower3> ^----
<FromGitter> <Blacksmoke16> welp
<FromGitter> <Blacksmoke16> `Log.for` might be for this maybe then
<FromGitter> <Blacksmoke16> yea thats what you would do
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Log.html#for(source:String,level:Severity?=nil):Log-class-method
<FromGitter> <Blacksmoke16> which wraps `Log::Builder` which says calling that method with same source will return same instance
<hightower3> hmm, nice one!
<FromGitter> <tenebrousedge> yay!
<hightower3> Hm, noticed a nuance with Log.setup_from_env and retrieving instances with Log.for(). If I collect all my loggers via #for and change their levels, only they are affected of course (loggers from shards are not). Whereas if I call Log.setup[_from_env], all loggers are affected, which is what I want.
<FromGitter> <Blacksmoke16> Does setup from env not clear the loggers?
<hightower3> Seems to preserve them. I have defined loggers in classes via constants as recommended in the docs (e.g. Log = ::Log.for('myname')), and these names remain even after multiple calls to setup_from_env
<hightower3> (and the updated logging severity is respected)
<hightower3> In fact, my latest and probably final code only calls Log.setup_from_env once (at the beginning). Then I do `level = oldlevel = ENV["LOG_LEVEL"] || "info"`, and from there I just switch between levels and re-set them with a call to Log.setup(Log::Severity.parse level)
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <ImAHopelessDev_gitlab> πŸ‘