ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.30.1 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <Blacksmoke16> oh wait, maybe `Module.class`?
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/7iup nice
<companion_cube> well, basic IRC bot + redis works
<companion_cube> neat.
<companion_cube> is `foo || next` a common pattern to handle nil?
<companion_cube> (within a block)
<FromGitter> <Blacksmoke16> depends what you're trying to do?
<FromGitter> <watzon> I need to think of a good way to provide persistence with Tourmaline. I need an easy way to allow the storing of Chats, Users, and Messages without constraining the user to a single database type.
<FromGitter> <watzon> This is gonna be fun to figure out
<FromGitter> <Blacksmoke16> text files stored in /tmp :trollface:
<FromGitter> <watzon> ๐Ÿ˜‚
<FromGitter> <Blacksmoke16> i mean something on the file system using json files or something wouldn't be a terrible idea?
<FromGitter> <Blacksmoke16> or coughusedicough then you could have various storage classes and they can plug the one they want in
<FromGitter> <watzon> That's the idea I'm pushing around
<FromGitter> <watzon> It's just implementing it in an abstract enough way that's the hard part
<FromGitter> <Blacksmoke16> ๐Ÿ˜‰
<FromGitter> <watzon> Lol yeah I have thought about Athena
<FromGitter> <Blacksmoke16> might be a bit heavy to just handle that one thing
<FromGitter> <Blacksmoke16> but using some module/parent class as an interface and just have your types include/inherit from that would be essentially the same idea
<FromGitter> <Blacksmoke16> main thing would be how to select which one
<FromGitter> <Blacksmoke16> generic maybe
<FromGitter> <Blacksmoke16> `@writer = T.new`
<FromGitter> <Blacksmoke16> :shrug:
hightower3 has quit [Ping timeout: 245 seconds]
<companion_cube> hmmmmmmmmmm what's the difference between class and object methods, at definition point?
<companion_cube> (also, not sure how to use modules to namespace stuff)
<FromGitter> <watzon> class methods can be used without a class being instantiated, eg `MyClass.do_something`, instance methods require an instance, eg `MyClass.new.do_something`
<companion_cube> I mean, yeah, but how to define a class method?
<FromGitter> <watzon> `def self.my_method`
<FromGitter> <watzon> as opposed to `def my_method` for an instance method
<companion_cube> oh ok, neat
dom96 has quit [Ping timeout: 264 seconds]
<FromGitter> <watzon> If everything is going to be a class method, as is the case when using modules sometimes, you can also use `extend self` at the top. Then every method becomes a class method.
<FromGitter> <watzon> Example: โŽ โŽ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d74505750508949d3f673c6]
<companion_cube> right
<companion_cube> so I can use such classes to namespace functions, I imagine
<FromGitter> <Blacksmoke16> Just use self and avoid extend if possible
<companion_cube> โœ”
<FromGitter> <Blacksmoke16> Heard it's possibly going to be removed at some point
sagax has quit [Quit: Konversation terminated!]
<FromGitter> <watzon> Really? That sucks
<FromGitter> <watzon> I hope they don't
<FromGitter> <watzon> Ok that would be work the tradeoff if it could include class methods and variables
<FromGitter> <Blacksmoke16> indeed
<FromGitter> <watzon> I've needed that several times
chachasmooth has joined #crystal-lang
<companion_cube> is there a http client that follows redirects?
<FromGitter> <watzon> Halite has the ability to
<FromGitter> <watzon> One reason I use it so much
<FromGitter> <Blacksmoke16> the relevant issues
<FromGitter> <watzon> Just needs to finally be implemented
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d745a40460a6f5a16e4cf6c]
<FromGitter> <Blacksmoke16> got this working so far
<FromGitter> <Blacksmoke16> prob rename the annotation to support both serialization and deserialization names
<FromGitter> <Blacksmoke16> question, make it a module you can include the types you want, or define the stuff on `Object`?
return0e has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
<companion_cube> how hard is it to contribute to the stdlib?
<FromGitter> <tenebrousedge> really hard. It's written in some language called Crystal
<FromGitter> <Blacksmoke16> tl;dr, fork it, make a PR
<FromGitter> <Blacksmoke16> that is correctly formatted, has specs, has documentation, and is needed/agreed upon
<companion_cube> I mean, the question is more of how much of a PITA it is to build it :)
<FromGitter> <Blacksmoke16> ah
<FromGitter> <watzon> Pretty large
<FromGitter> <watzon> Depending on your system resources
<FromGitter> <Blacksmoke16> then just do a `make`
<FromGitter> <Blacksmoke16> if all goes well it should work :p
<companion_cube> well first I should write these functions outside, we'll see about contributing afterwards :)
<companion_cube> but Regex misses some utils.
<FromGitter> <Blacksmoke16> prob wouldnt be a bad idea to search/make an issue first
<FromGitter> <Blacksmoke16> if its not something trivial
<FromGitter> <tenebrousedge> what utils?
<companion_cube> match_each, basically
<FromGitter> <tenebrousedge> you mean `scan` ?
<companion_cube> can't find that in Regex ?
<FromGitter> <Blacksmoke16> It's under string
<FromGitter> <tenebrousedge> `String#scan`
<companion_cube> ahhhhhhhh
<companion_cube> that's what I was looking for earlier
<FromGitter> <Blacksmoke16> Welp, there you go
<companion_cube> although there's no iterator version it seems
<FromGitter> <Blacksmoke16> Scan.each?
<FromGitter> <tenebrousedge> StringScanner
<FromGitter> <Blacksmoke16> It's just an array
<companion_cube> there's the Enumerable version, but not the Iterable version
<FromGitter> <tenebrousedge> I like using StringScanner and Iterator together
<FromGitter> <Blacksmoke16> Hm?
<FromGitter> <Blacksmoke16> like you want an `Iterator` for each match?
<companion_cube> yeah, why not? seems consistent with the rest of the stdlib
<companion_cube> (an Iterator of matches, rather)
<FromGitter> <tenebrousedge> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d746e05460a6f5a16e55a1c]
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/7ivi
<FromGitter> <tenebrousedge> or that
<companion_cube> well it's an array, it's not lazy
<FromGitter> <Blacksmoke16> oh so you want to be able to do like `.next` and it scans further and yields the next match?
<companion_cube> yeah, I mean, like all the iterators?
<companion_cube> it's more so that .map, etc. work lazily
<FromGitter> <Blacksmoke16> then do what @tenebrousedge example is
<companion_cube> or, in particular, foo.scan_each(/whatev/).size to count them without allocating
<FromGitter> <Blacksmoke16> i think id rather have a `String#count(pattern : Regex)`
<FromGitter> <Blacksmoke16> to go with https://crystal-lang.org/api/master/String.html#count(other:Char)-instance-method
<companion_cube> btw when you want multiple matches, you should have an `overlapping: Bool` argument
<companion_cube> hu, the compiler finished compiling `make` already
<FromGitter> <tenebrousedge> yeah I don't find it to take that long to compile
<companion_cube> that's amazing
<FromGitter> <tenebrousedge> but on resource-constrained systems
<FromGitter> <Blacksmoke16> release mode takes quite a bit longer
<FromGitter> <Blacksmoke16> but thats not really needed for devving
<companion_cube> ugh, make spec does OOM :/
<FromGitter> <Blacksmoke16> `make std_spec`
<FromGitter> <Blacksmoke16> if you're just doing stdlib stuff
<companion_cube> thanks :)
<FromGitter> <Blacksmoke16> otherwise it does compiler specs as well
<FromGitter> <Blacksmoke16> can also do
<FromGitter> <Blacksmoke16> `./bin/crystal spec spec/std/regex_spec.cr`
<FromGitter> <Blacksmoke16> that'll prob be easier...
<companion_cube> heh, overlapping added
<FromGitter> <Blacksmoke16> Anyway, I'm off to bed
<companion_cube> good night!
<companion_cube> undefined constant Regex::MatchData in `include Iterator(Regex::MatchData)` โ€ฆ so weird?
chemist69 has quit [Ping timeout: 276 seconds]
chemist69 has joined #crystal-lang
<companion_cube> https://github.com/crystal-lang/crystal/pull/8162 and, there we go
<FromGitter> <tenebrousedge> I probably would prefer that in two PRs
<FromGitter> <tenebrousedge> but I don't actually work on stdlib
<companion_cube> wow, running the samples is so easy :o
<companion_cube> I mean, yeah, I expect the PR to be discussed :DD
_whitelogger has joined #crystal-lang
<companion_cube> does the `select` syntax have a case for timeouts?
<companion_cube> (it's not documentd yet, it seems)
<FromGitter> <watzon> @companion_cube Like `Array#select`?
_whitelogger has joined #crystal-lang
DTZUZO has quit [Ping timeout: 248 seconds]
<FromGitter> <bararchy> I guess he means the select(Array(Channel))
<FromGitter> <bararchy> as in, select for channels
sorcus has joined #crystal-lang
ht_ has joined #crystal-lang
absolutejam1 has joined #crystal-lang
dom96 has joined #crystal-lang
gangstacat has quit [Quit: ฤœis!]
gangstacat has joined #crystal-lang
absolutejam1 has quit [Ping timeout: 244 seconds]
rohitpaulk has joined #crystal-lang
alex`` has joined #crystal-lang
hightower3 has joined #crystal-lang
livcd has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 245 seconds]
<Stephie> hmm, I wonder why URI.parse doesn't do percent-decoding automatically...
<Stephie> yeah... ruby doesn't unescape path components, go does
<Stephie> i really like go's interface
<Stephie> it basically means never touching URI.encode/decode manually
DTZUZO has joined #crystal-lang
DTZUZO has quit [Ping timeout: 246 seconds]
<companion_cube> yep, I mean select on channels
blassin has quit [Quit: The Lounge - https://thelounge.chat]
blassin has joined #crystal-lang
sagax has joined #crystal-lang
ua has joined #crystal-lang
ua_ has quit [Ping timeout: 268 seconds]
<FromGitter> <Whaxion> Hello! I want to know if it's possible to have multiple JSON mapping for a class. It's because I'm making a library of a shitty API so in an endpoint a key is "lat" and in another it's "stop_lat"
Human_G33k has joined #crystal-lang
Human_G33k has quit [Remote host closed the connection]
Human_G33k has joined #crystal-lang
DTZUZO has joined #crystal-lang
<FromGitter> <straight-shoota> @Whaxion Not directly. The JSON mapping goes only one direction. But you can write a converter that implements `.from_json(JSON::PullParser)` and/or `.to_json(value, JSON::Builder)`. That requires a bit more effort than just declaring a mapping, but it's not difficult.
HumanG33k has quit [Ping timeout: 240 seconds]
<FromGitter> <straight-shoota> Alternatively, you could use different types to represent different JSON mappings and convert between them in Crystal land. When the difference is just a simple key name, this seems unnecessary, but often there might be more, subtle differences between the data models.
<FromGitter> <Whaxion> @straight-shoota I'll look into that, thanks!
Groogy has joined #crystal-lang
HumanG33k has joined #crystal-lang
Human_G33k has quit [Ping timeout: 244 seconds]
alex`` has quit [Ping timeout: 258 seconds]
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/7j20 why is the `Time` overload not working?
alex`` has joined #crystal-lang
<FromGitter> <Blacksmoke16> it seems to work for every other type besides time
return0e_ has joined #crystal-lang
return0e has quit [Ping timeout: 245 seconds]
rohitpaulk has joined #crystal-lang
<FromGitter> <Sija> any1 knows how to make pass `__FILE__` and `__LINE__` constants between the macro and regular methods?
<FromGitter> <Sija> see https://carc.in/#/r/7j2d
<FromGitter> <asterite> Because there is Time::Format
<FromGitter> <Sija> both lines should show the actual values, yet the second one captures only argument names instead
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <Blacksmoke16> how does that fit into it @asterite ?
dannyAAM has quit [Quit: znc.saru.moe : ZNC 1.6.2 - http://znc.in]
dannyAAM has joined #crystal-lang
<FromGitter> <Blacksmoke16> since the type of `Time.utc` is `Time` shouldnt that not execute the method thats defined in that type?
<FromGitter> <asterite> You have a type restriction Format
<FromGitter> <asterite> it doesn't match your top level Formst
<FromGitter> <asterite> it matches Time::Format
<FromGitter> <asterite> that's why it's always better to put your stuff in a new namespace
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/7j2r im not sure i follow, each method is the same?
<FromGitter> <asterite> Try using ::Format as a type restriction
<FromGitter> <Blacksmoke16> OHH
<FromGitter> <Blacksmoke16> that makes sense
<FromGitter> <asterite> Format matches Time::Format in the Time overload
<FromGitter> <Blacksmoke16> because there is a class within `Time` with the same name
<FromGitter> <Blacksmoke16> good call :p
<FromGitter> <Blacksmoke16> thanks
<FromGitter> <asterite> Yes
<FromGitter> <asterite> It's a bit bad but that's w
<FromGitter> <asterite> how it works
alex`` has quit [Ping timeout: 244 seconds]
alex`` has joined #crystal-lang
absolutejam1 has joined #crystal-lang
alex`` has quit [Ping timeout: 245 seconds]
alex`` has joined #crystal-lang
fyber has quit [Remote host closed the connection]
rohitpaulk has quit [Ping timeout: 245 seconds]
<FromGitter> <Qard> Is it expected that `def update!(&block : Int32, Int32 -> T)` would replace `def update!(&block : Int32 -> T)` rather than providing an alternate signature?
<FromGitter> <Qard> Shouldnโ€™t the blocks be considered different types?
<FromGitter> <bcardiff> It is expected. Blocks signature canโ€™t be used to choose the overload. Using the arguments is optional
<FromGitter> <Qard> Ah, hmmโ€ฆitโ€™d be nice if there was a way to require using the arguments so it could be a properly type-safe block.
<FromGitter> <bcardiff> the type safe is there. but the overload is defined by the other arguments, not the block. Only the existence of the block is used as overload information
<FromGitter> <Qu4tro> Having a bit of a hard time using `mocks.cr`. Trying to mock a `HTTP::Server`, to check that both `bind_tcp` and `listen` are being called, but no actual mocking seems to occur. I've tried a few different things, but it seems I can only mock class methods.. โŽ If anyone has the time, I've setup a small repo, which should reproduce the issue I'm having : https://github.com/Qu4tro/crystal-server-mock and
<FromGitter> ... obviously thanks in advance.
<FromGitter> <Blacksmoke16> seems quite old :/
<FromGitter> <Qu4tro> Yeah.. I didn't found an alternative though.
<FromGitter> <Blacksmoke16> crystal doesnt have a *good* mock lib afaik, your best bet would be to just write some integration tests
<FromGitter> <Qu4tro> I can also confirm, its test suit is failing in one test, but the code is too much for me
<FromGitter> <Blacksmoke16> and just make sure the output you get is correct, vs making sure x method was called n times
<FromGitter> <Qu4tro> Right, I was trying to avoid that, since it's an auth server, requiring db and expensive bcrypt calls. Oh well, I think as is should be *goodenough* . Thanks for the advice!
<FromGitter> <Blacksmoke16> could still mock that stuff out no?
<FromGitter> <Blacksmoke16> just would have to do it yourself
<FromGitter> <Qu4tro> Yeah. I've managed to mock the underlying direct calls, which were represented as class methods. I wanted broader tests and the fact that I can't mock instance methods is making things all clunky
<FromGitter> <Blacksmoke16> tell me about it
<FromGitter> <Blacksmoke16> i feel your pain
<FromGitter> <Qu4tro> ahahah
<FromGitter> <Qu4tro> Can't get rid of developing friction
<FromGitter> <Qu4tro> But crystal seems alright. I've just made a couple of programs in it, but it's mostly smooth sailing. Testing (well and lack of some libs), is def. the biggest hurdle I found so far
<FromGitter> <Blacksmoke16> should get better as times goes on tho, more time for libs to appear
<FromGitter> <Blacksmoke16> https://github.com/mockery/mockery crystal version of this woud be nice
<FromGitter> <Blacksmoke16> would*
<FromGitter> <Qu4tro> Yeah. I think some work done on `mocks.cr` should suffice as well, though. It seems it has most features - but well, the state of it - I'm not so sure of. I might raise an issue, but the maintainer doesn't seem to be active. โŽ I think the only feature that I actually needed, that didn't exist, was having `and_raises` in complement of `and_returns`
<FromGitter> <Qu4tro> I ended up changing the actual code, to return `Value | Nil` instead of raising, which is okay, but err..
ht_ has quit [Quit: ht_]
<FromGitter> <Blacksmoke16> ๐Ÿ˜ฌ
<FromGitter> <watzon> @Blacksmoke16 have you found a way to make annotations work when they're defined in a module and included in a class that should support them?
<FromGitter> <Blacksmoke16> :thinking:
<FromGitter> <Blacksmoke16> got an example?
<FromGitter> <watzon> Not a simple one, but this (https://github.com/watzon/tourmaline/blob/master/src/tourmaline/command_registry.cr) is how I'm handing the `Command` annotation right now. If I use the `Command` annotation in a subclass of `Telegram::Bot` it works just fine, but if I use it in a module and then include that module in my subclass it doesn't work at all. The compiler doesn't even see it.
<FromGitter> <Blacksmoke16> right because you're only iterating over subclasses
<FromGitter> <Blacksmoke16> not included modules
<FromGitter> <Blacksmoke16> er do you mean like adding the annotation to a method in a module then including that module into your subclass
<FromGitter> <watzon> Yes
<FromGitter> <watzon> Would it be easy to iterate over included modules as well?
<FromGitter> <Blacksmoke16> that doesnt exist yet
<FromGitter> <watzon> Shit
<FromGitter> <Blacksmoke16> (is a PR for it tho)
<FromGitter> <Blacksmoke16> however it seems that https://play.crystal-lang.org/#/r/7j3k
<FromGitter> <Blacksmoke16> included methods dont exist in the typenode, maybe make an issue about it?
<FromGitter> <Blacksmoke16> bbiaf food
<FromGitter> <watzon> Lol I'll do that
<FromGitter> <watzon> Done #8164
<DeBot> https://github.com/crystal-lang/crystal/issues/8164 (Included methods don't appear to exist in the TypeNode)
<FromGitter> <Blacksmoke16> ๐Ÿ‘
return0e_ has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
<companion_cube> is there a system for automatically building to/from_json for custom classes?
<companion_cube> ooh neat
<companion_cube> thank you
<FromGitter> <Blacksmoke16> p
<FromGitter> <Blacksmoke16> np*
<companion_cube> I should look at the source :)
<FromGitter> <watzon> @companion_cube I'd highly recommend it
absolutejam1 has quit [Ping timeout: 245 seconds]
<FromGitter> <Daniel-Worrall> Is `JSON::Serializable` or `JSON.mapping` preferable for a Struct? I'm thinking mapping
<FromGitter> <Blacksmoke16> Serializable wit record
<FromGitter> <Daniel-Worrall> record?
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/toplevel.html#record(name,*properties)-macro
<FromGitter> <Blacksmoke16> ```record Point, x : Int32, y : Int32 do โŽ include JSON::Serializable โŽ end``` [https://gitter.im/crystal-lang/crystal?at=5d75796eb3e2fc579378b096]
<FromGitter> <Blacksmoke16> tada
<FromGitter> <Blacksmoke16> get initializer, getters, and clean code :P
<FromGitter> <Daniel-Worrall> what if I need converters
<FromGitter> <Blacksmoke16> Then you couldn't use record and would have to define the properties and annotations yourself
<FromGitter> <Daniel-Worrall> then back to my original question, which is preferable :^)
<FromGitter> <Blacksmoke16> Serializable is the newer one
<FromGitter> <Blacksmoke16> Makes it so you don't have to define the mapping and the properties
<FromGitter> <Blacksmoke16> As your properties are the mapping
<FromGitter> <Daniel-Worrall> It's a Struct, not a Class though
<FromGitter> <Blacksmoke16> So?
<FromGitter> <Daniel-Worrall> I'm gonna do some testing
<FromGitter> <Blacksmoke16> ๐Ÿ‘
<FromGitter> <Blacksmoke16> been working on my own serializer with some extra features, but isnt ready yet
<FromGitter> <Daniel-Worrall> idk, these are identical but I kinda feel like the mapping syntax is cleaner โŽ โŽ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d7580946e889c4bbdc16446]
<FromGitter> <Blacksmoke16> maybe, but would have to also define your getters/setters if you use the mapping
<FromGitter> <Blacksmoke16> i.e.
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d7580de2f93ab5a152c4927]
<FromGitter> <Blacksmoke16> which isn't ideal
<FromGitter> <Blacksmoke16> plus iirc the mapping doesnt work too well with inheritance
<FromGitter> <watzon> I am loving annotations https://github.com/watzon/tourmaline/wiki/Pattern-Matching
<FromGitter> <Blacksmoke16> welcome to the club
<FromGitter> <Blacksmoke16> was getting lonely as a club of one :P
<FromGitter> <Daniel-Worrall> The mapping already gives it setters/getters
<FromGitter> <Blacksmoke16> im pretty sure it doesnt
<FromGitter> <watzon> Now I need to figure out a good way to keep some of my models serializable, but also allow me to inject another class so I can add some methods to the model
<FromGitter> <Blacksmoke16> @Daniel-Worrall nvm apparently it does
<FromGitter> <watzon> ie, I have a Message model which gets automatically deserialized from json but I need to be able to inject my `Bot` class in when it gets deserialized
<FromGitter> <Daniel-Worrall> https://carc.in/#/r/7j3r
<FromGitter> <watzon> I think I just need to overload `from_json`
<FromGitter> <Blacksmoke16> would after it gets deserialized work?
<FromGitter> <Daniel-Worrall> I think I'll stick with mapping then, at least for structs
<FromGitter> <Daniel-Worrall> I'll try out the hierarchy stuff
<FromGitter> <watzon> I could do that, but then the variable would have to be nilable
<FromGitter> <watzon> Which means I'd always have to check if it's nil
<FromGitter> <watzon> The one major pain in the butt with having things be type safe lol
<FromGitter> <Blacksmoke16> https://carc.in/#/r/7j46
<FromGitter> <Blacksmoke16> `getter!` + `after_initialize`?
<FromGitter> <Blacksmoke16> assuming its always instantiated from json it'll never be nil
<FromGitter> <watzon> Only problem is `Bot` is already initialized
<FromGitter> <watzon> I need to pass in an instamce
<FromGitter> <Blacksmoke16> so?
<FromGitter> <Blacksmoke16> where do you get the instance from?
<FromGitter> <watzon> Well the deserialization is happening inside of the Bot class, so I just need to be able to pass `self` in during the `from_json`
<FromGitter> <Blacksmoke16> could you not just do like
<FromGitter> <watzon> Which means I probably just need to overload `from_json`
<companion_cube> dang, Serialize is heavy macro magicโ€ฆ
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d75854fae44a84124a4481b]
<FromGitter> <Blacksmoke16> ?
<FromGitter> <Blacksmoke16> `some_obj.bot = self`*
<FromGitter> <Daniel-Worrall> what does `property!` do
<FromGitter> <watzon> Yeah I guess I could do that couldn't I
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Object.html#property!(*names)-macro
<FromGitter> <watzon> I forgot about the bang properties
<FromGitter> <Blacksmoke16> also provides nilable getter
<FromGitter> <Blacksmoke16> companion_cube a bit yea
<FromGitter> <Blacksmoke16> ```code paste, see link``` โŽ โŽ newest feature [https://gitter.im/crystal-lang/crystal?at=5d7586a2b3e2fc5793790917]
<FromGitter> <Blacksmoke16> er copy paste fail on the other 2, can be assured they are `User2` and `User3` :p
<FromGitter> <watzon> Damn this is gonna be more complicated than I thought
<FromGitter> <Blacksmoke16> ๐Ÿ˜ข
<FromGitter> <watzon> I have multiple nested models that need references to the bot
<FromGitter> <watzon> Like `Update > Model > Chat`
<FromGitter> <Blacksmoke16> do the same instance?
<FromGitter> <watzon> Duh
<FromGitter> <watzon> Lol
<FromGitter> <watzon> Overthinking
<FromGitter> <Blacksmoke16> cant just use a module like `BotStore.get_bot`
<FromGitter> <watzon> I mean I could just theoretically assign the bot instance to a class variable
<FromGitter> <watzon> And access it from there
<FromGitter> <watzon> But then I can't have multiple bot instances
<FromGitter> <Blacksmoke16> define it in a module and include it
<FromGitter> <Blacksmoke16> or setup some simple DI thing
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d75893a54e7c649d4af998a]
<FromGitter> <Blacksmoke16> not really DI, more like just a service container but yea
<FromGitter> <watzon> Yeah that could work
<FromGitter> <watzon> Sec
<FromGitter> <Blacksmoke16> not sure if will be an issue or not but just know since its a class var its not fiber safe
<FromGitter> <watzon> I guess I'll see
<FromGitter> <watzon> Oh yeah, duh. I forgot for a minute that modules don't include class methods
return0e_ has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d758c9f50508949d3fe9468]
<FromGitter> <Blacksmoke16> next feature
<FromGitter> <Blacksmoke16> kinda obs, but it allows having methods act as properties within the serialized data
<FromGitter> <watzon> Ahh nice, I remember virtual properties from a Ruby library
<FromGitter> <watzon> Don't remember what it was called off the top of my head
<FromGitter> <Blacksmoke16> making progress :p
<FromGitter> <Blacksmoke16> next up is a way to define the order of the data
<FromGitter> <Blacksmoke16> default to `alphabetical` but also allow you to manually give a specific order
<FromGitter> <Blacksmoke16> or default to order defined in class, and have custom/abc as options
<FromGitter> <Blacksmoke16> kudos to whoever added https://crystal-lang.org/api/master/Crystal/Macros/ArrayLiteral.html#sort_by(&block):ArrayLiteral-instance-method
<FromGitter> <Blacksmoke16> should work well