<FromGitter>
<sam0x17> in classic me fashion, I want to name it before I try to make it
<FromGitter>
<tenebrousedge> it sounds easier to do that at runtime
<FromGitter>
<sam0x17> my use case is I'm in all these kemal endpoints and wish I could just `return` sometimes so I `next` a string or json or whatever, but if I'm in an `.each` block etc I can't do that and it gets so awk
<FromGitter>
<tenebrousedge> using `each` is probably one problem there
<FromGitter>
<Blacksmoke16> looks like you could use my validation shard π
<FromGitter>
<sam0x17> I totally should -- just want to get parity between old rails app and new crystal version before I start trying to revamp things
<FromGitter>
<Blacksmoke16> doesnt halt do it?
<FromGitter>
<sam0x17> that's a good point, I should try that again
<FromGitter>
<sam0x17> I think it does if I specify the mime type etc
<FromGitter>
<Blacksmoke16> or raises an exception that gets caught
<FromGitter>
<Blacksmoke16> to return the json error message
<FromGitter>
<sam0x17> hah you are right I actually have stuff in place for formatting the exception messages too
<FromGitter>
<sam0x17> !!!
<FromGitter>
<didactic-drunk> Is there way to get all superclasses in a macro that have a particular module included or constant defined? I'd prefer the module if there's a choice.
<FromGitter>
<sam0x17> in this case that is what I should do lol thanks @Blacksmoke16
<FromGitter>
<tenebrousedge> but they give you those warm fuzzy feelings inside
<FromGitter>
<didactic-drunk> You mean blood and hair balls? Yeszzz..
<FromGitter>
<watzon> Where are the pics?
<FromGitter>
<watzon> You summoned me, I expect pics
<FromGitter>
<didactic-drunk> Tried sending D pics. Apparently those also get your account suspended. Not eager to have it happen a 4th time (See project history at bottom) (https://github.com/didactic-drunk/sodium.cr).
<FromGitter>
<Blacksmoke16> anyone familiar with XML?
<FromGitter>
<Blacksmoke16> i think i found a bug
<FromGitter>
<tenebrousedge> a bug in...XML?
<FromGitter>
<Blacksmoke16> well in the crystal type enum :p
<FromGitter>
<Blacksmoke16> did i just happen to have the only post this week? :p
<FromGitter>
<Blacksmoke16> neat
<FromGitter>
<watzon> I think so π
<FromGitter>
<watzon> I was going to write one, but I've been too busy
<FromGitter>
<Blacksmoke16> hehe
<FromGitter>
<watzon> Can anyone think of a reason why running `shards install` would ask for a github username and password? @rmarronnier is trying to install https://github.com/cadmiumcr/tokenizer, but it's asking for a username and password. When I try it locally it works just fine.
<FromGitter>
<watzon> Maybe someone else could test it and see if it installs correctly?
<FromGitter>
<Blacksmoke16> make sure the github path is correct
<FromGitter>
<Blacksmoke16> and its not a private repo
<FromGitter>
<watzon> Should be correct, and definitely isn't private
<FromGitter>
<Blacksmoke16> whats his shard.yml look like/
<FromGitter>
<watzon> Ok so it must be something to do with your git config @rmarronnier
<FromGitter>
<rmarronnier> Damn, I'll look into this. Good news for everyone else though
<FromGitter>
<watzon> Yep lol. I'm assuming you're using ssh?
<FromGitter>
<dmitryrck> `shards install` works for me too with that `shard.yml` :P
<FromGitter>
<watzon> I guess it's working for him now
<FromGitter>
<watzon> Why it wasn't before we may never know
chemist69 has quit [Ping timeout: 276 seconds]
chemist69 has joined #crystal-lang
<FromGitter>
<dmitryrck> is there any way to add an spy in `puts` using *only* stdlib? β I want to test if `puts` is called and with the correct argument π€
<FromGitter>
<dmitryrck> (automated test, BTW)
<FromGitter>
<watzon> @dmitryrck what do you mean "add a spy"?
<FromGitter>
<dmitryrck> of course, this `expect().to receive` is a DSL that I don't have, anything similar helps :)
<FromGitter>
<watzon> Oh yeah, you can't do that. The best you could hope for is to monkeypatch the `puts` method. There is another spec library called Spectator (https://github.com/icy-arctic-fox/spectator) that is going to be implementing mocks soon.
<FromGitter>
<watzon> But I doubt the built in spec library will ever be capable
<FromGitter>
<watzon> Or at least not soon
<FromGitter>
<dmitryrck> yeah, that is what I just tried β I also tried dependency injection β I will try dependency injection, it is probably the best to do here π€ β in ruby `puts` is from `Kernel`, I have not done anything similar in Ruby, but I supposed it is possible `allow(Kernel).to receive(:puts)` (emphasis to *suppose*) β in Crystal it is from a constant [https://gitter.im/cry
<FromGitter>
<dmitryrck> actually, I did not try monkey patch properly, I felt like it was not a good idea, even thou I would write only in `spec/spec_helper.cr` :P
<FromGitter>
<watzon> Well `puts` is in the top level namespace. Technically you could wrap it as well and just create your own `puts` method that wraps puts and handle your own logic there.
<FromGitter>
<dmitryrck> π€
<FromGitter>
<dmitryrck> thanks for the idea, I will see what I can do, maybe I even write a blog post β see ya o/
absolutejam1 has joined #crystal-lang
<FromGitter>
<absolutejam_gitlab> I've done in a class because I wanted to be able to silence `puts` when testing
<FromGitter>
<absolutejam_gitlab> and just call `::puts` if I want the original version
<FromGitter>
<absolutejam_gitlab> Not sure I'm not using a logger though, maybe I need to revisit
<FromGitter>
<absolutejam_gitlab> TIL `delegate get_usable_flag, to: get_usable_flag_by_name`
<FromGitter>
<Daniel-Worrall> @Blacksmoke16 Do you know if there's a way to read the request body so that I can parse the body as json later as well? `env.request.body` returns a `HTTP::FixedLength` so if I `gets_to_end`, I can't `rewind` and a call to `env.params.json` attempts to parse the now empty io
<FromGitter>
<Blacksmoke16> why not just write to STDOUT and pipe the output to the file?
<FromGitter>
<Blacksmoke16> like `./myApp > file.log`
<FromGitter>
<kingsleyh> I tried that and it doesn't work very well - the logs are written only half way through the process and then missing a big chunk from the end
<FromGitter>
<kingsleyh> I want realtime logs
<FromGitter>
<Blacksmoke16> could use the multiwriter then maybe
<FromGitter>
<Blacksmoke16> one being a file, other being stdout?
<FromGitter>
<kingsleyh> can't I just write the IO::Memory to file everytime it gets something?
<FromGitter>
<kingsleyh> some kind of while sdout.gets then append to file
<FromGitter>
<stronny> it also causes the binary to grow in size. is there anything I can do to avoid this effect besides not using them?
ua has joined #crystal-lang
gangstacat has quit [Quit: Δis!]
gangstacat has joined #crystal-lang
kazooie___ has quit [Ping timeout: 246 seconds]
<FromGitter>
<asterite> I don't think so, it's an LLVM issue
devil_tux has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
devil_tux has quit [Ping timeout: 258 seconds]
<FromGitter>
<stronny> got it, thanks
ht_ has quit [Remote host closed the connection]
absolutejam has joined #crystal-lang
ht_ has joined #crystal-lang
ht_ has quit [Quit: ht_]
<FromGitter>
<watzon> Has @Blacksmoke16 done any blog posts/tutorials on using annotations? I think I'm going to change Tourmaline to have an annotation based API.
<FromGitter>
<watzon> But I haven't even touched that part of Crystal yet
<FromGitter>
<Blacksmoke16> and what would they do/
<FromGitter>
<Blacksmoke16> like whats the end goal?
<FromGitter>
<watzon> Well Tourmaline is a Telegram Bot framework. The `Command` annotation is going to register the method as a command. In the top example it will register the command `/help` to send a help message. `at_start: true` is going to make sure that the method is only called if the command is found at the beginning of a message. β β The second one is going to be a general event listener. There are a ton of potential
<FromGitter>
... events.
<FromGitter>
<watzon> Right now I
<FromGitter>
<watzon> But I want to make it a bit more friendly for actually extending `Tourmaline::Bot`. Right now it's a pain in the ass.
<FromGitter>
<Blacksmoke16> should be doable yea
<FromGitter>
<Blacksmoke16> does every command only have those 2 args?
<FromGitter>
<watzon> For now. Right now the second arg doesn't even exist, but it's something I want to add.
absolutejam has quit [Ping timeout: 258 seconds]
<FromGitter>
<Blacksmoke16> do what i would do is like
<FromGitter>
<Blacksmoke16> have a parent class that all the command stuff inherits from
<FromGitter>
<Blacksmoke16> then you can iterate over the children, iterate over methods, and "register" those that have the ann
<FromGitter>
<Blacksmoke16> registration could be like `Hash(String, Proc(message : Message, Nil))`
<FromGitter>
<Blacksmoke16> assuming they dont have any dependencies?
<FromGitter>
<Blacksmoke16> otherwise DI would work well here, as you wouldnt have to manually give it anything
<FromGitter>
<Blacksmoke16> could all be resolved from the container
<FromGitter>
<watzon> So this would work for class and instance methods?
<FromGitter>
<Blacksmoke16> this handles instance
<FromGitter>
<Blacksmoke16> main challenge with that is you have to new up a class first
<FromGitter>
<watzon> Right, which I'm ok with. I want users to have to subclass `Tourmaline::Bot`.
<FromGitter>
<Blacksmoke16> but there arent any dependencies you have to give it right?
<FromGitter>
<Blacksmoke16> like MyCommandClas.new x, y, z
<FromGitter>
<watzon> Right now `Tourmaline::Client` requires an `api_key` argument, but that's it.
<FromGitter>
<Blacksmoke16> hm ok
<FromGitter>
<Blacksmoke16> have a few options
<FromGitter>
<Blacksmoke16> idk how you want all this to work but the idea is you can iterate children of your parent class, iterate methods, and do something with the methods with that annotation
<FromGitter>
<Blacksmoke16> possibly converting the methods into procs to call later
<FromGitter>
<Blacksmoke16> is essentially how athena works
<FromGitter>
<watzon> That's the ideal situation
<FromGitter>
<Blacksmoke16> sounds like a plan :p
<FromGitter>
<watzon> Right now that code would just work with subclasses right? What if I wanted to define a command on the base class?
<FromGitter>
<Blacksmoke16> like a common command that all children should have?
<FromGitter>
<Blacksmoke16> or like default commands
<FromGitter>
<Blacksmoke16> for the app
<FromGitter>
<watzon> Like a common command. Tbh this wouldn't be for commands, but for event listeners.
<FromGitter>
<watzon> Because it's actually a default event listener that calls the commands.
<FromGitter>
<watzon> Although...
<FromGitter>
<watzon> I don't actually need to do that, nvm
<FromGitter>
<Blacksmoke16> in that case you can either define those on a subclass
<FromGitter>
<Blacksmoke16> or add another loop to loop over main class methods
<FromGitter>
<Blacksmoke16> π
<FromGitter>
<watzon> Yeah cool. Well awesome. I'll try and implement this. Should be pretty cool if I can get it working.
<FromGitter>
<Blacksmoke16> indeed, they allow for some cool things
<FromGitter>
<Blacksmoke16> mainly compile time errors and caching since everything gets registered at compile time