<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>
<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>
<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!
<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>
<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> 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>
<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โฆ