ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Fund Crystal's development: | GH: | Docs: | Gitter:
<FromGitter> <Blacksmoke16> Deleted his gitter again :s
<FromGitter> <Daniel-Worrall> some people be like that
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 272 seconds]
f1reflyylmao is now known as f1refly
chachasmooth has quit [Ping timeout: 264 seconds]
chachasmooth has joined #crystal-lang
chachasmooth has quit [Ping timeout: 260 seconds]
chachasmooth has joined #crystal-lang
<where_is_x> hey! I just wrote some code
<where_is_x> and it's kind shiny
<where_is_x> compile maybe?
<where_is_x> oh here's my crystal
<where_is_x> and all the other bugs
<where_is_x> try to chase me
<where_is_x> but here's my crystal
<where_is_x> so typecheck maybe?
where_is_x has quit [Quit: Quit]
fifr` has quit [Ping timeout: 240 seconds]
where_is_x has joined #crystal-lang
<FromGitter> <grkek> Oh come on
where_is_x has quit [Ping timeout: 240 seconds]
where_is_x has joined #crystal-lang
<FromGitter> <HertzDevil> update: i got the `while` transform working
<FromGitter> <HertzDevil> the only problem is it happens in the normalizer, not the literal expander
<FromGitter> <HertzDevil> ```code paste, see link``` []
sorcus has joined #crystal-lang
_ht has joined #crystal-lang
Flipez7 has joined #crystal-lang
Flipez has quit [Ping timeout: 240 seconds]
Flipez7 is now known as Flipez
fifr` has joined #crystal-lang
<FromGitter> <HertzDevil> solved
hendursa1 has joined #crystal-lang
hendursaga has quit [Ping timeout: 268 seconds]
_whitelogger has joined #crystal-lang
postmodern has joined #crystal-lang
<FromGitter> <asterite> Nice!
<FromGitter> <HertzDevil> there are now weird codegen bugs all over the place
<FromGitter> <HertzDevil> ```code paste, see link``` []
<FromGitter> <riffraff169> ``````
<FromGitter> <riffraff169> ```code paste, see link``` []
<FromGitter> <riffraff169> minimal code that generates the compiler error
<FromGitter> <riffraff169> works under 0.35.1, but not on any version above
<FromGitter> <Blacksmoke16> 👍 prob would be better off not using a hash in the first place tho
<FromGitter> <riffraff169> what would be recommended?
<FromGitter> <riffraff169> basically i need a type, a value, and a lineno, possibly more maybe later, but for now
<FromGitter> <riffraff169> tuple? array?
<FromGitter> <riffraff169> i could do an array
<FromGitter> <Blacksmoke16> a struct`
<FromGitter> <Blacksmoke16>,*properties)-macro
<FromGitter> <riffraff169> hmmm....i see....i like to understand these things rather than just use them....what would be advantages or disadvantages be?
<FromGitter> <Blacksmoke16> you get more type safety and easier to interact with
<FromGitter> <riffraff169> immutable, that is good, none of my tokens will need to change after being created
<FromGitter> <Blacksmoke16> i.e. `lexeme.type` etc
<FromGitter> <Blacksmoke16> is the type of `value` going to be different for each oen?
<FromGitter> <riffraff169> i put in a ticket/issue with the error above still...i will change my code to use a record/struct
<FromGitter> <riffraff169> value will have 3 different types, either a string, symbol, or int32 (maybe 64)
<FromGitter> <riffraff169> so could make an array of records
<FromGitter> <Blacksmoke16> and what about `type`?
<FromGitter> <riffraff169> type will always be a symbol specifying the type of the token, like :comma, :string, :lessthan, etc
<FromGitter> <riffraff169> `:value` will be the value of the token, `:line` will be current line number for the token
<FromGitter> <riffraff169> not tracking columns yet
<FromGitter> <> @riffraff169: i'd even consider `abstract struct Token`
<FromGitter> <riffraff169> i have never used abstract classes/structs in ruby/crystal, how would i use that properly? docs on it somewhere?
<FromGitter> <> @riffraff169: could you just provide some kind of overview what kind of items they could be?
<FromGitter> <Blacksmoke16> an enum might also be a good idea
<FromGitter> <> i see both `:type => :pragma, :value => :token` and `:type => :pragma, :value => "string"`, why is it that it can be both a symbol and a string, how are you going to deal with the usage?
<FromGitter> <riffraff169> a specific token cant be both, but a token will have a type and a a `:word:` type could have a value of `thisvar` `i`, etc, like variable names
<FromGitter> <riffraff169> a `:number` type will be 10, 1.7, etc
<FromGitter> <riffraff169> basically im just tokenizing
<FromGitter> <> well great then
<FromGitter> <> make use of the type system
<FromGitter> <riffraff169> im definitely open to suggestions, this is my first crystal program
<FromGitter> <Blacksmoke16> would a number actually be a `Number` type, or wouldnt they just be `String`?
<FromGitter> <Blacksmoke16> unless you're value conversion as well
<FromGitter> <> oh .. yea thats a good point i guess
<FromGitter> <riffraff169> yes, im parsing hex `$`, octal `0`, and binary `%` and converting to decimal for storage
<FromGitter> <> i think typically that isn't being done (because the integer type has its limit and maybe you don't want to run into it in the early stages of parsing)
<FromGitter> <riffraff169> normally that would be a problem, but my specific use case is parsing for 6502 assembly, which basically has a 16bit limit (high-byte, low-byte), so i have no overflow problems
<FromGitter> <MrSorcus> - if someone interested in this...
<FromGitter> <> ```code paste, see link``` []
<FromGitter> <> is an option
mipmip has joined #crystal-lang
<FromGitter> <riffraff169> ok, i at really early stages, basically just this lexing is all i have right now...not even parsing definitely open to suggestions
<FromGitter> <riffraff169> so i would define `lexemes = [] of Token`
<FromGitter> <riffraff169> which would cover all the subclasses
<FromGitter> <Blacksmoke16> yup
<FromGitter> <riffraff169> great, that would make it, i would do something like:
<FromGitter> <riffraff169> ```case token ⏎ when NumberToken ⏎ when WordToken``` ⏎ ⏎ to differentiate between them, and not try to access a type incorrectly (number will have Int32, word will have String) []
<FromGitter> <> 👌
<FromGitter> <Blacksmoke16> ```case token ⏎ in NumberToken ⏎ in WordToken ⏎ end``` []
<FromGitter> <riffraff169> groovy, thanks for the suggestions....ill go from here and see what happens
<FromGitter> <riffraff169> `in`, not `when` ?
<FromGitter> <Blacksmoke16> that would be a compile time error if you added a new token type and wouldnt be checking for it
<FromGitter> <> the difference is only an exhaustiveness check
<FromGitter> <Blacksmoke16> assuming you want to check all types versus just a few
<FromGitter> <riffraff169> ah....well, after looking at rust and some other languages, im kind of looking at the exhaustiveness....that would make sure i wouldnt have any unhandled types
<FromGitter> <riffraff169> this actually makes me make my tokens more orthogonal too...better, thanks
<FromGitter> <Blacksmoke16> 👍
yxhuvud has quit [Read error: Connection reset by peer]
yxhuvud has joined #crystal-lang
lanodan has quit [Quit: WeeChat 3.0]
<FromGitter> <riffraff169> do i have an error here: ⏎ ⏎ ```abstract struct Token ⏎ property line : Int32 ⏎ end``` []
<FromGitter> <riffraff169> ```code paste, see link``` []
<FromGitter> <Blacksmoke16> would ofc have to add a constructor for it
<FromGitter> <riffraff169> i need to look up struct
<FromGitter> <Blacksmoke16> ```code paste, see link``` []
<FromGitter> <Blacksmoke16> then in your child types would have to do like
<FromGitter> <Blacksmoke16> ```code paste, see link``` []
<FromGitter> <> that is the correct approach, yes
<FromGitter> <> the background is
<FromGitter> <riffraff169> thanks...i should know this....i did think there might be a default constructor, or a default value....thanks
<FromGitter> <> @riffraff169: it is in fact hard to know, no worries
<FromGitter> <riffraff169> cool thanks, ill memorize it now
<FromGitter> <straight-shoota> yeah, an abstract class shouldn't complain over missing ivar initialization
<FromGitter> <straight-shoota> or abstract struct
hightower2 has quit [Ping timeout: 246 seconds]
<FromGitter> <riffraff169> ok cool, got some sample code built and running, so thats good...
<FromGitter> <riffraff169> wondering, how would one implement something like rusts enum types? those enums can have values....this is sort of like that i think
<FromGitter> <Blacksmoke16> the values can only be integers tho
<straight-shoota> enum types in Rust are different
<FromGitter> <riffraff169> yeah
<FromGitter> <> @riffraff169: the closest is indeed abstract struct
<straight-shoota> Crystal equivalent would be a union type
<FromGitter> <riffraff169> yeah, thats what it looks like
<straight-shoota> or abstract struct
<FromGitter> <riffraff169> yeah, like c union but where it knows what type it is
<FromGitter> <riffraff169> cool thanks
<FromGitter> <riffraff169> what would be the best way to convert a String to a symbol? ruby has `.to_sym`...or is there something better to do?
<FromGitter> <> @riffraff169: you just don't do it
<FromGitter> <riffraff169> ok
<FromGitter> <> @riffraff169: if you really actually get user input as a string, and it always happens to match, this is the way
<FromGitter> <riffraff169> interesting, yeah, that wont quite work i think....ill just use a string and use string comparisons
<FromGitter> <> @riffraff169: the officially approved usage of symbols is limited to "the thing that serves as the key in a namedtuple", and the officially approved usage of namedtuple is limited to "the thing that stores named arguments to a function". symbols just aren't liked
<FromGitter> <riffraff169> ah
<FromGitter> <> although technically they do work fine in quite many situations
<FromGitter> <riffraff169> as im sure you know, in ruby they are preferred because `:thing` is always the object, whereas `"thing"` could be different objects
<FromGitter> <riffraff169> but that is fine
<FromGitter> <riffraff169> at least, thats how i understood it
<FromGitter> <> in crystal it's just SomeEnum::Thing
<FromGitter> <> and for fully runtime handling you just have to use string
<FromGitter> <riffraff169> yeah...can you add enums to an enum dynamically?
<FromGitter> <Blacksmoke16> no
<FromGitter> <> no
<FromGitter> <riffraff169> ok, ill just use strings, thanks
<FromGitter> <> if the set of valid strings is limited to particular compiletime values, then that's just Enum.parse again
<FromGitter> <riffraff169> i just probably use that....the set of acceptable words will be limited, so that should be easy
<FromGitter> <> and i haven't explicitly said this -- you really can't convert to symbol. they must be known at compile time
<FromGitter> <riffraff169> yeah, that makes sense
<FromGitter> <riffraff169> part of the compile time checking
<FromGitter> <riffraff169> even though crystal looks like ruby, still more like c i think...i will have to adjust my thinking
<FromGitter> <> i wouldn't call it "checking", it's an implementation requirement
<FromGitter> <riffraff169> now i like c, so not a problem
<FromGitter> <> symbols are like a special globally shared enum :>
<FromGitter> <riffraff169> haha, thats true
<FromGitter> <riffraff169> and global variables are Bad ™️
<FromGitter> <riffraff169> although classes are global vars....we wont get into that
<FromGitter> <riffraff169> something has to be global somewhere
<FromGitter> <> when i say this, i mean that's actually how they're implemented
<FromGitter> <riffraff169> ah, thats interesting...
<FromGitter> <> because the storage of an enum value is just 1 integer
<FromGitter> <riffraff169> so Enum.parse would probably be the best bet
<FromGitter> <> if u use :somevalue, that string never ends up in the executable
<FromGitter> <riffraff169> really, the actual value doesnt matter, so
<FromGitter> <riffraff169> hmm, interesting again
duane has quit [Quit: Lost terminal]
duane has joined #crystal-lang
<FromGitter> <HertzDevil> worked a bit more on the while loop stuff and it seems some `NoReturn`-related inference was broken
lanodan has joined #crystal-lang
<FromGitter> <naqvis> 1) 0 treats `Proc` as block?
<FromGitter> <naqvis> Doesn't work in 1.0 ⏎ ⏎ ```alias Foo = -> String ⏎ ⏎ { ⏎ return "foo" ⏎ }``` []
<FromGitter> <naqvis> used to work in previous versions ⏎
<FromGitter> <Blacksmoke16> prob because of
<FromGitter> <naqvis> Thanks @Blacksmoke16 , looks like that's the one
<FromGitter> <naqvis> but this breaks things
<FromGitter> <naqvis> like try to use some looping construct inside `Proc`, compiler still insists to use `next` to return from block , imagine what would happen when you do `next` in looping construct :P
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <naqvis> contrived example ⏎ works in previous versions, but no longer works in 1.0
<FromGitter> <Blacksmoke16> prob should have been marked as breaking i suppose
<FromGitter> <naqvis> yeah
<FromGitter> <Blacksmoke16> maybe add a comment to the ticket?
<FromGitter> <naqvis> thing is, this is not breaking change, but breaks the whole semantics and make using looping constructs inside `Proc` impossible
<FromGitter> <Blacksmoke16> not exactly
<FromGitter> <Blacksmoke16> just have to do it differently
<FromGitter> <naqvis> how would you do it?
<FromGitter> <Blacksmoke16> well this *would* be possible but there is another bug it seems
<FromGitter> <naqvis> `while` break always return nil
<FromGitter> <Blacksmoke16> based on that shouldnt be the case
<FromGitter> <naqvis> so there is no way to return value from while
<FromGitter> <Blacksmoke16> or the docs are wrong
<FromGitter> <naqvis> > A while's type is always Nil.
<FromGitter> <MrSorcus> @naqvis ⏎ ⏎ > To return from a block one should always use next. ⏎ ⏎ Or it works only outside of loops? []
<FromGitter> <naqvis> yeah, `next` is used to return from blocks
<FromGitter> <naqvis> but thing is 1.0 changed the semantics of `Proc`
<FromGitter> <naqvis> `Proc` is a function pointer
<FromGitter> <naqvis> kind of anonymous function
<FromGitter> <Blacksmoke16> sounds like the `break` docs need updated to clarify that "this doesn't work with `while`"
<FromGitter> <naqvis> yeah, agree
<FromGitter> <Blacksmoke16> or its a bug that it *should* work with `while`
<FromGitter> <Blacksmoke16> i feel like @HertzDevil would prob have more context
<FromGitter> <riffraff169> what is the best way to do an action based on a type/class?
<FromGitter> <riffraff169> case, when MyClass ?
<FromGitter> <riffraff169> actually, i need if it is a specific class, and some value in the class matches
<FromGitter> <riffraff169> like if val === MyClass and val.var == 1
<FromGitter> <Blacksmoke16> er nvm, that wont help with the `val.var == 1` case
<FromGitter> <naqvis> created an issue on github, let's see how it goes
<FromGitter> <Blacksmoke16> ```case {obj, obj.value} ⏎ when {SomeType, 1} then ... ⏎ end``` []
<FromGitter> <riffraff169> hmmm, lets see
<FromGitter> <riffraff169> can you put an else there? i want to do an action only if that case is false
<FromGitter> <riffraff169> so all other cases
<FromGitter> <riffraff169> ah yes
<FromGitter> <riffraff169> ```code paste, see link``` []
<FromGitter> <riffraff169> there might be a better way? a type of unless instead
<FromGitter> <riffraff169> but that works
<FromGitter> <> @riffraff169: why don't you just write `if`
<FromGitter> <Blacksmoke16> oh if you just want to skip 1 thing like that just use an if :P
<FromGitter> <riffraff169> i tried `if lexeme === OpToken && lexeme.value == ";"`, but that didnt work
<FromGitter> <riffraff169> but the case does
<FromGitter> <Blacksmoke16> `if lexeme.is_a? OpToken`
<FromGitter> <riffraff169> i could try there a benefit to using one over the other? my input and output wont be very big, so memory and cpu probably wont be a factor
<FromGitter> <riffraff169> although the case tuple check will be useful later...i might just keep it in that way as an easy reference
<FromGitter> <riffraff169> learning something new all the time
<FromGitter> <Blacksmoke16> im pretty sure the `case` example gets expanded to like: ⏎ ⏎ `````` []
<FromGitter> <riffraff169> how do you guys feel about doing type checking with .is_a? i read an article one that writing code that depends on type checking means your code needs to be not sure i care really, although that is why i was having a type var in it rather than using the class as the type
<FromGitter> <Blacksmoke16> ```code paste, see link``` []
<FromGitter> <Blacksmoke16> i think it depends on what you're doing exactly
<FromGitter> <riffraff169> well, how about in the case where lexeme.value type (String, Int32) doesnt match unless lexeme is the right type, like OpToken instead of StringToken
<FromGitter> <riffraff169> the case tuple would just not match, whereas the if would fail to compile
<FromGitter> <Blacksmoke16> why would the `if` fail to compile? I'm pretty sure the case expands to the `if` code i put there
<FromGitter> <riffraff169> what if i have this:
<FromGitter> <riffraff169> ```code paste, see link``` []
<FromGitter> <riffraff169> if it was just expanded to an if, then if it happened to be NumberToken with value 1 (Int32 instead of String)
<FromGitter> <riffraff169> the first if (`_tmp2 == ";"`) would fail because types wouldnt match
<FromGitter> <HertzDevil> no
<FromGitter> <riffraff169> no?
<FromGitter> <HertzDevil> `#==` is defined over all types
<FromGitter> <HertzDevil> in fact, `#===`
<FromGitter> <riffraff169> so `lexeme.value` being 1
<FromGitter> <riffraff169> and comparing to `";"`
<FromGitter> <riffraff169> in the first case of OpToken
<FromGitter> <HertzDevil> `";" === 1` compiles and returns false
<FromGitter> <Blacksmoke16> would be `false`
<FromGitter> <riffraff169> ah, `===` instead, ok
<FromGitter> <riffraff169> because that does type matching, not value matching
<FromGitter> <Blacksmoke16> and ohh thats right, when case is expanded it uses `===`
<FromGitter> <riffraff169> sort
<FromGitter> <riffraff169> of
<FromGitter> <riffraff169> ok, cool, i got it now
<FromGitter> <Blacksmoke16> pretty sure `===` aliases to `==` for most types
<FromGitter> <Blacksmoke16> unless a subtype overrides it
<FromGitter> <riffraff169> ok, so here is where my confusion is/was then
postmodern has quit [Quit: Leaving]
<FromGitter> <riffraff169> `==`, `===` doesn't fail compilation when types don't match... `=` does though
<FromGitter> <riffraff169> does return `false` though
<FromGitter> <Blacksmoke16> you can compare incompatible types, but ofc if you do like `foo : String = 1`, that would fail because you're trying to assign `1` to `foo` which can only be a `String`
<FromGitter> <riffraff169> great, im clear now
<FromGitter> <riffraff169> thanks!!!
where_is_x has quit [Read error: Connection reset by peer]
where_is_x has joined #crystal-lang
<FromGitter> <riffraff169> my code is working now with the token to add some enums and stuff, then i can start working on the actual parsing
<FromGitter> <Blacksmoke16> 👍
postmodern has joined #crystal-lang
<FromGitter> <> What's the best way to determine if a variable was declared nilable? For example, `test_var : String?` vs `test_var : String`.
<FromGitter> <Blacksmoke16> at runtime?
<FromGitter> <> No, at build time.
<FromGitter> <> I don't understand how that would work at run time.
<FromGitter> <Blacksmoke16> idt you can access local variables in macro land so afaik there wouldnt be a way to do that
<FromGitter> <Blacksmoke16> unless `test_var` is an instance variable?
<FromGitter> <> Ah, yes it is. Sorry, should have said that in my example.
<FromGitter> <Blacksmoke16> then it would be like `ivar.restriction.nilable?`
<FromGitter> <> Can you link to documentation for that? I can't find anything with the "nilable?" function except in macros.
<FromGitter> <Blacksmoke16> oh sorry its `.type`
<FromGitter> <Blacksmoke16>
<FromGitter> <Blacksmoke16> this is macro code
<FromGitter> <> Haven't spent the time to figure out macros yet. I think this will work though. Thanks!
<FromGitter> <Blacksmoke16> what are you wanting to do? actually getting the `ivar` in this case might be the harder part
<FromGitter> <> I have a class with a set of string properties, only some of which are nilable. I'm using a function outside the class to define those, but there is a possibility it will fail. If it fails, I need the function to return nil if the property I'm defining is nilable. If not nilable, I raise an exception.
<FromGitter> <Blacksmoke16> got some example code?
<FromGitter> <> Yeah, I'll whip something up.
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <> I finished my example, but I don't see a way to share it.
<FromGitter> <> Oh, I'm dumb:
<FromGitter> <> I'm just now realizing that my property isn't even being passed to the parse_entry function, so trying to detect that it's nilable isn't a solution. I think I might just have to pass a boolean to the function indicating if a nil response is acceptable.
<FromGitter> <HertzDevil> ```code paste, see link``` []
<FromGitter> <HertzDevil> something like that
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Blacksmoke16> although i will ask, whats the reason for using a `Hash` in the first place? seems kidna odd
<FromGitter> <> Hash was only for the example.
<FromGitter> <> In real life, it's an XML::Node.
<FromGitter> <Blacksmoke16> ah gotcha
<FromGitter> <HertzDevil> 😔
<FromGitter> <> I'm trying to pull properties that may or may not exist, and I thought Hash would be a simpler example since I can rescue the same KeyError.
<FromGitter> <HertzDevil> btw `ivar` inside that macro is a `MetaVar`, not `InstanceVar`, so you should always be able to get that type however it is declared
<FromGitter> <> Does that mean I can use ivar in the parse_entry function without having to pass it there?
<FromGitter> <HertzDevil> but then you have to pass `@type` there
<FromGitter> <HertzDevil> oh you can
<FromGitter> <> Wait, you're right. I do need to pass @type there.
<FromGitter> <HertzDevil> well even if `@type` appears inside `CommonClass`'s def as long as it is `TestClass` that invokes it `@type` will also be that
<FromGitter> <> ok, thanks that's a huge help
<FromGitter> <HertzDevil> in that case `#parse_entry` will be instantiated separately for every subclass that calls it:
where_is_x has quit [Ping timeout: 268 seconds]
where_is_x has joined #crystal-lang
dfdx has left #crystal-lang [#crystal-lang]
_ht has quit [Remote host closed the connection]
dostoyevsky has quit [Quit: leaving]
dostoyevsky has joined #crystal-lang
mipmip has quit [Quit: WeeChat 3.1]
pim1 has joined #crystal-lang
pim1 has quit [Client Quit]
pim1 has joined #crystal-lang
pim1 has quit [Client Quit]
pim1 has joined #crystal-lang
pim1 has quit [Client Quit]
mipmip has joined #crystal-lang
<FromGitter> <Blacksmoke16> @straight-shoota have you thought about flagging shards in shardbox that have < 1.0.0 `crystal` value?
<straight-shoota> yeah, thought about it
<straight-shoota> but not acted
<straight-shoota> yet
<straight-shoota> think I got lost in thought about general shard health checks
<FromGitter> <Blacksmoke16> 👍 fair enough
<FromGitter> <Blacksmoke16> @straight-shoota btw
<FromGitter> <Blacksmoke16> looks like you just need to upgrade `pg`
<straight-shoota> Yeah probably
<straight-shoota> btw. don't use `state: archived` with repos that are considered a mirror of a shard. They shouldn't show up as individual shards at all.
<straight-shoota> `state: archived` is just for cases where a shard is entirely discontinued, not when it basically just changed names
<straight-shoota> or location
<FromGitter> <Blacksmoke16> even in the case of them not being a 1:1 port?
<straight-shoota> then it shouldn't be a mirror of the other one
<FromGitter> <Blacksmoke16> ah ok that makes sense
<FromGitter> <Blacksmoke16> sec
<straight-shoota> probably...
<straight-shoota> hm, maybe mirror would work, too
<FromGitter> <Blacksmoke16> i guess my thinking was that "if you were using this shard, you should migrate to x"
<FromGitter> <Blacksmoke16> but maybe that should be its own role or something
<straight-shoota> yeah if assert and crserializer are essentially legacy versions of validator
<FromGitter> <Blacksmoke16> can think of it like a 1.0 to 2.0 thing
<straight-shoota> The only functionality of a mirror config is that when a shard uses the mirror repo as dependency, it's attributed as a dependency of the shard with the new repo
<FromGitter> <Blacksmoke16> maybe it would make more sense to do something like: ⏎ ⏎ ```code paste, see link``` []
<straight-shoota> not exactly that syntax, but yeah
<straight-shoota> maybe a custom archive message
<straight-shoota> A reference to the new shard could just be in the description, though
<FromGitter> <Blacksmoke16> ```state: archived ⏎ replacement: athena-framework/validator``` []
<FromGitter> <Blacksmoke16> prob could be added to the warning like
<FromGitter> <Blacksmoke16> "See #{shard.replacement} for a possible replacement"
<straight-shoota> yeah, sounds like a good idea
<straight-shoota> but I suppose more flexibility wouldn't hurt
<straight-shoota> for example if it was the other way around, splitting 1 shard into 2 separate ones. Then you would recommend two replacements.
<straight-shoota> well, it's probably not a likely use case
<FromGitter> <Blacksmoke16> well technically CrSerializer was split into 2 :P
<straight-shoota> nvm then :D
<FromGitter> <Blacksmoke16> CrSerialzer => assert => athena-validator and CrSerializer => athena-serializer hehe
<FromGitter> <Blacksmoke16> so prob an array of objects like `mirrors`
<straight-shoota> I don't know if it needs to be in structured form
<straight-shoota> it's just informational
<FromGitter> <Blacksmoke16> wouldnt you need to know what repo it uses to build a link?
hendursa1 has quit [Quit: hendursa1]
<straight-shoota> a little string expansion will doo
<FromGitter> <Blacksmoke16> 🤔 how you figure?
<FromGitter> <Blacksmoke16> given `athena-framework/validator` there isnt a way to know if it should be or or whatever
<straight-shoota> yes, but github:athena-framework/validator tells enough
<straight-shoota> or could be the a full git or http URL
<FromGitter> <Blacksmoke16> wait thats what i was proposing
<FromGitter> <Blacksmoke16> an array of objects with a resolver thing like `mirrors`, but without `role`?
<straight-shoota> yeah, I'm talking about freeform text
hendursaga has joined #crystal-lang
<straight-shoota> like `status_message: "This shard is deprecated, check out [github:athena-framework/validator] instead."`
<FromGitter> <Blacksmoke16> hmm yea that would work too i suppose